@conciso/design-system 0.0.0-bootstrap.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1786 -0
- package/LICENSE +21 -0
- package/NOTICE +15 -0
- package/README.md +134 -0
- package/assets/brand/LICENSE +11 -0
- package/assets/brand/README.md +45 -0
- package/assets/brand/logo-conciso-dark.svg +4 -0
- package/assets/brand/logo-conciso-light.svg +4 -0
- package/assets/brand/logo-conciso.svg +4 -0
- package/css/base.css +303 -0
- package/css/components.css +1633 -0
- package/css/dark-mode.css +716 -0
- package/css/fonts.css +20 -0
- package/css/tokens.css +209 -0
- package/dist/conciso-ds.css +2891 -0
- package/fonts/LibreBaskerville-OFL.txt +93 -0
- package/fonts/Montserrat-OFL.txt +93 -0
- package/fonts/libre-baskerville-400-latin-ext.woff2 +0 -0
- package/fonts/libre-baskerville-400-latin.woff2 +0 -0
- package/fonts/libre-baskerville-400i-latin-ext.woff2 +0 -0
- package/fonts/libre-baskerville-400i-latin.woff2 +0 -0
- package/fonts/libre-baskerville-700-latin-ext.woff2 +0 -0
- package/fonts/libre-baskerville-700-latin.woff2 +0 -0
- package/fonts/montserrat-300-latin-ext.woff2 +0 -0
- package/fonts/montserrat-300-latin.woff2 +0 -0
- package/fonts/montserrat-400-latin-ext.woff2 +0 -0
- package/fonts/montserrat-400-latin.woff2 +0 -0
- package/fonts/montserrat-400i-latin-ext.woff2 +0 -0
- package/fonts/montserrat-400i-latin.woff2 +0 -0
- package/fonts/montserrat-500-latin-ext.woff2 +0 -0
- package/fonts/montserrat-500-latin.woff2 +0 -0
- package/fonts/montserrat-700-latin-ext.woff2 +0 -0
- package/fonts/montserrat-700-latin.woff2 +0 -0
- package/icons/LICENSE-heroicons +21 -0
- package/icons/README.md +186 -0
- package/icons/icons.js +1156 -0
- package/icons/icons.json +1152 -0
- package/icons/manifest.json +595 -0
- package/icons/source/co-building.svg +1 -0
- package/icons/source/co-mark.svg +1 -0
- package/icons/source/es-window-check.svg +1 -0
- package/icons/source/ki-bot.svg +1 -0
- package/icons/source/ui-academic-cap.svg +1 -0
- package/icons/source/ui-adjustments-horizontal.svg +1 -0
- package/icons/source/ui-arrow-down-tray-2.svg +1 -0
- package/icons/source/ui-arrow-down-tray.svg +1 -0
- package/icons/source/ui-arrow-path.svg +1 -0
- package/icons/source/ui-arrow-trending-up.svg +1 -0
- package/icons/source/ui-banknotes.svg +1 -0
- package/icons/source/ui-bars-3-center-left.svg +1 -0
- package/icons/source/ui-bars-3.svg +1 -0
- package/icons/source/ui-bolt-2.svg +1 -0
- package/icons/source/ui-bolt.svg +1 -0
- package/icons/source/ui-book-open.svg +1 -0
- package/icons/source/ui-briefcase-2.svg +1 -0
- package/icons/source/ui-briefcase.svg +1 -0
- package/icons/source/ui-building-office.svg +1 -0
- package/icons/source/ui-calendar-days.svg +1 -0
- package/icons/source/ui-calendar.svg +1 -0
- package/icons/source/ui-caret-down.svg +1 -0
- package/icons/source/ui-chart-bar.svg +1 -0
- package/icons/source/ui-chat-bubble-left-right.svg +1 -0
- package/icons/source/ui-chat-bubble-oval-left-ellipsis.svg +1 -0
- package/icons/source/ui-chat-bubble-oval.svg +1 -0
- package/icons/source/ui-check-badge.svg +1 -0
- package/icons/source/ui-check-circle-2.svg +1 -0
- package/icons/source/ui-check-circle.svg +1 -0
- package/icons/source/ui-check.svg +1 -0
- package/icons/source/ui-chevron-down.svg +1 -0
- package/icons/source/ui-chevron-up-down.svg +1 -0
- package/icons/source/ui-circle-stack.svg +1 -0
- package/icons/source/ui-clock.svg +1 -0
- package/icons/source/ui-code-bracket-2.svg +1 -0
- package/icons/source/ui-code-bracket-square.svg +1 -0
- package/icons/source/ui-code-bracket.svg +1 -0
- package/icons/source/ui-cog-6tooth.svg +1 -0
- package/icons/source/ui-cog.svg +1 -0
- package/icons/source/ui-computer-desktop.svg +1 -0
- package/icons/source/ui-cpu-chip-2.svg +1 -0
- package/icons/source/ui-cpu-chip.svg +1 -0
- package/icons/source/ui-cube-2.svg +1 -0
- package/icons/source/ui-cube-transparent.svg +1 -0
- package/icons/source/ui-cube.svg +1 -0
- package/icons/source/ui-currency-euro.svg +1 -0
- package/icons/source/ui-cursor-arrow-rays.svg +1 -0
- package/icons/source/ui-device-phone-mobile.svg +1 -0
- package/icons/source/ui-document-text.svg +1 -0
- package/icons/source/ui-face-smile.svg +1 -0
- package/icons/source/ui-flag.svg +1 -0
- package/icons/source/ui-folder.svg +1 -0
- package/icons/source/ui-hand-raised.svg +1 -0
- package/icons/source/ui-heart.svg +1 -0
- package/icons/source/ui-information-circle.svg +1 -0
- package/icons/source/ui-language.svg +1 -0
- package/icons/source/ui-link.svg +1 -0
- package/icons/source/ui-list-bullet.svg +1 -0
- package/icons/source/ui-lock-closed-2.svg +1 -0
- package/icons/source/ui-lock-closed.svg +1 -0
- package/icons/source/ui-magnifying-glass.svg +1 -0
- package/icons/source/ui-map-pin-2.svg +1 -0
- package/icons/source/ui-map-pin.svg +1 -0
- package/icons/source/ui-megaphone.svg +1 -0
- package/icons/source/ui-newspaper-2.svg +1 -0
- package/icons/source/ui-newspaper.svg +1 -0
- package/icons/source/ui-pause.svg +1 -0
- package/icons/source/ui-pencil-square.svg +1 -0
- package/icons/source/ui-photo.svg +1 -0
- package/icons/source/ui-play.svg +1 -0
- package/icons/source/ui-puzzle-piece.svg +1 -0
- package/icons/source/ui-quote.svg +1 -0
- package/icons/source/ui-rectangle-stack.svg +1 -0
- package/icons/source/ui-rocket-launch.svg +1 -0
- package/icons/source/ui-shield-check-2.svg +1 -0
- package/icons/source/ui-shield-check.svg +1 -0
- package/icons/source/ui-sparkles-2.svg +1 -0
- package/icons/source/ui-sparkles-3.svg +1 -0
- package/icons/source/ui-sparkles-4.svg +1 -0
- package/icons/source/ui-sparkles.svg +1 -0
- package/icons/source/ui-square-2-stack.svg +1 -0
- package/icons/source/ui-squares-2x2.svg +1 -0
- package/icons/source/ui-squares-plus.svg +1 -0
- package/icons/source/ui-star-2.svg +1 -0
- package/icons/source/ui-star.svg +1 -0
- package/icons/source/ui-sun.svg +1 -0
- package/icons/source/ui-swatch.svg +1 -0
- package/icons/source/ui-table-cells.svg +1 -0
- package/icons/source/ui-tag.svg +1 -0
- package/icons/source/ui-trophy-2.svg +1 -0
- package/icons/source/ui-trophy.svg +1 -0
- package/icons/source/ui-user-group-2.svg +1 -0
- package/icons/source/ui-user-group.svg +1 -0
- package/icons/source/ui-users-2.svg +1 -0
- package/icons/source/ui-users.svg +1 -0
- package/icons/source/ui-viewfinder-circle.svg +1 -0
- package/icons/source/ui-window.svg +1 -0
- package/icons/source/ui-wrench-screwdriver.svg +1 -0
- package/icons/source/wo-network.svg +1 -0
- package/package.json +87 -0
- package/tokens/tokens.js +229 -0
- package/tokens/tokens.json +227 -0
- package/tokens/tokens.scss +228 -0
|
@@ -0,0 +1,2891 @@
|
|
|
1
|
+
/*! Conciso Design System — gebündelt. Quelle: css/fonts.css → css/tokens.css → css/dark-mode.css → css/base.css → css/components.css. Generiert, nicht manuell editieren. */
|
|
2
|
+
/* === css/fonts.css === */
|
|
3
|
+
/* Conciso Design System — Self-Host-Fonts (DSGVO: keine Google-CDN-Anfrage).
|
|
4
|
+
Montserrat + Libre Baskerville, Subsets latin + latin-ext, font-display:swap.
|
|
5
|
+
Lizenz: SIL Open Font License 1.1 (siehe fonts/*-OFL.txt). Generiert. */
|
|
6
|
+
|
|
7
|
+
@font-face{font-family:'Libre Baskerville';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/libre-baskerville-400i-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
8
|
+
@font-face{font-family:'Libre Baskerville';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/libre-baskerville-400i-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
9
|
+
@font-face{font-family:'Libre Baskerville';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/libre-baskerville-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
10
|
+
@font-face{font-family:'Libre Baskerville';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/libre-baskerville-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
11
|
+
@font-face{font-family:'Libre Baskerville';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/libre-baskerville-700-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
12
|
+
@font-face{font-family:'Libre Baskerville';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/libre-baskerville-700-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
13
|
+
@font-face{font-family:'Montserrat';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/montserrat-400i-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
14
|
+
@font-face{font-family:'Montserrat';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/montserrat-400i-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
15
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:300;font-display:swap;src:url('../fonts/montserrat-300-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
16
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:300;font-display:swap;src:url('../fonts/montserrat-300-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
17
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/montserrat-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
18
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/montserrat-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
19
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/montserrat-500-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
20
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/montserrat-500-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
21
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/montserrat-700-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
|
|
22
|
+
@font-face{font-family:'Montserrat';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/montserrat-700-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
|
|
23
|
+
|
|
24
|
+
/* === css/tokens.css === */
|
|
25
|
+
/* ── Design Tokens ── */
|
|
26
|
+
:root {
|
|
27
|
+
/* ── Corporate (Global Brand) ── */
|
|
28
|
+
--co-500:#00BEBE; --co-50:#E0F7F7; --co-100:#B3ECEC; --co-200:#80DEDE;
|
|
29
|
+
--co-300:#4DD0D0; --co-400:#26C2C2; --co-600:#009E9E; --co-700:#007575;
|
|
30
|
+
--co-800:#004F4F; --co-900:#002B2B; --co-ink:var(--co-700);
|
|
31
|
+
|
|
32
|
+
/* ── AI.Applied ── */
|
|
33
|
+
--ki-500:#B5E61C; --ki-50:#F4FCD5; --ki-100:#E6F8A0; --ki-200:#D6F06D;
|
|
34
|
+
--ki-300:#C8EA42; --ki-400:#BEE82D; --ki-600:#8FAF0E; --ki-700:#6B8208;
|
|
35
|
+
--ki-800:#475705; --ki-900:#242C02; --ki-ink:var(--ki-800); /* farbiger ki-Text/Icons; flippt im Dark auf --ki-200 (dark-mode.css), da ki-800 dunkel-auf-dunkel wäre */
|
|
36
|
+
|
|
37
|
+
/* ── Wirksame Organisationen ── */
|
|
38
|
+
--wo-500:#44A030; --wo-50:#EBF5E6; --wo-100:#CEEAC3; --wo-200:#A3D48E;
|
|
39
|
+
--wo-300:#72BD58; --wo-400:#55AD3F; --wo-600:#347A22; --wo-700:#285E1A;
|
|
40
|
+
--wo-800:#183A0E; --wo-900:#0A1F05; --wo-ink:var(--wo-700);
|
|
41
|
+
|
|
42
|
+
/* ── Effektive Software ── */
|
|
43
|
+
--es-500:#2F5FD4; --es-50:#EAF0FB; --es-100:#C8D9F5; --es-200:#98B7EE;
|
|
44
|
+
--es-300:#6593E5; --es-400:#4677DC; --es-600:#2249B2; --es-700:#1B3D9A;
|
|
45
|
+
--es-800:#112568; --es-900:#071035; --es-ink:var(--es-700);
|
|
46
|
+
|
|
47
|
+
/* ── Bereichs-Akzenttext ──
|
|
48
|
+
--XX-ink ist farbiger Text und farbige Icons, die in BEIDEN Modi lesbar bleiben müssen:
|
|
49
|
+
Light der dunkle Ton (-700, ki -800 weil ki-700 nur 4,05:1 trägt), Dark der helle (-200,
|
|
50
|
+
es -100). Bisher gab es das nur für ki, und genau deshalb ist bei jeder Korrektur die Gefahr,
|
|
51
|
+
eine Light-Farbe zu setzen, die im Dark dunkel-auf-dunkel läuft: co-700 trägt auf Weiß 5,52:1
|
|
52
|
+
und auf der dunklen Seite nur 3,17:1. Wer farbigen Text setzt, nimmt --XX-ink. */
|
|
53
|
+
|
|
54
|
+
/* ── Rosé ── */
|
|
55
|
+
--ro-500:#C23060; --ro-50:#FDEDF2; --ro-100:#F9CEDD; --ro-200:#F0A0BE;
|
|
56
|
+
--ro-300:#E06898; --ro-400:#CF4478; --ro-600:#A02050; --ro-700:#7E1639;
|
|
57
|
+
--ro-800:#560E26; --ro-900:#2E0513;
|
|
58
|
+
|
|
59
|
+
/* ── Bereichs-Bänder ──
|
|
60
|
+
--XX-band ist die Fläche großer getönter Sektionen (Hero, CTA-Band). Im Light identisch mit
|
|
61
|
+
--XX-50, es gibt also nichts zu unterscheiden. Getrennt wird es erst im Dark: dort muss ein
|
|
62
|
+
Band dunkler bleiben als die Karten, die darauf sitzen, während eine Badge- oder Kachel-Füllung
|
|
63
|
+
umgekehrt heller als ihr Grund sein muss, um überhaupt als Fläche zu lesen. Ein Wert kann
|
|
64
|
+
beides nicht leisten, deshalb zwei Token. */
|
|
65
|
+
--co-band:var(--co-50); --ki-band:var(--ki-50); --es-band:var(--es-50); --wo-band:var(--wo-50);
|
|
66
|
+
|
|
67
|
+
/* ── Bauteil-Füllungen ──
|
|
68
|
+
--XX-fill ist die Füllung von Pill und Bereichs-Badge. Im Light ist das der ruhige Tint, also
|
|
69
|
+
dasselbe Rezept wie bei den Icon-Kacheln: zarte Fläche, kräftige dunkle Schrift darauf
|
|
70
|
+
(7,5 bis 11,4:1). WCAG verlangt für diese Fläche nichts, das Label trägt die Aussage, und
|
|
71
|
+
darüber entscheidet das Markenrad: „Ruhig“. Die Schrift wirkt auf dem zarten Grund kräftiger,
|
|
72
|
+
weil sie nicht mit der Fläche konkurriert.
|
|
73
|
+
Getrennt wird es erst im Dark: dort liegt helle Schrift auf dunklem Tint, und wenn der Tint
|
|
74
|
+
fast die Helligkeit der Karte hat, hält nichts mehr die Pill zusammen. Deshalb dort eigene,
|
|
75
|
+
gehobene Werte (siehe dark-mode.css). Gleiche Rolle, zwei Werte, wie bei --XX-band.
|
|
76
|
+
Kein --ro-fill: Rosé ist Akzent- und Statusfarbe, es gibt weder ro-Pill noch ro-Badge.
|
|
77
|
+
|
|
78
|
+
Abgrenzung nach oben und unten: --XX-50 bleibt der RUHIGE Tint, in beiden Modi. Er trägt
|
|
79
|
+
dekorative Flächen (Icon-Kachel, Timeline-Marker, Hover-Füllung des Chips, Inline-Code), die
|
|
80
|
+
nicht als Fläche lesen müssen: WCAG verlangt dort nichts, und das Markenrad sagt „Ruhig“.
|
|
81
|
+
--XX-band ist die große Sektionsfläche. Drei Rollen, drei Namen. */
|
|
82
|
+
--co-fill:var(--co-50); --ki-fill:var(--ki-50); --es-fill:var(--es-50); --wo-fill:var(--wo-50);
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
/* ── Neutrals ── */
|
|
86
|
+
--n-0:#FFFFFF; --n-50:#F5F7F7; --n-100:#E8EDED; --n-200:#C9D3D3;
|
|
87
|
+
--n-300:#A0B0B0; --n-400:#6E8585; --n-500:#4A6565; --n-600:#2E4545;
|
|
88
|
+
--n-700:#1A2E2E; --n-800:#0D1F1F; --n-900:#060F0F;
|
|
89
|
+
|
|
90
|
+
/* ── Semantic ──
|
|
91
|
+
--c-* sind Text-Farben (Required-Asterisk, Inline-Fehlertext, Do/Don't-Marker).
|
|
92
|
+
Werte sind in beiden Modi auf AA-Lesbarkeit auf der jeweiligen page-bg ausgelegt.
|
|
93
|
+
Light: dunklere/gedeckte Sättigung für Kontrast auf weiß. Dark-Overrides in dark-mode.css.
|
|
94
|
+
--c-*-bg sind Tint-Hintergründe für Callouts; Text darauf via --badge-*-text. */
|
|
95
|
+
/* Die -bg-Tints sind Bauteil-Füllungen (Callout, Status-Badge, Trend-Chip) und müssen als FLÄCHE
|
|
96
|
+
lesen: 1,3:1 gegen Weiß UND gegen n-50 (CONTRIBUTING § 3). Die alten Werte lagen bei 1,02 bis
|
|
97
|
+
1,16:1, das Element las nur noch als farbiger Text. Neu gemessen Fläche Weiß / n-50 und Text
|
|
98
|
+
darauf: success 1,43 / 1,33 mit 4,91:1 · warning 1,47 / 1,37 mit 4,84:1 · error 1,60 / 1,49
|
|
99
|
+
mit 4,99:1. Beim Warnton musste der Text mitwandern (--badge-warn-text), auf der kräftigeren
|
|
100
|
+
Füllung trug #8A5E0A nur 3,87:1. */
|
|
101
|
+
--c-success:#0E6644; --c-success-bg:#A9E5C8; /* Text auf #fff: 6.99:1 ✓ AAA */
|
|
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
|
+
--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
|
+
|
|
105
|
+
/* ── Component color tokens (theme-overridable) ── */
|
|
106
|
+
--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
|
+
--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 */
|
|
108
|
+
--cbadge-aa-bg:#E6F9F1; --cbadge-aa-text:#0a5c38;
|
|
109
|
+
--cbadge-aaa-bg:#D0F0FF; --cbadge-aaa-text:#004466;
|
|
110
|
+
--cbadge-fail-bg:#FDEAEA; --cbadge-fail-text:#9b2020;
|
|
111
|
+
|
|
112
|
+
/* ── Surfaces & Text ── */
|
|
113
|
+
--bg-page:#FFFFFF; --bg-surface:var(--n-0); --bg-overlay:rgba(0,94,94,.06); --bg-code:var(--n-800);
|
|
114
|
+
/* --bg-surface-hover: gehobene Fläche interaktiver Elemente im Hover. Light bewusst gleich
|
|
115
|
+
--bg-surface: auf weißem Grund trägt die Tiefe der Schatten (--e3), eine Aufhellung gäbe es
|
|
116
|
+
nicht. Im Dark trägt der Schatten weniger, dort hebt der Zustand zusätzlich die Fläche.
|
|
117
|
+
Es ist ein Zustand, keine dritte statische Flächen-Stufe. */
|
|
118
|
+
--bg-surface-hover:var(--bg-surface);
|
|
119
|
+
/* --bg-plate: helle Platte unter Fremd-Assets, die nur in einer dunklen Fassung vorliegen
|
|
120
|
+
(Kundenlogos). Im Dark gedämpft statt reinweiß, weil eine reinweiße Fläche dieser Größe
|
|
121
|
+
auf dunklem Grund blendet. */
|
|
122
|
+
--bg-plate:#FFFFFF;
|
|
123
|
+
--tx-brand:#333E48; --tx-primary:#333E48; --tx-secondary:var(--n-500); --tx-muted:#5A7171; /* Auf Weiß 5,20:1, auf n-50 4,84:1, auf getönten Hellflächen 4,66 bis 4,73:1.
|
|
124
|
+
Vorher #5E7676: auf Weiß 4,85:1 ✓, aber auf n-50 und getönten Gründen nur 4,35 bis 4,51:1, also
|
|
125
|
+
genau dort unter AA, wo gedämpfter Text meist sitzt (Meta-Zeilen, Annotationen, Specimen-Labels).
|
|
126
|
+
Bleibt klar heller als --tx-secondary (#4A6565, 5,63 bis 6,29:1), die Hierarchie bleibt also. */
|
|
127
|
+
|
|
128
|
+
/* ── Typography ── */
|
|
129
|
+
--font:'Montserrat','Segoe UI',system-ui,-apple-system,sans-serif;
|
|
130
|
+
--font-display:'Libre Baskerville','Georgia',serif;
|
|
131
|
+
/* --font-mono: dritte Schriftrolle des Systems (Code/Werte), bisher zehnmal hart im CSS.
|
|
132
|
+
Wert unverändert übernommen, reiner Struktur-Schritt, keine gerenderte Änderung. */
|
|
133
|
+
--font-mono:'Courier New',monospace;
|
|
134
|
+
|
|
135
|
+
/* ── Typography Scale ──
|
|
136
|
+
Einheiten rem-basiert (Juli 2026, WCAG 1.4.4 "Resize Text"): 1rem = 16px bei Default-Root
|
|
137
|
+
(body: font-size:16px). Umrechnung px→rem = px/16. rem respektiert die vom Nutzer im Browser
|
|
138
|
+
eingestellte Standardschriftgröße; px täte das nicht.
|
|
139
|
+
Minimum-Font-Size systemweit: 12 px = 0.75rem. Das Minimum gilt bei Default-Root und skaliert
|
|
140
|
+
bei größerer Nutzereinstellung nach oben. Tokens darunter wurden eliminiert oder angehoben,
|
|
141
|
+
damit Inhalte unter allen Bedingungen gut lesbar bleiben (Bildschirm, Mobile, Print). */
|
|
142
|
+
/* Sans-serif (Montserrat)
|
|
143
|
+
Body-Skala (Mai 2026): 16 / 14 / 12 px. Body Md ist Standard-Fließtext (war 14, jetzt 16
|
|
144
|
+
für bessere Lesbarkeit auf C-Level-Mittelstand-Zielgruppe und iOS-Auto-Zoom-Fix bei Form-Inputs).
|
|
145
|
+
Body Sm = 14 px für Meta-Daten/Card-Meta. Body Xs = 12 px für Captions. */
|
|
146
|
+
--ty-caption: 400 0.75rem/1rem var(--font);
|
|
147
|
+
--ty-body-xs: 400 0.75rem/1rem var(--font);
|
|
148
|
+
--ty-body-sm: 400 0.875rem/1.25rem var(--font);
|
|
149
|
+
--ty-body-md: 400 1rem/1.5rem var(--font);
|
|
150
|
+
/* label-xs und label-sm haben dieselben Metriken — label-xs ist die "Eyebrow"-Variante,
|
|
151
|
+
mit text-transform:uppercase + letter-spacing am Use-Site. label-sm ist für Mixed-Case-Labels. */
|
|
152
|
+
--ty-label-xs: 500 0.75rem/1rem var(--font);
|
|
153
|
+
--ty-label-sm: 500 0.75rem/1rem var(--font);
|
|
154
|
+
--ty-label-md: 500 0.875rem/1.25rem var(--font);
|
|
155
|
+
/* Title-Sm (Mai 2026): 20 px statt 18 px, damit Card-Titel mit klarer 4-px-Stufe über
|
|
156
|
+
dem neuen 16-px-Body-Md sitzen. Title-Lg ist entfallen, das Logo nutzt jetzt eine eigene
|
|
157
|
+
Klasse .nav-logo-text mit fest verdrahteten Metriken. */
|
|
158
|
+
--ty-title-sm: 500 1.25rem/1.75rem var(--font);
|
|
159
|
+
--ty-label-xs-strong: 600 0.75rem/1rem var(--font);
|
|
160
|
+
--ty-name: 600 0.875rem/1.25rem var(--font);
|
|
161
|
+
/* Display / serif (Libre Baskerville) */
|
|
162
|
+
--ty-serif-sm: 400 1.0625rem/1.75rem var(--font-display);
|
|
163
|
+
--ty-serif-md: 400 1.25rem/1.75rem var(--font-display);
|
|
164
|
+
--ty-serif-lg: 400 1.25rem/2rem var(--font-display);
|
|
165
|
+
/* Headline/Display fluid: font-size via clamp(), Zeilenhöhe als unitless Ratio
|
|
166
|
+
(skaliert proportional zur gerechneten Größe, nie < 1 — siehe line-height-Konvention).
|
|
167
|
+
rem-basiert (Juli 2026, WCAG 1.4.4 "Resize Text"): Min/Max in rem, Mittel-Term als
|
|
168
|
+
rem + vw, damit die Schrift auch die Browser-Standardschriftgröße respektiert (px+vw
|
|
169
|
+
reagierte nur auf Seiten-Zoom). Mittel-Term = Zwei-Anker-Fluid-Kurve (Anker 360 px → Min,
|
|
170
|
+
1240 px → Max); rem-Anteil trägt die Basis (resize-fähig), vw fügt fluides Wachstum hinzu.
|
|
171
|
+
Max = bisheriger Fixwert → Desktop unverändert; Min greift am Phone (alle ≥ 1.25rem =
|
|
172
|
+
20 px @ Default, also ≥ Font-Size-Minimum). Mirror von --ty-display-lg. */
|
|
173
|
+
--ty-headline-xs: 400 clamp(1.25rem, 1.2rem + 0.23vw, 1.375rem)/1.35 var(--font-display);
|
|
174
|
+
--ty-headline-sm: 400 clamp(1.3125rem, 1.236rem + 0.34vw, 1.5rem)/1.33 var(--font-display);
|
|
175
|
+
--ty-headline-md: 400 clamp(1.4375rem, 1.31rem + 0.57vw, 1.75rem)/1.3 var(--font-display);
|
|
176
|
+
--ty-display-sm: 400 clamp(1.75rem, 1.546rem + 0.91vw, 2.25rem)/1.22 var(--font-display);
|
|
177
|
+
--ty-display-md: 400 clamp(1.875rem, 1.619rem + 1.14vw, 2.5rem)/1.2 var(--font-display);
|
|
178
|
+
--ty-display-lg: 400 clamp(1.75rem, 1.29rem + 2.05vw, 2.875rem)/1.15 var(--font-display);
|
|
179
|
+
|
|
180
|
+
/* ── Spacing ── */
|
|
181
|
+
--s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:20px;--s6:24px;--s8:32px;--s10:40px;--s12:48px;--s16:64px;
|
|
182
|
+
|
|
183
|
+
/* ── Shape (5 Stufen) ── */
|
|
184
|
+
--r-xs:4px; --r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:28px; --r-full:9999px;
|
|
185
|
+
|
|
186
|
+
/* ── Elevation (Shadow + Tonal Overlay) ── */
|
|
187
|
+
--e0:none;
|
|
188
|
+
--e1:0 1px 2px rgba(0,0,0,.30),0 1px 3px 1px rgba(0,0,0,.15);
|
|
189
|
+
--e2:0 1px 2px rgba(0,0,0,.30),0 2px 6px 2px rgba(0,0,0,.15);
|
|
190
|
+
--e3:0 1px 3px rgba(0,0,0,.30),0 4px 8px 3px rgba(0,0,0,.15);
|
|
191
|
+
--e4:0 2px 3px rgba(0,0,0,.30),0 6px 10px 4px rgba(0,0,0,.15);
|
|
192
|
+
--e5:0 4px 4px rgba(0,0,0,.30),0 8px 12px 6px rgba(0,0,0,.15);
|
|
193
|
+
/* Tonal overlay: primärfarbe auf Oberfläche aufgebracht */
|
|
194
|
+
--tonal-1:rgba(0,190,190,.05); --tonal-2:rgba(0,190,190,.08);
|
|
195
|
+
--tonal-3:rgba(0,190,190,.11); --tonal-4:rgba(0,190,190,.12);
|
|
196
|
+
--tonal-5:rgba(0,190,190,.14);
|
|
197
|
+
|
|
198
|
+
/* ── Motion ── */
|
|
199
|
+
--m-fast:150ms cubic-bezier(.4,0,.2,1); --m-std:250ms cubic-bezier(.4,0,.2,1);
|
|
200
|
+
|
|
201
|
+
/* ── Icon Stroke-Width ── */
|
|
202
|
+
--icon-stroke-micro:1;
|
|
203
|
+
--icon-stroke-sm:1.25;
|
|
204
|
+
--icon-stroke-md:1.5;
|
|
205
|
+
--icon-stroke-lg:2;
|
|
206
|
+
--icon-stroke-xl:2.5;
|
|
207
|
+
|
|
208
|
+
/* ── Borders ──
|
|
209
|
+
Zwei Rollen, nicht zwei Stärken: --bd ist die Trennlinie INNERHALB eines Bauteils
|
|
210
|
+
(Card-Footer, Tabellenzeile, Caption-Kante), --bd-strong die AUSSENKANTE einer Fläche
|
|
211
|
+
(Karte, Kasten, schwebendes Panel). Beide sind 1px; die Kante muss nur mehr tragen, weil sie
|
|
212
|
+
eine Fläche gegen ihren Grund abgrenzt, während die Trennlinie innerhalb einer schon
|
|
213
|
+
abgegrenzten Fläche liegt.
|
|
214
|
+
--bd-strong-c war n-200 und trug im Light nur 1,53:1 gegen Weiß und 1,42:1 gegen eine
|
|
215
|
+
n-50-Sektion; eine weiße Karte auf weißem Grund war damit praktisch randlos, obwohl genau
|
|
216
|
+
dieser Rand sie laut Konvention zur Fläche macht. n-300 gibt 2,25:1 bzw. 2,09:1 und bleibt
|
|
217
|
+
ruhig. Der Dark-Wert (#8694A5, 4,21:1) war nie das Problem und ändert sich nicht.
|
|
218
|
+
--bd-c / --bd-strong-c halten die reine Farbe. --bd und --bd-strong sind Shorthand-Werte und
|
|
219
|
+
lassen sich nicht in border-color einsetzen; Regeln, die nur die Farbe brauchen (z. B. der
|
|
220
|
+
verstärkte Rand schwebender Panels im Dark), greifen deshalb auf die -c-Variante zu, statt den
|
|
221
|
+
Hexwert ein zweites Mal zu führen. */
|
|
222
|
+
--bd-c:var(--n-100); --bd-strong-c:var(--n-300);
|
|
223
|
+
--bd:1px solid var(--bd-c); --bd-strong:1px solid var(--bd-strong-c);
|
|
224
|
+
--field-border:var(--n-400); /* Formularfeld-Rahmen: 4.13:1 auf bg-surface (#fff) → WCAG 1.4.11 ✓. n-200 (#C9D3D3) verfehlte mit 1.5:1. */
|
|
225
|
+
|
|
226
|
+
/* ── Focus ── */
|
|
227
|
+
/* Sichtbarer Ring co-700 (nicht co-500): co-500 #00BEBE erreicht auf Weiß nur 2,3:1 und verfehlt
|
|
228
|
+
die 3:1-Schwelle für Fokus-Indikatoren (WCAG 2.4.11). co-700 #007575 = 5,5:1. Gilt global (alle
|
|
229
|
+
:focus-visible-Ringe im DS nutzen diese Tokens). Dark bleibt co-500 (dort 4,7:1 auf dunklem Grund,
|
|
230
|
+
co-700 wäre dunkel-auf-dunkel) — s. dark-mode.css. */
|
|
231
|
+
--focus-ring:0 0 0 3px var(--co-50),0 0 0 5px var(--co-700);
|
|
232
|
+
--focus-aa:0 0 0 2px var(--bg-surface),0 0 0 4px var(--co-700);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* === css/dark-mode.css === */
|
|
236
|
+
/* ── Dark Mode & Theme Overrides ── */
|
|
237
|
+
|
|
238
|
+
/* ════════════════════════════════════════════
|
|
239
|
+
DARK MODE
|
|
240
|
+
════════════════════════════════════════════ */
|
|
241
|
+
/* @media screen umschließt die GANZE Datei, Token-Block und Komponenten-Regeln. Im Druck greifen
|
|
242
|
+
dadurch die Light-Werte aus tokens.css, ohne dass sie hier ein zweites Mal stehen (eine Kopie
|
|
243
|
+
wäre eine zweite Quelle der Wahrheit und würde auseinanderlaufen). Ohne das druckt eine Seite
|
|
244
|
+
mit data-theme="dark" die volle dunkle Fläche: sehr viel Farbauftrag, und auf vielen Druckern
|
|
245
|
+
heller Text auf grauem Grund.
|
|
246
|
+
Die Komponenten-Regeln müssen mit hinein: 183 von ihnen setzen eine helle Tint- oder Festfarbe
|
|
247
|
+
(co-200, ki-200, es-100, heller tx-primary). Auf dem hellen Druckgrund tragen die 1,2 bis 1,9:1,
|
|
248
|
+
die Zeile wäre also unlesbar. Nur den Token-Block zu schützen hätte den Text genau dort verloren,
|
|
249
|
+
wo eine eigene Dark-Regel greift. Neue Dark-Regeln deshalb immer INNERHALB dieses Blocks. */
|
|
250
|
+
@media screen {
|
|
251
|
+
[data-theme="dark"] {
|
|
252
|
+
/* Native Controls (Checkbox, Radio, Scrollbar, Select-Popup) im Dark-Theme rendern lassen,
|
|
253
|
+
statt hell-thematisiert auf dunklem Grund — sonst wirkt die Checkbox wie ein Fremdkörper. */
|
|
254
|
+
color-scheme: dark;
|
|
255
|
+
/* Surfaces: Flächen-Leiter nach der Material-Dark-Theme-Guidance.
|
|
256
|
+
Dark-only: bg-page #333E48 ❌ 10,92:1 gegen Weiß → #151A1F ✓ 17,51:1. (Light: #FFFFFF.)
|
|
257
|
+
Gefordert sind mindestens 15,8:1. Die Schwelle ist kein Stilmittel, sondern der Puffer, der
|
|
258
|
+
Fließtext auch auf der höchsten Elevationsstufe noch 4,5:1 sichert. Der Altwert war wörtlich
|
|
259
|
+
--tx-brand aus dem Light Mode, also eine gegen Weiß optimierte Textfarbe, keine Fläche.
|
|
260
|
+
Farbwinkel 209 (Slate) durchgehend, damit der Marken-Ton erhalten bleibt.
|
|
261
|
+
Dark-only: Stufe bg-page zu bg-surface ❌ 1,223:1 → ✓ 1,346:1. Trotz tieferer Basis wächst die
|
|
262
|
+
Tiefe, weil mehr Kopfraum nach unten mehr Spielraum nach oben schafft. */
|
|
263
|
+
--bg-page:#151A1F; --bg-surface:#28323D; --bg-overlay:rgba(0,190,190,.10);
|
|
264
|
+
/* Dark-only: bg-code #060D0D ❌ 1,12:1 gegen die neue Seite, der Well verschwand → #07090C ✓
|
|
265
|
+
1,14:1, zusammen mit dem --bd-Rahmen ablesbar. (Light: n-800 als dunkler Well auf Weiß.) */
|
|
266
|
+
--bg-code:#07090C;
|
|
267
|
+
/* Dark-only: Hover interaktiver Flächen, 11,47:1. Die Schatten tragen auf 17,51:1 weniger als
|
|
268
|
+
auf dem alten #333E48, deshalb hebt der Zustand zusätzlich die Fläche. Entspricht etwa 14 dp
|
|
269
|
+
im Material-Overlay-Modell. Das ist ein Zustand, KEINE dritte statische Flächen-Stufe.
|
|
270
|
+
(Light: gleich bg-surface, dort trägt --e3 die Tiefe.) */
|
|
271
|
+
--bg-surface-hover:#2E3B46;
|
|
272
|
+
/* Dark-only: Logo-Platte #FFFFFF ❌ 17,51:1 gegen die Seite, blendet großflächig → #E8EDED ✓
|
|
273
|
+
14,81:1. Dunkle Kundenlogos darauf weiterhin 14,73:1. (Light: #FFFFFF.) */
|
|
274
|
+
--bg-plate:#E8EDED;
|
|
275
|
+
/* Text */
|
|
276
|
+
--tx-brand:#C4D8D8; --tx-primary:#DDE9E9; --tx-secondary:#A6C6C6; --tx-muted:#93B6B6; /* tx-secondary #A6C6C6 → AA auf bg-surface-Cards (4.9:1); tx-muted von #7A9E9E auf #93B6B6 angehoben → AA auf bg-page (5.0:1), bg-surface 4.1:1, bleibt klar unter tx-secondary */
|
|
277
|
+
/* Neutrals (only lowest, used as bg/border), auf denselben Farbwinkel 209 gezogen.
|
|
278
|
+
Dark-only: n-100 #1C2E2E ❌ 1,09:1 gegen die neue bg-surface, Füllungen auf Cards
|
|
279
|
+
verschwanden → #1E262E ✓ 1,18:1 zur Card und 1,14:1 zur Seite, trägt also in beide
|
|
280
|
+
Richtungen. n-50 bleibt die tiefste Stufe, 19,25:1. (Light: #F5F7F7 / #E8EDED.) */
|
|
281
|
+
--n-50:#0B0F11; --n-100:#1E262E;
|
|
282
|
+
/* Borders. Dark-only: bd #818C99 ❌ auf der tieferen Seite 5,12:1, die Haarlinie wirkte drahtig
|
|
283
|
+
→ #6F7A89 ✓ 4,02:1 auf der Seite, 2,99:1 auf der Card. bd ist dekorative Trennung, nicht das
|
|
284
|
+
alleinige Erkennungsmerkmal eines Bedienelements. (Light: n-100 / n-200.) */
|
|
285
|
+
--bd-c:#6F7A89; --bd-strong-c:#8694A5;
|
|
286
|
+
--bd:1px solid var(--bd-c); --bd-strong:1px solid var(--bd-strong-c);
|
|
287
|
+
/* Dark-only: field-border war n-200 #C9D3D3 ❌ 11,46:1 gegen die neue Seite, ein greller Rahmen
|
|
288
|
+
→ #869C9C ✓ 6,04:1 auf der Seite und 4,49:1 auf der Card. Der Feldrahmen ist die einzige
|
|
289
|
+
Grenze, die WCAG 1.4.11 zwingend braucht, und liegt damit sicher über 3:1. (Light: n-400.) */
|
|
290
|
+
--field-border:#869C9C;
|
|
291
|
+
/* Focus: innerer Ring = bg-page für den Cutout-Effekt. Folgt jetzt dem Token statt einem
|
|
292
|
+
hartkodierten #333E48, dadurch laufen beide Ringe bei künftigen Flächen-Änderungen mit.
|
|
293
|
+
co-500 trägt 7,59:1 auf der Seite, 5,64:1 auf der Card, 4,98:1 auf der Hover-Card. */
|
|
294
|
+
--focus-ring:0 0 0 3px var(--bg-page),0 0 0 5px var(--co-500);
|
|
295
|
+
--focus-aa:0 0 0 2px var(--bg-page),0 0 0 4px var(--co-500);
|
|
296
|
+
/* Elevation – heavier shadows on dark */
|
|
297
|
+
--e1:0 1px 2px rgba(0,0,0,.60),0 1px 3px 1px rgba(0,0,0,.40);
|
|
298
|
+
--e2:0 1px 2px rgba(0,0,0,.60),0 2px 6px 2px rgba(0,0,0,.40);
|
|
299
|
+
--e3:0 1px 3px rgba(0,0,0,.60),0 4px 8px 3px rgba(0,0,0,.40);
|
|
300
|
+
--e4:0 2px 3px rgba(0,0,0,.70),0 6px 10px 4px rgba(0,0,0,.40);
|
|
301
|
+
--e5:0 4px 4px rgba(0,0,0,.70),0 8px 12px 6px rgba(0,0,0,.40);
|
|
302
|
+
/* Semantic backgrounds: Callout- und Badge-Tints, auf derselben Stufe wie die kleinen
|
|
303
|
+
Bereichs-Füllungen (9,8:1).
|
|
304
|
+
Dark-only: c-warning-bg #231800 ❌ 1,00:1 gegen die neue Seite, die Fläche war dort schlicht
|
|
305
|
+
unsichtbar → #544115 ✓ 1,79:1 zur Seite, 1,33:1 zur Card. success und error mitgezogen, damit
|
|
306
|
+
die drei Status-Flächen auf einer Stufe liegen. Statustexte darauf 5,2 bis 6,3:1.
|
|
307
|
+
(Light: helle Tints auf Weiß.) */
|
|
308
|
+
--c-success-bg:#1F573B; --c-warning-bg:#5F4B1E; --c-error-bg:#882725;
|
|
309
|
+
/* Semantic text colors: hellere Pendants für Lesbarkeit auf bg-page (#151A1F).
|
|
310
|
+
Light-Pendants in tokens.css. Verwendung: ✓/✕-Marker, Required-Asterisk, Inline-Fehlertext. */
|
|
311
|
+
--c-success:#5CE8A0; /* auf bg-page: 11.26:1 ✓ AAA · auf bg-surface: 8.37:1 ✓ AAA */
|
|
312
|
+
--c-warning:#F0C060; /* auf bg-page: 10.35:1 ✓ AAA · auf bg-surface: 7.69:1 ✓ AAA */
|
|
313
|
+
--c-error:#FFA5A5; /* auf bg-page: 9.32:1 ✓ AAA · auf bg-surface: 6.93:1 ✓ AAA. Angehoben von
|
|
314
|
+
#FF8E8E, das nur gegen bg-page geprüft war und auf bg-surface 4.0:1
|
|
315
|
+
erreichte. Inline-Fehlertext sitzt aber fast immer auf bg-surface. */
|
|
316
|
+
/* Brand tints (Dark), getrennt nach den zwei Jobs, die --XX-50 im Light in einem Wert erledigt.
|
|
317
|
+
Der Grund: Ein Band muss DUNKLER bleiben als die Karten darauf, eine Badge- oder Kachel-Füllung
|
|
318
|
+
muss HELLER sein als ihr Grund, sonst liest sie nicht als Fläche. Bei einer Basis von 17,51:1
|
|
319
|
+
ist der Spielraum zu klein, damit ein Wert beides trägt.
|
|
320
|
+
|
|
321
|
+
--XX-50 = kleine Fuellung (Badges, Pills, Icon-Kacheln, getoente Select-Flaechen).
|
|
322
|
+
ZWEI Kriterien, nicht eins: Der Kontrastquotient allein greift bei satten Farben zu kurz. Die
|
|
323
|
+
Vorgaengerwerte trugen 1,33:1 gegen die Karte, erfuellten den 1,3:1-Faustwert also, hatten aber
|
|
324
|
+
nur 8,3 L*-Punkte Helligkeitsabstand. Der Unterschied lag damit fast vollstaendig in Farbton
|
|
325
|
+
und Saettigung, und eine satte Flaeche auf gleicher Helligkeit liest als dunkler Fleck statt
|
|
326
|
+
als hellere Stufe; am deutlichsten bei ES, weil Blau bei gleichem L* am dunkelsten wirkt.
|
|
327
|
+
Jetzt um gut 4 L*-Punkte gehoben, Farbton und Saettigung unveraendert (a und b in Lab gleich
|
|
328
|
+
gelassen, nur L angehoben): Flaeche 1,54 bis 1,55:1 gegen die Karte, 2,07 bis 2,09:1 gegen
|
|
329
|
+
die Seite, Helligkeitsabstand 12,5 bis 12,7 L*. Text darauf 4,97:1 (wo, der knappste) bis
|
|
330
|
+
6,64:1, helle -100-Glyphen 5,86 bis 7,34:1. Nach oben bleibt wenig Luft: der wo-Text liegt
|
|
331
|
+
0,47 ueber AA. --ro-50 wird nicht als Fuellung eingesetzt (Rose ist Akzent- und Statusfarbe)
|
|
332
|
+
und bleibt unveraendert.
|
|
333
|
+
(Light: zarter Bereichstint auf Weiss, Bauteil-Fuellungen dort ueber --XX-fill.) */
|
|
334
|
+
--co-50:#134C47; --ki-50:#384912; --wo-50:#144E1F; --es-50:#253C92; --ro-50:#7E1F37;
|
|
335
|
+
/* --XX-band = große getönte Sektionsfläche (Hero, CTA-Band), 16,5:1. Die Bänder lagen früher
|
|
336
|
+
UNTER bg-page (14,0:1 gegen 10,9:1). Nach unten bleibt jetzt nur Faktor 1,20 bis Schwarz, sie
|
|
337
|
+
liegen deshalb knapp ÜBER der Seite und trennen sich von ihr primär über den Farbton statt über
|
|
338
|
+
die Helligkeit (1,06:1). Karten darauf behalten 1,27:1 und bilden weiter die hellere Stufe.
|
|
339
|
+
Sättigung auf 0,60 begrenzt: großflächig gesättigte Farbe „vibriert“ auf dunklem Grund.
|
|
340
|
+
(Light: identisch mit --XX-50, dort gibt es den Konflikt nicht.) */
|
|
341
|
+
--co-band:#092321; --ki-band:#1A2208; --wo-band:#09240E; --es-band:#111C44;
|
|
342
|
+
/* --XX-fill = Füllung kleiner Bauteile (Pill, Bereichs-Badge). Im Dark identisch mit --XX-50, das
|
|
343
|
+
hier ja schon auf genau diese Aufgabe kalibriert ist (1,78:1 zur Seite, 1,32:1 zur Karte). Das
|
|
344
|
+
Token existiert für den Light Mode, wo --XX-50 als Füllung nur 1,06 bis 1,14:1 trägt und
|
|
345
|
+
zugleich Sektions-Tint ist. OHNE diese vier Zeilen liefen Pill und Badge im Dark auf --XX-200,
|
|
346
|
+
also helle Füllung mit hellem Text. Wer --XX-50 im Dark anfasst, zieht diese Werte mit. */
|
|
347
|
+
/* Pill- und Badge-Fuellung im Dark: gehoben gegenueber dem ruhigen -50-Tint. Im Light traegt die
|
|
348
|
+
dunkle Schrift auf zartem Grund die Praesenz; im Dark ist es umgekehrt, helle Schrift auf
|
|
349
|
+
dunklem Tint, und bei fast gleicher Helligkeit wie die Karte haelt nichts mehr die Flaeche.
|
|
350
|
+
Deshalb hier 1,54 bis 1,55:1 zur Karte und 12,5 bis 12,7 L* Helligkeitsabstand, in Lab
|
|
351
|
+
gerechnet mit unveraendertem Farbton. Text darauf 4,97 bis 6,64:1. */
|
|
352
|
+
--co-fill:#1F5651; --ki-fill:#43531C; --es-fill:#34469D; --wo-fill:#205828;
|
|
353
|
+
/* Bereichs-Akzenttext im Dark: die hellen Pendants, gemessen auf der Seite 10,31 bis 13,79:1,
|
|
354
|
+
auf einer Karte 7,66 bis 10,25:1. Die Light-Werte (-700/-800) wären hier dunkel-auf-dunkel. */
|
|
355
|
+
--co-ink:var(--co-200); --ki-ink:var(--ki-200); --es-ink:var(--es-100); --wo-ink:var(--wo-200);
|
|
356
|
+
/* Badge text – lighter for dark backgrounds */
|
|
357
|
+
/* Dark-only: badge-err-text #F08080 ❌ 3,78:1 auf der aufgehellten Fehler-Füllung #802020
|
|
358
|
+
→ #FFA5A5 ✓ 5,21:1. Damit derselbe Ton wie --c-error, eine Fehlerfarbe weniger im System.
|
|
359
|
+
(Light: #9b2020 auf hellem Tint.) */
|
|
360
|
+
--badge-ok-text:#5CE8A0; --badge-warn-text:#F0C060; --badge-err-text:#FFA5A5;
|
|
361
|
+
/* Neutraler Badge, gleiche Stufe wie die Bereichs-Badges, damit das Bild konsistent bleibt und
|
|
362
|
+
kein Sonder-Rahmen nötig ist. Dark-only: lag als var(--n-50) bei 1,10:1 gegen die Seite ❌
|
|
363
|
+
(n-50 ist die tiefste Flächenstufe und damit dunkler als der Grund, der Badge verschwand)
|
|
364
|
+
→ eigener Wert #364553 ✓ 1,78:1 zur Seite, 1,32:1 zur Card, Text darauf 6,64:1.
|
|
365
|
+
(Light: var(--n-100).) */
|
|
366
|
+
--badge-neu-bg:#404F5D; --badge-neu-text:#C4D8D8;
|
|
367
|
+
/* Contrast badge (dark): auf derselben Stufe wie die Bereichs- und Status-Füllungen (9,8:1),
|
|
368
|
+
sonst stünden die Badges in den Kontrast-Tabellen flächengleich auf ihrem Grund.
|
|
369
|
+
Je 1,78 bis 1,79:1 zur Seite, 1,32 bis 1,33:1 zur Card, Text darauf 5,2 bis 6,3:1. */
|
|
370
|
+
--cbadge-aa-bg:#134D31; --cbadge-aa-text:#5CE8A0;
|
|
371
|
+
--cbadge-aaa-bg:#194864; --cbadge-aaa-text:#70C8F0;
|
|
372
|
+
--cbadge-fail-bg:#802020; --cbadge-fail-text:#FFA5A5; /* Dark-only: #F08080 ❌ 3,78:1 → 5,21:1 ✓ */
|
|
373
|
+
}
|
|
374
|
+
/* Dark: Brand Wheel. Die Ringe lagen unter der alten Seite (1,69:1 und 1,46:1). Gegen die tiefere
|
|
375
|
+
Seite fielen sie auf 1,06:1 und 1,10:1 und wären als Ringe verschwunden, deshalb wie die
|
|
376
|
+
Bereichs-Tints über die Seite gehoben: 1,16:1 und 1,40:1 zur Seite, 1,21:1 zueinander (vorher
|
|
377
|
+
1,16:1). Die Divider-Striche laufen über var(--bg-page) und trennen die Ringe weiterhin. */
|
|
378
|
+
[data-theme="dark"] .bw-outer { fill: #0B2B2B }
|
|
379
|
+
[data-theme="dark"] .bw-middle { fill: #0E3A3A }
|
|
380
|
+
[data-theme="dark"] .bw-divider { stroke: var(--bg-page) }
|
|
381
|
+
[data-theme="dark"] .bw-ring-outline { stroke: var(--bg-page) }
|
|
382
|
+
[data-theme="dark"] .bw-label-segment { fill: var(--co-200) }
|
|
383
|
+
[data-theme="dark"] .bw-label-attr { fill: var(--co-300) }
|
|
384
|
+
[data-theme="dark"] .bw-pillar-card { background: var(--bg-surface) }
|
|
385
|
+
/* co-700 (#007575) on bg-surface (#28323D) = 2.36:1 → co-300 (#4DD0D0) = 6.97:1 ✓ AAA */
|
|
386
|
+
[data-theme="dark"] .bw-pillar-title { color: var(--co-300) }
|
|
387
|
+
/* Dark-only: tx-secondary (#A6C6C6) on bg-surface (#28323D) = 7.13:1 → tx-primary = 10.48:1, hier
|
|
388
|
+
bewusst die kräftigere Stufe, weil die Attribute im Rad als Primärinformation gelesen werden.
|
|
389
|
+
(Light: #4A6565 auf #fff = 6.28:1 ✓, kein Fix nötig.) */
|
|
390
|
+
[data-theme="dark"] .bw-pillar-attrs { color: var(--tx-primary) }
|
|
391
|
+
/* co-700 (#007575) on bg-page (#151A1F) = 3.17:1 ❌ für Normaltext → co-200 (#80DEDE) = 11.19:1 ✓ AAA */
|
|
392
|
+
[data-theme="dark"] .doc-eyebrow { color: var(--co-200) }
|
|
393
|
+
|
|
394
|
+
/* Dark: targeted component fixes that can't be token-driven */
|
|
395
|
+
/* Select arrow: n-500 (#4A6565) auf bg-surface (#28323D) = 2.07:1 ❌ → n-200 (#C9D3D3) = 8.51:1 ✓ */
|
|
396
|
+
[data-theme="dark"] .field select { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23C9D3D3' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19.5 8.25l-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E") }
|
|
397
|
+
/* Textarea-Resizer: der native Eck-Griff (dunkle Diagonalen) ist im Dark auf dem Feld-bg unsichtbar.
|
|
398
|
+
Eigenen hellen Griff (#C9D3D3, 5,84:1) als background-image aufs Textarea legen — zuverlässiger
|
|
399
|
+
positioniert als im winzigen ::-webkit-resizer-Pseudoelement — und den nativen Resizer transparent
|
|
400
|
+
schalten (Drag-Funktion bleibt). Firefox zeigt für resize:vertical keinen Eck-Griff. */
|
|
401
|
+
[data-theme="dark"] .field textarea {
|
|
402
|
+
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cpath d='M11 4L4 11M11 8L8 11' stroke='%23C9D3D3' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
|
|
403
|
+
background-repeat:no-repeat;
|
|
404
|
+
background-position:right 6px bottom 6px;
|
|
405
|
+
}
|
|
406
|
+
[data-theme="dark"] .field textarea::-webkit-resizer { background:transparent }
|
|
407
|
+
/* Slider: --sl-color = Thumb, --sl-text = Wert-Anzeige. Die -500/-700/-800-Töne fallen im Dark auf dem
|
|
408
|
+
dunklen Grund durch (Wert-Text ki/es/wo < 4,5:1, Thumb < 3:1). Beide auf die hellen -200/-100-Töne
|
|
409
|
+
heben (5,3-7:1). Track (--n-200 #C9D3D3) bleibt hell/sichtbar; disabled (.38 opacity) ist 1.4.3-ausgenommen. */
|
|
410
|
+
/* Dark-only: Der Slider OHNE Bereichsklasse fiel durchs Raster. Er nimmt den Fallback der
|
|
411
|
+
Komponente (--sl-text: co-700) und stand damit ❌ 2,36:1 auf der Karte, dunkel auf dunkel.
|
|
412
|
+
Die vier Bereichsklassen darunter waren gesetzt, der Grundfall nicht. → co-200 ✓ 8,32:1.
|
|
413
|
+
(Light: co-700 auf Weiß, 5,52:1.) */
|
|
414
|
+
[data-theme="dark"] .field-slider-output { color: var(--sl-text, var(--co-200)) }
|
|
415
|
+
[data-theme="dark"] .slider-co { --sl-color: var(--co-200); --sl-text: var(--co-200) }
|
|
416
|
+
[data-theme="dark"] .slider-ki { --sl-color: var(--ki-200); --sl-text: var(--ki-200) }
|
|
417
|
+
[data-theme="dark"] .slider-es { --sl-color: var(--es-100); --sl-text: var(--es-100) }
|
|
418
|
+
[data-theme="dark"] .slider-wo { --sl-color: var(--wo-200); --sl-text: var(--wo-200) }
|
|
419
|
+
/* Tick-Labels (min/mid/max): tx-muted reißt im Dark AA (~3:1) → tx-secondary (4,9:1) */
|
|
420
|
+
[data-theme="dark"] .field-slider-ticks { color: var(--tx-secondary) }
|
|
421
|
+
/* Such-Feld-Magnifier: stroke=var(--n-400) #6E8585 flippt nicht und liegt im Dark bei nur 2,28:1.
|
|
422
|
+
Das Icon trägt den „Such“-Kontext (nicht rein dekorativ) → auf tx-secondary heben (4,9:1).
|
|
423
|
+
CSS-stroke schlägt das Präsentationsattribut am <svg>. */
|
|
424
|
+
[data-theme="dark"] [role="search"] svg { stroke: var(--tx-secondary) }
|
|
425
|
+
/* Dropdowns (.ep-select/.ep-combobox): Caret n-500 (#4A6565) auf Feld-bg ≈ 1,1:1 → n-200 (#C9D3D3),
|
|
426
|
+
analog zur nativen Select-Pfeil-Korrektur oben. */
|
|
427
|
+
[data-theme="dark"] .ep-select-caret { color: var(--n-200); stroke: var(--n-200) }
|
|
428
|
+
/* Akzent des gewählten Eintrags: --sel-500 nutzt die -700/-800-Bereichstöne → dunkel-auf-dunkel auf der
|
|
429
|
+
bg-surface-Popup-Fläche bzw. der dunklen -50-Tönung. Auf die hellen -200/-100-Töne heben (wie t-Utilities,
|
|
430
|
+
Badges, Pills); die --sel-50-Tönung bleibt theme-aware (dunkle -50-Kachel), heller Text trägt den Kontrast. */
|
|
431
|
+
[data-theme="dark"] .ep-select, [data-theme="dark"] .ep-combobox { --sel-500: var(--co-200) }
|
|
432
|
+
[data-theme="dark"] .ep-select[data-area="ki"], [data-theme="dark"] .ep-combobox[data-area="ki"] { --sel-500: var(--ki-200) }
|
|
433
|
+
[data-theme="dark"] .ep-select[data-area="es"], [data-theme="dark"] .ep-combobox[data-area="es"] { --sel-500: var(--es-100) }
|
|
434
|
+
[data-theme="dark"] .ep-select[data-area="wo"], [data-theme="dark"] .ep-combobox[data-area="wo"] { --sel-500: var(--wo-200) }
|
|
435
|
+
/* Dark-only: Ruhe-Rand des neutralen Chips. Stand als hartkodiertes #818C99 da, dem alten --bd-Wert,
|
|
436
|
+
den die Flächen-Umstellung auf #6F7A89 gedämpft hat. Jetzt --bd-strong-c aus der Rahmen-Familie:
|
|
437
|
+
4,21:1 gegen die Chip-Fläche und 5,66:1 gegen die Seite. --bd-c wäre hier zu schwach (2,99:1 zur
|
|
438
|
+
Chip-Fläche), der Chip-Rand ist eine Bedienelement-Grenze und braucht 3:1 nach WCAG 1.4.11.
|
|
439
|
+
(Light: n-200, 1.5px, aus components.css.) */
|
|
440
|
+
[data-theme="dark"] .chip { border-color: var(--bd-strong-c) }
|
|
441
|
+
/* Dark-only: Hover-Rand des neutralen Chips. Light geht auf n-400 (#6E8585), im Dark liegt das mit
|
|
442
|
+
3,32:1 unter dem Ruhe-Rand: der Rand würde beim Überfahren schwächer statt kräftiger.
|
|
443
|
+
→ n-200 = #C9D3D3, 8,51:1. (Light: n-400 bleibt.) */
|
|
444
|
+
[data-theme="dark"] .chip:hover { border-color: var(--n-200) }
|
|
445
|
+
/* Dark-only: Ruhezustand der BEREICHS-Chips. Sie setzen Rahmen und Text in components.css auf die
|
|
446
|
+
dunklen Stufen (-500/-600/-700 Rahmen, -700/-800 Text), die im Dark nicht flippen: der Text stand
|
|
447
|
+
damit ❌ 1,35:1 (es-700) bis 2,36:1 (co-700) auf einer Karte, also dunkel-auf-dunkel, und der
|
|
448
|
+
es-Rahmen mit 2,30:1 unter der 3:1-Schwelle für die Bedienelement-Grenze. Jetzt wie überall im
|
|
449
|
+
Dark die hellen Pendants: Text -200 (es -100), 7,66 bis 10,25:1 ✓; Rahmen -300, 4,25 bis 9,48:1 ✓,
|
|
450
|
+
eine Stufe unter dem Text, damit die Schrift dominant bleibt wie im Light.
|
|
451
|
+
Der Hover geht auf -200/-100 (auf der getönten Füllung 5,78 bis 7,77:1), also kräftiger als die
|
|
452
|
+
Ruhe, gleiche Richtung wie beim neutralen Chip. Die Hover-Füllung --XX-50 flippt schon selbst.
|
|
453
|
+
(Light: -500/-600/-700-Rahmen mit -700/-800-Text, unverändert.) */
|
|
454
|
+
[data-theme="dark"] .chip[data-area="co"] { border-color: var(--co-300); color: var(--co-200) }
|
|
455
|
+
[data-theme="dark"] .chip[data-area="ki"] { border-color: var(--ki-300); color: var(--ki-200) }
|
|
456
|
+
[data-theme="dark"] .chip[data-area="es"] { border-color: var(--es-300); color: var(--es-100) }
|
|
457
|
+
[data-theme="dark"] .chip[data-area="wo"] { border-color: var(--wo-300); color: var(--wo-200) }
|
|
458
|
+
[data-theme="dark"] .chip[data-area="co"]:hover { border-color: var(--co-200) }
|
|
459
|
+
[data-theme="dark"] .chip[data-area="ki"]:hover { border-color: var(--ki-200) }
|
|
460
|
+
[data-theme="dark"] .chip[data-area="es"]:hover { border-color: var(--es-100) }
|
|
461
|
+
[data-theme="dark"] .chip[data-area="wo"]:hover { border-color: var(--wo-200) }
|
|
462
|
+
/* Dark-only: Gedrückter Chip invertiert, wie das Segmented Control (dort --seg-fill -300 mit
|
|
463
|
+
--seg-on -900). Light füllt mit n-700 und schreibt weiß; im Dark ergäbe das eine sehr dunkle
|
|
464
|
+
Fläche auf dunklem Grund — ❌ 1,60:1 zwischen Chip und Seite, der ausgewählte Zustand war nur
|
|
465
|
+
noch am Text erkennbar. Helle Füllung n-300 mit dunklem Text n-900 ✓. Der Hover geht eine Stufe
|
|
466
|
+
heller (n-200) statt dunkler, damit die Richtung stimmt. (Light: n-700/n-800 bleiben.) */
|
|
467
|
+
[data-theme="dark"] .chip[aria-pressed="true"] { background: var(--n-300); border-color: var(--n-300); color: var(--n-900) }
|
|
468
|
+
[data-theme="dark"] .chip[aria-pressed="true"]:hover { background: var(--n-200); border-color: var(--n-200) }
|
|
469
|
+
/* Die Bereichs-Chips setzen ihren gewählten Zustand mit eigener Regel (--XX-700/800 + weißer Text) und
|
|
470
|
+
brauchen deshalb eigene Dark-Regeln — sonst greift oben die neutrale Füllung, der weiße Text bleibt
|
|
471
|
+
stehen und ergibt ❌ 1,53:1. Gleiche Inversion wie beim Segmented Control, jeweils Bereichston -300
|
|
472
|
+
mit -900-Text; Hover eine Stufe heller. (Light: -700/-800 mit Weiß bleiben.) */
|
|
473
|
+
[data-theme="dark"] .chip[data-area="co"][aria-pressed="true"] { background: var(--co-300); border-color: var(--co-300); color: var(--co-900) }
|
|
474
|
+
[data-theme="dark"] .chip[data-area="ki"][aria-pressed="true"] { background: var(--ki-300); border-color: var(--ki-300); color: var(--ki-900) }
|
|
475
|
+
[data-theme="dark"] .chip[data-area="es"][aria-pressed="true"] { background: var(--es-300); border-color: var(--es-300); color: var(--es-900) }
|
|
476
|
+
[data-theme="dark"] .chip[data-area="wo"][aria-pressed="true"] { background: var(--wo-300); border-color: var(--wo-300); color: var(--wo-900) }
|
|
477
|
+
[data-theme="dark"] .chip[data-area="co"][aria-pressed="true"]:hover { background: var(--co-200); border-color: var(--co-200) }
|
|
478
|
+
[data-theme="dark"] .chip[data-area="ki"][aria-pressed="true"]:hover { background: var(--ki-200); border-color: var(--ki-200) }
|
|
479
|
+
[data-theme="dark"] .chip[data-area="es"][aria-pressed="true"]:hover { background: var(--es-200); border-color: var(--es-200) }
|
|
480
|
+
[data-theme="dark"] .chip[data-area="wo"][aria-pressed="true"]:hover { background: var(--wo-200); border-color: var(--wo-200) }
|
|
481
|
+
/* Dark-only: Pause-Knopf im Logo-Karussell. Light dunkelt das Icon beim Hover auf n-700 (#1A2E2E),
|
|
482
|
+
im Dark sind das 1,60:1 auf der Karten-Fläche. → n-100 hebt es auf das hellste Neutral.
|
|
483
|
+
(Light: n-700 bleibt.) */
|
|
484
|
+
[data-theme="dark"] .logo-carousel-pause:hover { color: var(--n-200) }
|
|
485
|
+
[data-theme="dark"] .ai-warning { color:var(--ki-300) }
|
|
486
|
+
[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.
|
|
499
|
+
(Light: helle Tints #E6F9F1 / #FDEAEA mit dunklem Glyph, kein Fix nötig.) */
|
|
500
|
+
[data-theme="dark"] .a11y-ok .a11y-rule-icon { background:var(--c-success-bg); color:var(--c-success) }
|
|
501
|
+
[data-theme="dark"] .a11y-fail .a11y-rule-icon { background:var(--c-error-bg); color:var(--c-error) }
|
|
502
|
+
/* Dark: buttons – Text/Rahmen auf die Bereichs-Light-Tints (--c-ink = -200/-100, wie t-Utilities,
|
|
503
|
+
Badges, Icons; auf der Skala) heben; Filled invertiert auf helle -300-Fläche + dunklen Text (s. u.). */
|
|
504
|
+
/* Filled: die dunkle -700/-800-Fläche verschwimmt im Dark mit bg-page (1,1–2,0:1, Button "verschwindet").
|
|
505
|
+
Daher invertieren: helle -300-Bereichsfläche + dunkler Text (n-900) → poppt als Primär-Aktion
|
|
506
|
+
(Fläche 3,6–8:1, Text 6–14:1). Nur .btn-filled umstellen (nicht --c500, das Tonal/Outlined/Text trägt);
|
|
507
|
+
.btn-on-band (weiße Fläche auf Bereichsband) ausnehmen. Light bleibt dunkle Fläche + weißer Text. */
|
|
508
|
+
[data-theme="dark"] .btn-filled:not(.btn-on-band) { color: var(--n-900) }
|
|
509
|
+
[data-theme="dark"] .btn-co.btn-filled:not(.btn-on-band) { background: var(--co-300) }
|
|
510
|
+
[data-theme="dark"] .btn-ki.btn-filled:not(.btn-on-band) { background: var(--ki-300) }
|
|
511
|
+
[data-theme="dark"] .btn-es.btn-filled:not(.btn-on-band) { background: var(--es-300) }
|
|
512
|
+
[data-theme="dark"] .btn-wo.btn-filled:not(.btn-on-band) { background: var(--wo-300) }
|
|
513
|
+
/* --c-ink = Bereichs-Light-Tint für Text/Rahmen der nicht-gefüllten Buttons im Dark. Dieselben Töne
|
|
514
|
+
wie t-Utilities, Badges, Icons, Eyebrows (auf der offiziellen Skala) statt eines off-scale color-mix → alle
|
|
515
|
+
Bereichstöne der Seite ziehen aus EINER Skala. */
|
|
516
|
+
[data-theme="dark"] .btn-co { --c-ink: var(--co-200) }
|
|
517
|
+
[data-theme="dark"] .btn-ki { --c-ink: var(--ki-200) }
|
|
518
|
+
[data-theme="dark"] .btn-es { --c-ink: var(--es-100) }
|
|
519
|
+
[data-theme="dark"] .btn-wo { --c-ink: var(--wo-200) }
|
|
520
|
+
/* Tonal im Dark: dezent brand-getönte Fläche (c500 18% in bg-page) + neutraler Rahmen über
|
|
521
|
+
--bd-strong-c (vorher als #9DA8B6 hartkodiert, dem alten --bd-strong-Wert; die Gleichung stimmte
|
|
522
|
+
nach der Flächen-Umstellung nicht mehr). Auf den vier Tonal-Füllungen 3,64:1 (ki) bis 4,87:1 (es),
|
|
523
|
+
also durchgehend über der 3:1-Schwelle. Der Rahmen macht den Button erkennbar, die Tönung
|
|
524
|
+
unterscheidet ihn von Outlined (brand-Rahmen). Basis bg-page (nicht bg-surface): so trägt der
|
|
525
|
+
-ink-Text (-200/-100) auch auf der Tonal-Fläche AA (≥5:1; auf bg-surface lagen co/wo bei
|
|
526
|
+
4,43:1, knapp drunter). */
|
|
527
|
+
[data-theme="dark"] .btn-tonal {
|
|
528
|
+
background: color-mix(in srgb, var(--c500) 18%, var(--bg-page));
|
|
529
|
+
color: var(--c-ink);
|
|
530
|
+
border-color: var(--bd-strong-c);
|
|
531
|
+
}
|
|
532
|
+
[data-theme="dark"] .btn-elevated { color: var(--c-ink) }
|
|
533
|
+
[data-theme="dark"] .btn-outlined {
|
|
534
|
+
color: var(--c-ink);
|
|
535
|
+
border-color: var(--c-ink);
|
|
536
|
+
}
|
|
537
|
+
[data-theme="dark"] .btn-outlined:hover { background: color-mix(in srgb, var(--c50) 15%, var(--bg-surface)) }
|
|
538
|
+
[data-theme="dark"] .btn-text { color: var(--c-ink) }
|
|
539
|
+
[data-theme="dark"] .btn-text:hover { background: color-mix(in srgb, var(--c50) 15%, var(--bg-surface)) }
|
|
540
|
+
|
|
541
|
+
/* ════════════════════════════════════════════
|
|
542
|
+
DARK MODE: Beispielseiten
|
|
543
|
+
════════════════════════════════════════════ */
|
|
544
|
+
/* Shared structural overrides */
|
|
545
|
+
/* .ds-card hat nur Rahmen, keinen Hintergrund (transparent → zeigt die Sektion durch). Im Dark zeigt
|
|
546
|
+
eine hintergrundlose Karte auf einer getönten Sektion denselben dunklen Ton → keine eigene Fläche.
|
|
547
|
+
Im Dark daher bg-surface geben: die Karte wird eine erkennbare, erhöhte Fläche. Karten MIT Inline-bg
|
|
548
|
+
(Info-Callouts auf co-50/n-50) behalten ihren Ton — Inline-Style schlägt diese Regel. */
|
|
549
|
+
[data-theme="dark"] .ds-card { background: var(--bg-surface) }
|
|
550
|
+
[data-theme="dark"] .ep-logo { color: var(--tx-primary) !important }
|
|
551
|
+
[data-theme="dark"] .ep-nav-links { color: var(--tx-secondary) !important }
|
|
552
|
+
/* Topnav Hover/Aktiv: co-700 (Light) → co-200 im Dark (co-700 wäre dunkel-auf-dunkel).
|
|
553
|
+
co-200 (#80DEDE) auf bg-surface bzw. co-50-dark ≥ 4.9:1 ✓ AA; Tönungsfläche bleibt co-50. */
|
|
554
|
+
[data-theme="dark"] .ep-nav-btn:hover,
|
|
555
|
+
[data-theme="dark"] .ep-nav-btn[aria-current="page"],
|
|
556
|
+
[data-theme="dark"] .ep-nav-has-sub:hover .ep-nav-item-toggle,
|
|
557
|
+
[data-theme="dark"] .ep-nav-has-sub.is-open .ep-nav-item-toggle,
|
|
558
|
+
[data-theme="dark"] .ep-nav-sub-btn:hover,
|
|
559
|
+
[data-theme="dark"] .ep-nav-sub-btn[aria-current="page"] { color: var(--co-200) }
|
|
560
|
+
/* Aktiv-Unterstrich im Dark ebenfalls co-200 (Light: co-700) — spiegelt die Aktiv-Textfarbe, 5,71:1 auf bg-surface. */
|
|
561
|
+
[data-theme="dark"] .ep-nav-btn::after { background: var(--co-200) }
|
|
562
|
+
/* Topnav-Aktionen (Suche/Theme): co-700-Hover wäre dunkel-auf-dunkel → co-200, wie die Nav-Links. */
|
|
563
|
+
[data-theme="dark"] .ep-nav-icon-btn:hover,
|
|
564
|
+
[data-theme="dark"] .ep-nav-search.is-open .ep-nav-search-toggle { color: var(--co-200) }
|
|
565
|
+
[data-theme="dark"] .ep-section { background: var(--bg-page) !important }
|
|
566
|
+
/* Section-Rhythmus erhalten: im Light staffeln sich Sektionen über bg-surface (Basis) und n-50
|
|
567
|
+
(Alternativ-Ton) — die „Abstufungen“. Pauschal alles auf bg-page macht den Dark flach. n-50-Sektionen
|
|
568
|
+
daher auf bg-surface heben (hellerer Dark-Surface-Tier, 1,22:1) → sichtbare Alternation Basis/erhöht. */
|
|
569
|
+
[data-theme="dark"] .ep-section[style*="var(--n-50)"] { background: var(--bg-surface) !important }
|
|
570
|
+
/* Die Hebung gilt AUSNAHMSLOS, auch für kartentragende Sektionen. Damit ist die Tonfolge im Dark
|
|
571
|
+
dieselbe wie im Light, und der Wechsel Basis/erhöht bleibt über die ganze Seite intakt.
|
|
572
|
+
|
|
573
|
+
Warum keine Ausnahme: Eine gehobene Sektion trifft den Ton ihrer eigenen bg-surface-Karten. Die
|
|
574
|
+
naheliegende Antwort war, solche Sektionen auf bg-page zurückzuziehen, damit die Karten die
|
|
575
|
+
hellere Stufe bilden. Das kostet aber genau den Rhythmus, um den es hier geht: die Sektion sitzt
|
|
576
|
+
dann auf dem Ton ihrer Nachbarn. Gemessen über die 24 Beispielseiten (133 Abschnitte): mit
|
|
577
|
+
Rücknahme 63 verschmolzene Übergänge, ohne 20, im Light sind es 17.
|
|
578
|
+
|
|
579
|
+
Die Karten lesen deshalb über ihren RAND, nicht über eine Tonstufe. Das ist keine Notlösung,
|
|
580
|
+
sondern exakt das, was im Light auf weißen Sektionen längst passiert: weiße Karte auf weißem
|
|
581
|
+
Grund, abgegrenzt durch die Kante. Die trägt im Light --bd-strong (2,25:1 gegen Weiß, 2,09:1
|
|
582
|
+
gegen eine n-50-Sektion), im Dark ist derselbe Rand mit 4,21:1 gegen die Kartenfläche noch
|
|
583
|
+
deutlicher, siehe die Rand-Regeln bei den Karten unten.
|
|
584
|
+
Auf bg-page-Sektionen bleibt es bei Tonstufe PLUS Rand. */
|
|
585
|
+
/* Getönte CTA-Sektionen: behalten im Dark ihren Bereichs-Tint (var(--XX-50) = gedämpfter Dunkston wie
|
|
586
|
+
#16302E), statt vom pauschalen bg-page geschluckt zu werden → CTA-Band bleibt als getönte Fläche
|
|
587
|
+
erkennbar. Texte/Labels darauf flippen auf helle Tints (8–10:1). */
|
|
588
|
+
/* Getönte Sektionen ziehen --XX-band statt --XX-50: das Band muss dunkler bleiben als die Karten
|
|
589
|
+
darauf, die kleine --XX-50-Füllung dagegen heller als ihr Grund. Siehe Token-Block oben. */
|
|
590
|
+
[data-theme="dark"] .ep-section[style*="var(--co-50)"] { background: var(--co-band) !important }
|
|
591
|
+
[data-theme="dark"] .ep-section[style*="var(--ki-50)"] { background: var(--ki-band) !important }
|
|
592
|
+
[data-theme="dark"] .ep-section[style*="var(--es-50)"] { background: var(--es-band) !important }
|
|
593
|
+
[data-theme="dark"] .ep-section[style*="var(--wo-50)"] { background: var(--wo-band) !important }
|
|
594
|
+
/* Header-Trennlinien: die getönten Beispielseiten-Header nutzen inline border-bottom mit dem hellen
|
|
595
|
+
Bereichston var(--XX-100). Der flippt nicht → im Dark eine grelle helle Linie (~7–11:1). Auf den
|
|
596
|
+
neutralen var(--bd) umstellen (~3–4:1), damit die Trennlinie dezent bleibt wie der gleichfarbige
|
|
597
|
+
Whisper im Light. Nur Sektionen mit border-bottom getroffen, nicht die randlosen getönten Bänder. */
|
|
598
|
+
[data-theme="dark"] .ep-section[style*="border-bottom:1px solid var(--co-100)"],
|
|
599
|
+
[data-theme="dark"] .ep-section[style*="border-bottom:1px solid var(--ki-100)"],
|
|
600
|
+
[data-theme="dark"] .ep-section[style*="border-bottom:1px solid var(--es-100)"],
|
|
601
|
+
[data-theme="dark"] .ep-section[style*="border-bottom:1px solid var(--wo-100)"] { border-bottom: var(--bd) !important }
|
|
602
|
+
[data-theme="dark"] .ep-section-h2 { color: var(--tx-primary) !important }
|
|
603
|
+
[data-theme="dark"] .ep-section-sub { color: var(--tx-secondary) !important }
|
|
604
|
+
/* Elevation = Interaktivität (siehe components.css): statische .ep-card ruhen flach — Containment über
|
|
605
|
+
die hellere bg-surface-Fläche + --bd-strong-Rahmen. Schatten nur für interaktive .ep-card-link. */
|
|
606
|
+
[data-theme="dark"] .ep-card { background: var(--bg-surface) !important }
|
|
607
|
+
[data-theme="dark"] .ep-card-link { box-shadow: var(--e2) }
|
|
608
|
+
/* Dark-only: Der Rand trägt die Kartenkante, weil die Karte auf einer gehobenen Sektion denselben
|
|
609
|
+
Ton hat wie ihr Grund (n-50-Sektionen werden im Dark auf bg-surface gehoben, siehe oben). Genau
|
|
610
|
+
wie im Light auf weißen Sektionen, dort übernimmt dieselbe --bd-strong-Kante (2,25:1).
|
|
611
|
+
Im Dark gibt --bd-strong-c 4,21:1 gegen die Kartenfläche, also noch klarer. .ep-card-link setzt in
|
|
612
|
+
components.css border-color:transparent, weil dort der Schatten allein trug; auf der tiefen
|
|
613
|
+
Dark-Basis trägt er das nicht mehr, gleiche Begründung wie bei den schwebenden Panels.
|
|
614
|
+
(Light: --bd-strong für .ep-card, transparenter Rand für die Link-Variante.) */
|
|
615
|
+
[data-theme="dark"] .ep-card,
|
|
616
|
+
[data-theme="dark"] .ep-card-link { border-color: var(--bd-strong-c) }
|
|
617
|
+
/* Dark-only: Auf der tieferen Seite tragen die schwarzen Schatten weniger als auf dem alten
|
|
618
|
+
#333E48. Der Hover hebt deshalb zusätzlich die Fläche (13,01:1 → 11,47:1), wie im
|
|
619
|
+
Material-Overlay-Modell, wo Tiefe primär über Helligkeit entsteht. Das ist ein Zustand,
|
|
620
|
+
KEINE dritte statische Flächen-Stufe. Das !important schlägt die .ep-card-Grundregel oben.
|
|
621
|
+
(Light: bg-surface-hover = bg-surface, dort trägt --e3 die Tiefe allein.) */
|
|
622
|
+
[data-theme="dark"] .ep-card-link:hover,
|
|
623
|
+
[data-theme="dark"] .ep-card-link:focus-visible { background: var(--bg-surface-hover) !important }
|
|
624
|
+
[data-theme="dark"] .ep-card-title { color: var(--tx-primary) !important }
|
|
625
|
+
[data-theme="dark"] .ep-card-text { color: var(--tx-secondary) !important }
|
|
626
|
+
/* ep-card-icon: Im Dark-Mode werden die --XX-50-Kacheln fast schwarz, die Glyph-Farben (--XX-700/800)
|
|
627
|
+
bleiben aber dunkel → dunkel-auf-dunkel (KI 2.2:1, ES 2.1:1, WO 2.5:1, Corp 3.4:1; der alte
|
|
628
|
+
filter:brightness(.75) verschlimmerte das auf bis zu 1.7:1). Glyph daher bereichsweise auf den
|
|
629
|
+
hellen --XX-100-Ton heben (nach der Flächen-Umstellung 7,49 bis 9,99:1, Schwelle für Icons ist 3:1).
|
|
630
|
+
CSS auf <svg> schlägt das Inline-stroke-Präsentationsattribut. */
|
|
631
|
+
[data-theme="dark"] .ep-card-icon[data-area="co"] svg { stroke: var(--co-100) }
|
|
632
|
+
/* Timeline-Marker: co-50-Tile wird im Dark dunkel → Icon auf helles co-100 heben */
|
|
633
|
+
[data-theme="dark"] .ep-tl-icon svg { stroke: var(--co-100) }
|
|
634
|
+
/* Der box-shadow-Ring stellt den Kreis von der Timeline-Linie frei und muss die Hintergrundfarbe
|
|
635
|
+
treffen. In Light = bg-surface (= weiß = Grund) → unsichtbar. Im Dark liegt die Timeline (Doku wie
|
|
636
|
+
ep-Section) auf bg-page; bg-surface waere dort ein hellerer Halo. Ring daher auf bg-page. */
|
|
637
|
+
[data-theme="dark"] .ep-tl-icon { box-shadow: 0 0 0 4px var(--bg-page) }
|
|
638
|
+
[data-theme="dark"] .ep-card-icon[data-area="ki"] svg { stroke: var(--ki-100) }
|
|
639
|
+
[data-theme="dark"] .ep-card-icon[data-area="es"] svg { stroke: var(--es-100) }
|
|
640
|
+
[data-theme="dark"] .ep-card-icon[data-area="wo"] svg { stroke: var(--wo-100) }
|
|
641
|
+
/* Gefüllte Brand-Glyphen (.ep-card-icon mit .t-*-Klasse, fill=currentColor) holen ihre Farbe schon
|
|
642
|
+
über t-* (flippt im Dark auf helle -200/-100). Der stroke-Override oben ist für OUTLINE-Icons; auf
|
|
643
|
+
gefüllten Pfaden erzwingt er eine zusätzliche 1,5px-Kontur → verzerrt den Glyph. Daher hier stroke:none. */
|
|
644
|
+
[data-theme="dark"] .ep-card-icon.t-co svg,
|
|
645
|
+
[data-theme="dark"] .ep-card-icon.t-ki svg,
|
|
646
|
+
[data-theme="dark"] .ep-card-icon.t-es svg,
|
|
647
|
+
[data-theme="dark"] .ep-card-icon.t-wo svg { stroke: none }
|
|
648
|
+
/* Offene Feature-Liste: --ki-800 bleibt im Dark-Mode dunkel-oliv, --ki-50 ist ein dunkler Olivton.
|
|
649
|
+
Pro-Glyph + Tier-Label daher auf das helle --ki-100 umstellen (>11:1 auf der Tile).
|
|
650
|
+
Core (tx-secondary/n-100) ist theme-aware und braucht keinen Override. */
|
|
651
|
+
[data-theme="dark"] .ep-feature-icon[data-area="ki"] { color: var(--ki-100) }
|
|
652
|
+
[data-theme="dark"] .ep-feature-icon[data-area="co"] { color: var(--co-100) }
|
|
653
|
+
[data-theme="dark"] .ep-feature-icon[data-area="es"] { color: var(--es-100) }
|
|
654
|
+
[data-theme="dark"] .ep-feature-icon[data-area="wo"] { color: var(--wo-100) }
|
|
655
|
+
/* Dark-only: .ep-compare nutzt rohes --ki-800 (flippt nicht) für Summary, ✓-Glyph und Pro-Header
|
|
656
|
+
→ dunkel-auf-dunkel: ❌ ki-800 #475705 auf bg-page/ki-50 #2A3411. Auf helle ki-Töne heben ✓,
|
|
657
|
+
analog .ep-feature-icon/.ep-tier-label. (Light: ki-800/ki-900 bleiben.) */
|
|
658
|
+
[data-theme="dark"] .ep-compare-summary { color: var(--ki-200) }
|
|
659
|
+
[data-theme="dark"] .ep-compare-summary:hover { color: var(--ki-100) }
|
|
660
|
+
[data-theme="dark"] .ep-compare-yes { color: var(--ki-100) }
|
|
661
|
+
[data-theme="dark"] .ep-compare-table thead .ep-compare-pro { color: var(--ki-100) }
|
|
662
|
+
/* Testimonial-Zitatzeichen: --t-accent (-500) bei opacity .2 verschwindet im Dark auf der
|
|
663
|
+
bg-surface-Karte (perzeptuell schwach, es-500 zudem zu dunkel). Im Dark auf den helleren -300-Ton
|
|
664
|
+
+ opacity .6 → erkennbarer, aber weiterhin dezenter Flourish (2,1–3,4:1, gleichmäßig über alle Bereiche). */
|
|
665
|
+
[data-theme="dark"] .testimonial-icon { color: var(--co-300); opacity: .6 }
|
|
666
|
+
[data-theme="dark"] .testimonial[data-area="ki"] .testimonial-icon { color: var(--ki-300) }
|
|
667
|
+
[data-theme="dark"] .testimonial[data-area="es"] .testimonial-icon { color: var(--es-300) }
|
|
668
|
+
[data-theme="dark"] .testimonial[data-area="wo"] .testimonial-icon { color: var(--wo-300) }
|
|
669
|
+
/* Blockquote-Zitatzeichen (.bq-icon): analog — -500 @ .35 verschwindet im Dark auf dem getönten
|
|
670
|
+
-50-Grund. Auf -300 je Bereich + opacity .6 → erkennbarer Flourish (2,7–4,5:1). */
|
|
671
|
+
[data-theme="dark"] .bq-icon { color: var(--co-300); opacity: .6 }
|
|
672
|
+
[data-theme="dark"] .bq[data-area="ki"] .bq-icon { color: var(--ki-300) }
|
|
673
|
+
[data-theme="dark"] .bq[data-area="es"] .bq-icon { color: var(--es-300) }
|
|
674
|
+
[data-theme="dark"] .bq[data-area="wo"] .bq-icon { color: var(--wo-300) }
|
|
675
|
+
/* Team-Stimme-Zitatzeichen (.team-voice-icon): gleicher Fall auf der bg-surface-Karte → -300 + opacity .6. */
|
|
676
|
+
[data-theme="dark"] .team-voice-icon { color: var(--co-300); opacity: .6 }
|
|
677
|
+
[data-theme="dark"] .team-voice[data-area="ki"] .team-voice-icon { color: var(--ki-300) }
|
|
678
|
+
[data-theme="dark"] .team-voice[data-area="es"] .team-voice-icon { color: var(--es-300) }
|
|
679
|
+
[data-theme="dark"] .team-voice[data-area="wo"] .team-voice-icon { color: var(--wo-300) }
|
|
680
|
+
/* Icon-Doku-Swatches (#sec-icons): dieselbe --XX-50-Kachel ist im Dark-Mode ein dunkler Bereichston, die
|
|
681
|
+
Glyph-Farben sind teils hart kodiert (#333E48, #004F4F, #183A0E), teils currentColor aus einer
|
|
682
|
+
inline gesetzten --XX-700/800-color → dunkel-auf-dunkel (analog .ep-card-icon). Glyph auf den
|
|
683
|
+
hellen --XX-100-Ton heben. Override pro <path> über Attribut-Selektor des Ist-Werts: schlägt
|
|
684
|
+
sowohl das Präsentationsattribut als auch die Inline-color am Container (sonst gewänne diese),
|
|
685
|
+
und trifft nur farbige Formen — Outline-Pfade mit fill="none" bleiben unberührt. Selektor auf
|
|
686
|
+
beliebige SVG-Form (nicht nur path): die Micro-16px-Icons nutzen <circle>/<rect>, die ein
|
|
687
|
+
path-Selektor verfehlt hätte (Knoten/Fenster blieben dunkel). */
|
|
688
|
+
[data-theme="dark"] .icon-size-swatch[data-area="co"] svg [fill="#333E48"],
|
|
689
|
+
[data-theme="dark"] .icon-size-swatch[data-area="co"] svg [fill="#004F4F"] { fill: var(--co-100) }
|
|
690
|
+
[data-theme="dark"] .icon-size-swatch[data-area="wo"] svg [stroke="#183A0E"] { stroke: var(--wo-100) }
|
|
691
|
+
[data-theme="dark"] .icon-size-swatch[data-area="wo"] svg [fill="currentColor"] { fill: var(--wo-100) }
|
|
692
|
+
[data-theme="dark"] .icon-size-swatch[data-area="ki"] svg [fill="currentColor"] { fill: var(--ki-100) }
|
|
693
|
+
[data-theme="dark"] .icon-size-swatch[data-area="es"] svg [fill="currentColor"] { fill: var(--es-100) }
|
|
694
|
+
[data-theme="dark"] .icon-size-swatch[data-area="es"] svg [stroke="currentColor"] { stroke: var(--es-100) }
|
|
695
|
+
/* Info-Callouts (.ds-card / Hinweisboxen auf --co-50-Grund): das dekorative co-700-Icon wird im Dark
|
|
696
|
+
dunkel-auf-dunkel (~3,35:1, knapp über der Grafik-Schwelle, aber schwach). Glyph auf --co-200 heben
|
|
697
|
+
(~11,8:1), konsistent mit den übrigen area-Glyphen. CSS schlägt das inline-stroke-Präsentationsattribut. */
|
|
698
|
+
[data-theme="dark"] [style*="var(--co-50)"] svg[stroke^="var(--co-"] { stroke: var(--co-200) }
|
|
699
|
+
[data-theme="dark"] [style*="var(--ki-50)"] svg[stroke^="var(--ki-"] { stroke: var(--ki-200) }
|
|
700
|
+
[data-theme="dark"] [style*="var(--es-50)"] svg[stroke^="var(--es-"] { stroke: var(--es-100) }
|
|
701
|
+
[data-theme="dark"] [style*="var(--wo-50)"] svg[stroke^="var(--wo-"] { stroke: var(--wo-200) }
|
|
702
|
+
/* Dark-only: Bereichs-Rahmen der Team-Stimme. Lag auf den -800-Stufen ❌ 1,07:1 (wo) bis 1,63:1 (ki)
|
|
703
|
+
gegen die Kartenfläche, der Rahmen war als Bereichssignal nicht vorhanden. Jetzt -300 wie beim
|
|
704
|
+
Bereichs-Chip ✓ 4,25:1 (es) bis 9,48:1 (ki), also über der 3:1-Schwelle für grafische Objekte.
|
|
705
|
+
Das Quote-Icon daneben ist dekorativ (opacity .6), der Rahmen trägt das Signal.
|
|
706
|
+
(Light: -600/-700/-500, 3,29 bis 5,66:1 auf Weiß.) */
|
|
707
|
+
[data-theme="dark"] .team-voice[data-area="co"] { border-color: var(--co-300) }
|
|
708
|
+
[data-theme="dark"] .team-voice[data-area="ki"] { border-color: var(--ki-300) }
|
|
709
|
+
[data-theme="dark"] .team-voice[data-area="es"] { border-color: var(--es-300) }
|
|
710
|
+
[data-theme="dark"] .team-voice[data-area="wo"] { border-color: var(--wo-300) }
|
|
711
|
+
[data-theme="dark"] .ep-tier-label[data-area="ki"] { color: var(--ki-100) }
|
|
712
|
+
[data-theme="dark"] .card-stat-strip { background: var(--bg-surface) }
|
|
713
|
+
[data-theme="dark"] .card-stat-flat[data-area="co"] .card-stat-flat-value { color: var(--co-200) }
|
|
714
|
+
[data-theme="dark"] .card-stat-flat[data-area="ki"] .card-stat-flat-value { color: var(--ki-200) }
|
|
715
|
+
[data-theme="dark"] .card-stat-flat[data-area="es"] .card-stat-flat-value { color: var(--es-100) }
|
|
716
|
+
[data-theme="dark"] .card-stat-flat[data-area="wo"] .card-stat-flat-value { color: var(--wo-200) }
|
|
717
|
+
/* In-Article-Callout-Eyebrow: 700er-/800er-Ton → dunkel-auf-dunkel auf der getönten -50-Fläche
|
|
718
|
+
(1,6–2,5:1). Auf die hellen Bereichs-Tints heben (8–10:1), wie bei .t-Utilities und Badges. Body-Text ist
|
|
719
|
+
tx-primary und flippt ohnehin. */
|
|
720
|
+
[data-theme="dark"] .article-callout-eyebrow { color: var(--co-200) }
|
|
721
|
+
[data-theme="dark"] .article-callout[data-area="ki"] .article-callout-eyebrow { color: var(--ki-200) }
|
|
722
|
+
[data-theme="dark"] .article-callout[data-area="es"] .article-callout-eyebrow { color: var(--es-100) }
|
|
723
|
+
[data-theme="dark"] .article-callout[data-area="wo"] .article-callout-eyebrow { color: var(--wo-200) }
|
|
724
|
+
|
|
725
|
+
/* ── Bereichs-Komponenten Vergleich ── */
|
|
726
|
+
/* Active tabs: --atab-color inline style is dark → override with light palette shades */
|
|
727
|
+
[data-theme="dark"] .atab[data-area="co"].active { color: var(--co-200); border-bottom-color: var(--co-200) }
|
|
728
|
+
[data-theme="dark"] .atab[data-area="ki"].active { color: var(--ki-200); border-bottom-color: var(--ki-200) }
|
|
729
|
+
[data-theme="dark"] .atab[data-area="es"].active { color: var(--es-100); border-bottom-color: var(--es-100) }
|
|
730
|
+
[data-theme="dark"] .atab[data-area="wo"].active { color: var(--wo-200); border-bottom-color: var(--wo-200) }
|
|
731
|
+
/* Branded chips: override inline color/border that are hardcoded dark palette shades */
|
|
732
|
+
[data-theme="dark"] #at-co .chip[style] { color: var(--co-200) !important; border-color: var(--co-300) !important }
|
|
733
|
+
[data-theme="dark"] #at-ai .chip[style] { color: var(--ki-200) !important; border-color: var(--ki-400) !important }
|
|
734
|
+
[data-theme="dark"] #at-es .chip[style] { color: var(--es-100) !important; border-color: var(--es-300) !important }
|
|
735
|
+
[data-theme="dark"] #at-wo .chip[style] { color: var(--wo-200) !important; border-color: var(--wo-300) !important }
|
|
736
|
+
/* Chip-Basis (nicht-inline, data-area): Text-/Border-Bereichstöne (--XX-700/800) bleiben im Dark dunkel
|
|
737
|
+
auf dem dunklen bg-surface → auf die hellen -200/-100/-300-Töne heben (analog .card-eyebrow). */
|
|
738
|
+
[data-theme="dark"] .chip[data-area="co"] { color: var(--co-200); border-color: var(--co-300) }
|
|
739
|
+
[data-theme="dark"] .chip[data-area="ki"] { color: var(--ki-200); border-color: var(--ki-400) }
|
|
740
|
+
[data-theme="dark"] .chip[data-area="es"] { color: var(--es-100); border-color: var(--es-300) }
|
|
741
|
+
[data-theme="dark"] .chip[data-area="wo"] { color: var(--wo-200); border-color: var(--wo-300) }
|
|
742
|
+
/* Dark-only: Der Hover-Rand nutzt im Light die kräftigeren -500/-600/-700-Töne. Im Dark sind das die
|
|
743
|
+
dunkleren, der Rand würde beim Überfahren also schwächer statt kräftiger — die Affordanz liefe
|
|
744
|
+
rückwärts (z.B. ki ruhend -400 #BEE82D → hover -700 #6B8208). Jeweils eine Stufe HELLER als der
|
|
745
|
+
Ruhezustand. (Light: -500/-600/-700 bleiben.) Spezifität 0,4,0 schlägt die Light-Regel. */
|
|
746
|
+
[data-theme="dark"] .chip[data-area="co"]:hover { border-color: var(--co-200) }
|
|
747
|
+
[data-theme="dark"] .chip[data-area="ki"]:hover { border-color: var(--ki-300) }
|
|
748
|
+
[data-theme="dark"] .chip[data-area="es"]:hover { border-color: var(--es-200) }
|
|
749
|
+
[data-theme="dark"] .chip[data-area="wo"]:hover { border-color: var(--wo-200) }
|
|
750
|
+
/* Doku-Sidebar: aktiver Eintrag hat im Light co-700-Text auf hellem co-50. Im Dark ist co-50 fast schwarz
|
|
751
|
+
(#16302E) → Text/Balken auf die hellen Töne heben (co-200 ~9,6:1 / co-300), sonst dunkel-auf-dunkel. */
|
|
752
|
+
[data-theme="dark"] .nav-item.active { color: var(--co-200); border-left-color: var(--co-300) }
|
|
753
|
+
/* Pills: --XX-50-Grund wird im Dark fast schwarz, Text --XX-700/800 bleibt dunkel → Text auf die hellen
|
|
754
|
+
-200/-100-Töne heben. Grund bleibt die dunkle -50-Kachel, der helle Text trägt den Kontrast (analog
|
|
755
|
+
.ep-card-icon/.card-eyebrow, ~13-15:1). aria-pressed-/Hover-States der Chips bleiben unberührt. */
|
|
756
|
+
[data-theme="dark"] .pill,
|
|
757
|
+
[data-theme="dark"] .pill[data-area="co"] { color: var(--co-200) }
|
|
758
|
+
[data-theme="dark"] .pill[data-area="ki"] { color: var(--ki-200) }
|
|
759
|
+
[data-theme="dark"] .pill[data-area="es"] { color: var(--es-100) }
|
|
760
|
+
[data-theme="dark"] .pill[data-area="wo"] { color: var(--wo-200) }
|
|
761
|
+
/* Bereichs-Text-Utilities + Bereichs-Badges: Light-Töne (-700/-800) bleiben im Dark dunkel → auf -200/-100 heben (Badge-Grund bleibt dunkle -50-Kachel, heller Text trägt den Kontrast). */
|
|
762
|
+
[data-theme="dark"] .t-ki { color: var(--ki-200) }
|
|
763
|
+
[data-theme="dark"] .t-es { color: var(--es-100) }
|
|
764
|
+
[data-theme="dark"] .t-wo { color: var(--wo-200) }
|
|
765
|
+
[data-theme="dark"] .badge[data-area="co"] { color: var(--co-200) }
|
|
766
|
+
[data-theme="dark"] .badge[data-area="ki"] { color: var(--ki-200) }
|
|
767
|
+
[data-theme="dark"] .badge[data-area="es"] { color: var(--es-100) }
|
|
768
|
+
[data-theme="dark"] .badge[data-area="wo"] { color: var(--wo-200) }
|
|
769
|
+
|
|
770
|
+
/* Segmented Control (dark): die dunkle -700/-800-Füllung würde auf dunklem Grund nicht heraustreten
|
|
771
|
+
→ helle -300-Füllung mit dunklem -900-Text (Corporate: #4DD0D0 ~4,7:1 gg. inaktive Segmente,
|
|
772
|
+
Text ~9,9:1). Die Bereichs-Varianten brauchen eigene Dark-Regeln, weil [data-theme] .seg
|
|
773
|
+
spezifischer ist als .seg-ki allein und die Light-Variante sonst überschreiben würde. */
|
|
774
|
+
[data-theme="dark"] .seg { --seg-fill: var(--co-300); --seg-on: var(--co-900) }
|
|
775
|
+
[data-theme="dark"] .seg-ki { --seg-fill: var(--ki-300); --seg-on: var(--ki-900) }
|
|
776
|
+
[data-theme="dark"] .seg-es { --seg-fill: var(--es-300); --seg-on: var(--es-900) }
|
|
777
|
+
[data-theme="dark"] .seg-wo { --seg-fill: var(--wo-300); --seg-on: var(--wo-900) }
|
|
778
|
+
|
|
779
|
+
/* ── Spacing & Grid + Code tokens ── */
|
|
780
|
+
/* co-700 (#007575) auf co-50 (dark, #16302E) ~2,4:1 → co-300 (#4DD0D0) = 7,5:1 */
|
|
781
|
+
[data-theme="dark"] .gcol { color: var(--co-ink) } /* co-300 trug auf der gehobenen Fuellung nur 4,48:1, co-ink (co-200) 5,35:1 */
|
|
782
|
+
/* Dark-only: co-300 trug auf der gehobenen co-Fuellung nur noch 4,48:1. Ueber --co-ink (im Dark
|
|
783
|
+
co-200) sind es 5,35:1, und farbiger Text laeuft damit ueber dasselbe Token wie ueberall sonst. */
|
|
784
|
+
[data-theme="dark"] .token { color: var(--co-ink) }
|
|
785
|
+
|
|
786
|
+
/* Body-Link / Card-CTA-Link / t-co: --co-700 auf bg-page = 1.97:1 ❌ → --co-200 = 6.97:1 ✓ AA */
|
|
787
|
+
[data-theme="dark"] .body-link { color: var(--co-200) }
|
|
788
|
+
[data-theme="dark"] .body-link:hover { color: var(--co-100) }
|
|
789
|
+
[data-theme="dark"] .card-cta-link { color: var(--co-200) }
|
|
790
|
+
/* Bereichsvariante des Card-CTA-Links (Shades wie .ep-card-cta): hebt die Akzentfarbe auf den
|
|
791
|
+
hellen Bereichston, sonst dunkel-auf-dunkel. Höhere Spezifität als die co-200-Regel darüber. */
|
|
792
|
+
[data-theme="dark"] .card-cta-link[data-area="co"] { color: var(--co-200) }
|
|
793
|
+
[data-theme="dark"] .card-cta-link[data-area="ki"] { color: var(--ki-200) }
|
|
794
|
+
[data-theme="dark"] .card-cta-link[data-area="es"] { color: var(--es-100) }
|
|
795
|
+
[data-theme="dark"] .card-cta-link[data-area="wo"] { color: var(--wo-200) }
|
|
796
|
+
[data-theme="dark"] .t-co { color: var(--co-200) }
|
|
797
|
+
[data-theme="dark"] [data-accent="ki"] .t-co { color: var(--ki-200) }
|
|
798
|
+
[data-theme="dark"] [data-accent="es"] .t-co { color: var(--es-200) }
|
|
799
|
+
[data-theme="dark"] [data-accent="wo"] .t-co { color: var(--wo-200) }
|
|
800
|
+
[data-theme="dark"] [data-accent="ki"] .body-link { color: var(--ki-200) }
|
|
801
|
+
[data-theme="dark"] [data-accent="es"] .body-link { color: var(--es-200) }
|
|
802
|
+
[data-theme="dark"] [data-accent="wo"] .body-link { color: var(--wo-200) }
|
|
803
|
+
[data-theme="dark"] [data-accent] .footer .body-link { color: var(--co-200) }
|
|
804
|
+
[data-theme="dark"] [data-accent] .ep-topnav .t-co { color: var(--co-200) }
|
|
805
|
+
/* Dark-only: Hover der bereichsgetönten Body-Links. Light geht auf -800 (dunkler), im Dark ergäbe das
|
|
806
|
+
dunkel-auf-dunkel: ❌ wo-800 auf bg-page = 1,17:1 → wo-100 = 8,7:1 ✓. (Light: -800 bleibt.)
|
|
807
|
+
Nötig, weil die Light-Hover-Regel `[data-accent="wo"] .body-link:hover` dieselbe Spezifität hat wie
|
|
808
|
+
die Dark-Grundregel eine Zeile höher und components.css NACH dark-mode.css geladen wird — ohne
|
|
809
|
+
eigene :hover-Regel hier gewinnt sonst der Light-Wert. Analog zu .body-link:hover → co-100. */
|
|
810
|
+
[data-theme="dark"] [data-accent="ki"] .body-link:hover { color: var(--ki-100) }
|
|
811
|
+
[data-theme="dark"] [data-accent="es"] .body-link:hover { color: var(--es-100) }
|
|
812
|
+
[data-theme="dark"] [data-accent="wo"] .body-link:hover { color: var(--wo-100) }
|
|
813
|
+
/* Dark-only: derselbe Fall eine Regel weiter — der Chrome-Reset der Footer-Links auf area-getönten
|
|
814
|
+
Seiten. Light hebt den Hover auf co-800, im Dark ergibt das ❌ 1,97:1 auf dem Footer-Grund.
|
|
815
|
+
→ co-100 ✓. (Light: co-800 bleibt.) Spezifität 0,5,0, damit die Ladereihenfolge egal ist. */
|
|
816
|
+
[data-theme="dark"] [data-accent] .footer .body-link:hover { color: var(--co-100) }
|
|
817
|
+
/* Dark-only: Hover-Zustände mit --co-700 auf theme-awarem tx-primary-Text (Footer-Link, Article-TOC)
|
|
818
|
+
→ im Dark wäre der Hover dunkler statt heller: ❌ co-700 auf bg-page. Hover-Akzent auf --co-200 heben ✓,
|
|
819
|
+
analog .body-link:hover. (Light: co-700 bleibt.) */
|
|
820
|
+
[data-theme="dark"] .footer-link:hover { color: var(--co-200) }
|
|
821
|
+
[data-theme="dark"] .article-toc-summary:hover,
|
|
822
|
+
[data-theme="dark"] .article-toc-list a:hover { color: var(--co-200) }
|
|
823
|
+
|
|
824
|
+
/* ── Cards ── */
|
|
825
|
+
/* Dark-only: Kartenkante über den Rand, dieselbe Begründung wie bei .ep-card oben. Auf einer
|
|
826
|
+
gehobenen n-50-Sektion hat die Karte den Ton ihres Grundes, der Rand macht sie zur Fläche:
|
|
827
|
+
--bd-strong-c = 4,21:1 gegen die Karte. .card trägt --bd-strong inzwischen in beiden Modi, diese
|
|
828
|
+
Regel ist aber NICHT redundant: sie hält mit Spezifität 0,2,0 auch die Link-Karte, die im Light
|
|
829
|
+
border:none trägt und sich auf --e1 verlässt: auf der
|
|
830
|
+
tiefen Dark-Basis trägt der schwarze Schatten das nicht mehr. Spezifität 0,2,0 schlägt
|
|
831
|
+
a.card-elevated (0,1,1), die Ladereihenfolge spielt also keine Rolle.
|
|
832
|
+
box-sizing ist global border-box, der Rand ändert die Kartengröße nicht. */
|
|
833
|
+
[data-theme="dark"] .card { border: 1px solid var(--bd-strong-c) }
|
|
834
|
+
/* Area card icons/eyebrows – same shades used for area-specimen-text in dark mode.
|
|
835
|
+
Eyebrow-Text auf bg-surface, nachgemessen nach der Flächen-Umstellung:
|
|
836
|
+
co-200 (#80DEDE) 8,32:1 · ki-200 (#D6F06D) 10,25:1 · es-100 (#C8D9F5) 9,11:1 · wo-200 (#A3D48E) 7,66:1.
|
|
837
|
+
Dieselben Töne auf der getönten -50-Kachel (Icon-Glyph, Schwelle 3:1): 6,24 / 7,77 / 6,87 / 5,78:1. */
|
|
838
|
+
[data-theme="dark"] .card[data-area="co"] .card-media{color:var(--co-200)}
|
|
839
|
+
[data-theme="dark"] .card[data-area="ki"] .card-media{color:var(--ki-200)}
|
|
840
|
+
[data-theme="dark"] .card[data-area="es"] .card-media{color:var(--es-100)}
|
|
841
|
+
[data-theme="dark"] .card[data-area="wo"] .card-media{color:var(--wo-200)}
|
|
842
|
+
[data-theme="dark"] .card[data-area="co"] .card-eyebrow{color:var(--co-200)}
|
|
843
|
+
[data-theme="dark"] .card[data-area="ki"] .card-eyebrow{color:var(--ki-200)}
|
|
844
|
+
[data-theme="dark"] .card[data-area="es"] .card-eyebrow{color:var(--es-100)}
|
|
845
|
+
[data-theme="dark"] .card[data-area="wo"] .card-eyebrow{color:var(--wo-200)}
|
|
846
|
+
/* ep-card-Eyebrow + CTA-Link: nutzen area -700/-800 ohne Dark-Override → dunkel-auf-dunkel.
|
|
847
|
+
Auf die hellen -200/-100-Töne heben (wie .card-eyebrow). Default (ohne data-area) = co. */
|
|
848
|
+
[data-theme="dark"] .ep-card-eyebrow, [data-theme="dark"] .ep-card-cta { color: var(--co-200) }
|
|
849
|
+
/* co explizit data-area-scoped: components.css (laedt NACH dark-mode.css) hat
|
|
850
|
+
.ep-card[data-area="co"] .ep-card-cta{co-700} mit gleicher Spezifitaet (0,2,0) → gewinnt sonst per
|
|
851
|
+
Quellreihenfolge → CTA bliebe dunkel (1,62:1). Gleiche Spezifitaet wie ki/es/wo unten herstellen. */
|
|
852
|
+
[data-theme="dark"] .ep-card-eyebrow[data-area="co"], [data-theme="dark"] .ep-card[data-area="co"] .ep-card-cta { color: var(--co-200) }
|
|
853
|
+
[data-theme="dark"] .ep-card-eyebrow[data-area="ki"], [data-theme="dark"] .ep-card[data-area="ki"] .ep-card-cta { color: var(--ki-200) }
|
|
854
|
+
[data-theme="dark"] .ep-card-eyebrow[data-area="es"], [data-theme="dark"] .ep-card[data-area="es"] .ep-card-cta { color: var(--es-100) }
|
|
855
|
+
[data-theme="dark"] .ep-card-eyebrow[data-area="wo"], [data-theme="dark"] .ep-card[data-area="wo"] .ep-card-cta { color: var(--wo-200) }
|
|
856
|
+
/* Stat Card values: co-700 (#007575) ~1.6:1 on dark → lighter shades (verified ≥4.5:1) */
|
|
857
|
+
[data-theme="dark"] .card-stat[data-area="co"] .card-stat-value{color:var(--co-200)}
|
|
858
|
+
[data-theme="dark"] .card-stat[data-area="ki"] .card-stat-value{color:var(--ki-200)}
|
|
859
|
+
[data-theme="dark"] .card-stat[data-area="es"] .card-stat-value{color:var(--es-100)}
|
|
860
|
+
[data-theme="dark"] .card-stat[data-area="wo"] .card-stat-value{color:var(--wo-200)}
|
|
861
|
+
|
|
862
|
+
/* ── Area specimen text – lighter palette shades pass ≥4.5:1 on dark surface (#28323D) ── */
|
|
863
|
+
[data-theme="dark"] [data-area="co"] .area-specimen-text { color: var(--co-200) } /* #80DEDE · 4.92:1 */
|
|
864
|
+
[data-theme="dark"] [data-area="ki"] .area-specimen-text { color: var(--ki-200) } /* #D6F06D · 6.10:1 */
|
|
865
|
+
[data-theme="dark"] [data-area="es"] .area-specimen-text { color: var(--es-100) } /* #C8D9F5 · 5.41:1 */
|
|
866
|
+
[data-theme="dark"] [data-area="wo"] .area-specimen-text { color: var(--wo-200) } /* #A3D48E · 4.57:1 */
|
|
867
|
+
|
|
868
|
+
/* ── Download CTA (dark) ── */
|
|
869
|
+
/* Icon colors: area-50 wird sehr dunkel → helle Palette-Shades wie area-specimen-text */
|
|
870
|
+
[data-theme="dark"] .cta-dl[data-area="co"] .cta-dl-icon{color:var(--co-200)}
|
|
871
|
+
[data-theme="dark"] .cta-dl[data-area="ki"] .cta-dl-icon{color:var(--ki-200)}
|
|
872
|
+
[data-theme="dark"] .cta-dl[data-area="es"] .cta-dl-icon{color:var(--es-100)}
|
|
873
|
+
[data-theme="dark"] .cta-dl[data-area="wo"] .cta-dl-icon{color:var(--wo-200)}
|
|
874
|
+
[data-theme="dark"] .cta-dl[data-area="co"] .cta-dl-eyebrow{color:var(--co-200)}
|
|
875
|
+
[data-theme="dark"] .cta-dl[data-area="ki"] .cta-dl-eyebrow{color:var(--ki-200)}
|
|
876
|
+
[data-theme="dark"] .cta-dl[data-area="es"] .cta-dl-eyebrow{color:var(--es-100)}
|
|
877
|
+
[data-theme="dark"] .cta-dl[data-area="wo"] .cta-dl-eyebrow{color:var(--wo-200)}
|
|
878
|
+
[data-theme="dark"] .cta-strip[data-area="co"] .cta-strip-icon{color:var(--co-200)}
|
|
879
|
+
[data-theme="dark"] .cta-strip[data-area="ki"] .cta-strip-icon{color:var(--ki-200)}
|
|
880
|
+
[data-theme="dark"] .cta-strip[data-area="es"] .cta-strip-icon{color:var(--es-100)}
|
|
881
|
+
[data-theme="dark"] .cta-strip[data-area="wo"] .cta-strip-icon{color:var(--wo-200)}
|
|
882
|
+
[data-theme="dark"] .cta-visual[data-area="co"] .cta-visual-eyebrow{color:var(--co-200)}
|
|
883
|
+
[data-theme="dark"] .cta-visual[data-area="ki"] .cta-visual-eyebrow{color:var(--ki-200)}
|
|
884
|
+
[data-theme="dark"] .cta-visual[data-area="es"] .cta-visual-eyebrow{color:var(--es-100)}
|
|
885
|
+
[data-theme="dark"] .cta-visual[data-area="wo"] .cta-visual-eyebrow{color:var(--wo-200)}
|
|
886
|
+
[data-theme="dark"] .cta-link[data-area="co"]{color:var(--co-200)}
|
|
887
|
+
[data-theme="dark"] .cta-link[data-area="ki"]{color:var(--ki-200)}
|
|
888
|
+
[data-theme="dark"] .cta-link[data-area="es"]{color:var(--es-100)}
|
|
889
|
+
[data-theme="dark"] .cta-link[data-area="wo"]{color:var(--wo-200)}
|
|
890
|
+
|
|
891
|
+
/* ── Palette threshold badges (dark) ── */
|
|
892
|
+
[data-theme="dark"] .pal-thresholds{background:#0d1f3a;color:#90bcf0;border-color:#1e3f6b}
|
|
893
|
+
[data-theme="dark"] .thr-aa-l{background:#1a3355;color:#90bcf0}
|
|
894
|
+
[data-theme="dark"] .thr-aa{background:#0a3028;color:#80e8c8}
|
|
895
|
+
[data-theme="dark"] .thr-aaa{background:#2a1050;color:#c890ff}
|
|
896
|
+
/* Code-Block (hell → dunkel) */
|
|
897
|
+
[data-theme="dark"] .cb-wrap{border-color:var(--bd)}
|
|
898
|
+
[data-theme="dark"] .cb-header{background:var(--bg-page);border-bottom-color:var(--bd)}
|
|
899
|
+
[data-theme="dark"] .cb-lang{color:var(--co-200)}
|
|
900
|
+
[data-theme="dark"] .cb-copy{border-color:var(--bd);color:var(--tx-muted)}
|
|
901
|
+
[data-theme="dark"] .cb-copy:hover{background:var(--bg-overlay);color:var(--tx-primary)}
|
|
902
|
+
[data-theme="dark"] .cb-body{background:var(--bg-surface);color:var(--tx-primary)}
|
|
903
|
+
/* Syntax tokens auf bg-surface (#28323D), alle ≥4.5:1 verifiziert */
|
|
904
|
+
[data-theme="dark"] .cb-body .k{color:var(--es-200)} /* #98B7EE · 5.1:1 */
|
|
905
|
+
[data-theme="dark"] .cb-body .v{color:var(--co-200)} /* #80DEDE · 4.9:1 */
|
|
906
|
+
[data-theme="dark"] .cb-body .s{color:var(--wo-200)} /* #A3D48E · 4.6:1 */
|
|
907
|
+
/* .cb-body .c nutzt jetzt schon im Light var(--tx-muted), der Dark-Override wäre wirkungsgleich
|
|
908
|
+
und ist deshalb entfallen. Die Terminal-Variante hat ihre eigene Regel in components.css. */
|
|
909
|
+
[data-theme="dark"] .cb-body .fn{color:var(--ro-200)} /* #F0A0BE · 4.6:1 */
|
|
910
|
+
[data-theme="dark"] .cb-numbered .cb-ln::before{color:var(--tx-muted)}
|
|
911
|
+
/* Inline code – co-700 (#007575) ~1.6:1 auf co-50 dark → co-200 (#80DEDE) ~4.9:1 ✓ */
|
|
912
|
+
[data-theme="dark"] .cb-prose code{color:var(--co-200);border-color:var(--n-100)}
|
|
913
|
+
/* Tabellen-Header + Streifen: --n-50 flippt im Dark auf #0A1515 (fast schwarz) → harte schwarze
|
|
914
|
+
Balken auf dem dunklen bg-page-Grund (1,70:1). Auf bg-surface heben (1,22:1) = sanfte, hellere
|
|
915
|
+
Differenzierung statt schwarzer Balken. Spiegelt die dezente Light-Streifung (dort minimal dunkler). */
|
|
916
|
+
[data-theme="dark"] .tbl thead th { background: var(--bg-surface) }
|
|
917
|
+
[data-theme="dark"] .tbl--striped tbody tr:nth-child(even) td,
|
|
918
|
+
[data-theme="dark"] .tbl--striped tbody tr:nth-child(even) th { background: var(--bg-surface) }
|
|
919
|
+
|
|
920
|
+
/* ── Fotos im Dark dämpfen ──
|
|
921
|
+
Bisher gab es keine Behandlung: helle Fotos standen unverändert auf dem Seitengrund. Auf der
|
|
922
|
+
tieferen Fläche (17,51:1 statt 10,92:1) blendet ein großflächiges helles Bild deutlich stärker,
|
|
923
|
+
die Material-Guidance nennt das unter „große leuchtende Flächen begrenzen“. .92 ist bewusst
|
|
924
|
+
knapp gewählt: Markenfotos sollen nicht ausgewaschen wirken, es geht nur um die Spitzlichter.
|
|
925
|
+
Nicht zu verwechseln mit dem verworfenen filter:brightness(.75) auf Icon-Glyphen weiter oben.
|
|
926
|
+
Das betraf Strichgrafik auf getönten Kacheln und drückte den Kontrast auf 1,7:1; hier liegt
|
|
927
|
+
Bildinhalt vor, kein bedeutungstragender Vordergrund auf einer Fläche. */
|
|
928
|
+
[data-theme="dark"] .hero-image-media img,
|
|
929
|
+
[data-theme="dark"] .ep-media-band img,
|
|
930
|
+
[data-theme="dark"] .article-figure img { filter: brightness(.92) }
|
|
931
|
+
|
|
932
|
+
/* ── Schwebende Panels: der Rand übernimmt, was der Schatten nicht mehr trägt ──
|
|
933
|
+
Menüs und Popover grenzen sich im Light über --e3 vom Inhalt darunter ab. Auf der tiefen
|
|
934
|
+
Basisfläche trägt ein schwarzer Schatten das nicht mehr. Gemessen stand ein geöffnetes
|
|
935
|
+
Topnav-Menü über dem Hero-Foto nur noch 1,34:1 gegen die hellste Stelle daneben (vorher 1,92:1),
|
|
936
|
+
weil die Panel-Fläche mitgesunken ist, das Foto darunter aber nicht.
|
|
937
|
+
Eine dritte statische Flächen-Stufe wäre der Material-Weg („höher gleich heller“), würde aber die
|
|
938
|
+
Zwei-Stufen-Konvention des Systems brechen und einem Menü über einer Karte nur 1,13:1 bringen.
|
|
939
|
+
Stattdessen übernimmt der Rand: --bd-strong-c statt --bd-c, das ist unabhängig davon lesbar, was
|
|
940
|
+
zufällig hinter dem Panel liegt, und erfüllt WCAG 1.4.11 für die Panel-Grenze deutlich.
|
|
941
|
+
(Light: --bd bleibt, dort trägt der Schatten auf hellem Grund.) */
|
|
942
|
+
[data-theme="dark"] .ep-nav-sub,
|
|
943
|
+
[data-theme="dark"] .ep-select-menu,
|
|
944
|
+
[data-theme="dark"] .ep-combobox-menu,
|
|
945
|
+
[data-theme="dark"] .ep-nav-search-panel { border-color: var(--bd-strong-c) }
|
|
946
|
+
/* Die Snackbar gehört in dieselbe Familie: sie schwebt über beliebigem Inhalt und trägt im Light
|
|
947
|
+
keinen Rahmen, weil ihre dunkle Fläche auf hellem Grund für sich steht. Im Dark liegt sie mit
|
|
948
|
+
1,23:1 (Default) bis 1,79:1 (Status) sehr nah am Grund, deshalb bekommt sie den Rand dazu.
|
|
949
|
+
Er trägt 4,61:1 auf der Default-Fläche und 3,17:1 auf den Status-Flächen. */
|
|
950
|
+
[data-theme="dark"] .snack { border: 1px solid var(--bd-strong-c) }
|
|
951
|
+
} /* Ende @media screen, umschließt die ganze Datei (siehe Kopf) */
|
|
952
|
+
|
|
953
|
+
/* === css/base.css === */
|
|
954
|
+
/* ── Base: Reset · Layout · Global ── */
|
|
955
|
+
|
|
956
|
+
/* ════════════════════════════════════════════
|
|
957
|
+
SYSTEM HIGH CONTRAST (Windows / OS level)
|
|
958
|
+
@media (forced-colors: active)
|
|
959
|
+
════════════════════════════════════════════ */
|
|
960
|
+
@media (forced-colors: active) {
|
|
961
|
+
/* box-shadow is suppressed by OS – replace focus rings with outline */
|
|
962
|
+
:focus-visible {
|
|
963
|
+
outline: 3px solid Highlight !important;
|
|
964
|
+
outline-offset: 2px !important;
|
|
965
|
+
box-shadow: none !important;
|
|
966
|
+
}
|
|
967
|
+
/* Custom button backgrounds need explicit forced-color mapping */
|
|
968
|
+
.btn-filled {
|
|
969
|
+
forced-color-adjust: none;
|
|
970
|
+
background: ButtonText;
|
|
971
|
+
color: ButtonFace;
|
|
972
|
+
border: 2px solid ButtonText;
|
|
973
|
+
}
|
|
974
|
+
.btn-tonal,
|
|
975
|
+
.btn-elevated,
|
|
976
|
+
.btn-text,
|
|
977
|
+
.btn-outlined {
|
|
978
|
+
color: ButtonText;
|
|
979
|
+
border-color: ButtonText;
|
|
980
|
+
background: ButtonFace;
|
|
981
|
+
box-shadow: none;
|
|
982
|
+
}
|
|
983
|
+
/* Restore borders that forced-colors removes */
|
|
984
|
+
.chip { border: 2px solid ButtonText }
|
|
985
|
+
.card,
|
|
986
|
+
.card-elevated,
|
|
987
|
+
/* .stoerer liegt über einem Foto und verlässt sich im Light auf --bd-strong plus --e1.
|
|
988
|
+
Im Kontrastmodus fällt der Schatten weg, der 1px-Rand allein trägt die Kachel dann nicht
|
|
989
|
+
mehr gegen das Bild ab — gleiche 2px wie bei den übrigen Kartenflächen. */
|
|
990
|
+
.stoerer { border: 2px solid CanvasText }
|
|
991
|
+
.badge { border: 1px solid ButtonText; background: ButtonFace; color: ButtonText }
|
|
992
|
+
/* Active states */
|
|
993
|
+
.nav-item.active { border-left-color: Highlight; color: Highlight }
|
|
994
|
+
.atab.active { border-bottom-color: Highlight; color: Highlight }
|
|
995
|
+
.tbtn.active { forced-color-adjust: none; background: Highlight; color: HighlightText }
|
|
996
|
+
/* Links in footer */
|
|
997
|
+
.footer-link,
|
|
998
|
+
.footer-btm-link { color: LinkText }
|
|
999
|
+
/* Skip link */
|
|
1000
|
+
.skip-link { background: Highlight; color: HighlightText; border: 2px solid ButtonText }
|
|
1001
|
+
/* Sidebar toggle */
|
|
1002
|
+
.sidebar-toggle { border: 1px solid ButtonText; color: ButtonText }
|
|
1003
|
+
/* Form inputs */
|
|
1004
|
+
.field input,
|
|
1005
|
+
.field select,
|
|
1006
|
+
.field textarea { border: 2px solid ButtonText; color: CanvasText; background: Canvas }
|
|
1007
|
+
/* Code blocks */
|
|
1008
|
+
.code-block { border: 1px solid CanvasText }
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/* ── Reset ── */
|
|
1012
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
1013
|
+
body{font-family:var(--font);font-size:1rem;line-height:1.7;color:var(--tx-primary);background:var(--bg-page);transition:background var(--m-std),color var(--m-std)}
|
|
1014
|
+
|
|
1015
|
+
/* ── Skip link ── */
|
|
1016
|
+
/* Fläche co-700, nicht co-500: weiß auf #00BEBE trägt nur 2,31:1 und verfehlt AA für Normaltext.
|
|
1017
|
+
In Ruhe ist der Link geclippt, beim Fokus springt er sichtbar herein, also genau dann, wenn
|
|
1018
|
+
Tastaturnutzende ihn brauchen. co-700 (#007575) trägt weiß mit 5,52:1 und ist zugleich die
|
|
1019
|
+
Füllfarbe, die .btn-filled.btn-co verwendet. Gilt in beiden Modi, co-* flippt nicht. */
|
|
1020
|
+
.skip-link{position:absolute;top:-100px;left:var(--s4);background:var(--co-700);color:#fff;padding:var(--s2) var(--s4);border-radius:var(--r-md);font-weight:600;font-size:0.875rem;z-index:9999;transition:top var(--m-fast);border:none;cursor:pointer;font-family:var(--font)}
|
|
1021
|
+
.skip-link:focus{top:var(--s4)}
|
|
1022
|
+
|
|
1023
|
+
/* ── Layout ── */
|
|
1024
|
+
.ds-page{display:flex;min-height:100vh}
|
|
1025
|
+
.ds-sidebar{width:252px;flex-shrink:0;background:var(--bg-surface);border-right:var(--bd);padding:var(--s8) 0;position:sticky;top:0;height:100vh;overflow-y:auto;overflow-x:hidden;transition:width var(--m-std)}
|
|
1026
|
+
.ds-content{flex:1;padding:var(--s10) var(--s6);max-width:1280px;transition:margin-left var(--m-std)}
|
|
1027
|
+
/* Vorschau-Modus (≤ 1024px): Doku-Sidebar ausblenden und horizontalen Content-Abstand
|
|
1028
|
+
auf 0, damit die Beispielseiten exakt die Fensterbreite einnehmen. Sonst quetscht die
|
|
1029
|
+
feste 252px-Sidebar die .ep-page in eine Restspalte, während ihre @media-Queries die
|
|
1030
|
+
volle Fensterbreite lesen — Container-Breite und Breakpoint passen dann nicht zusammen
|
|
1031
|
+
und die Mobile/Tablet-Vorschau wird unbrauchbar. So stimmen .ep-page-Breite und Breakpoint
|
|
1032
|
+
überein → DevTools-Geräte-Modus und Fenster-Verkleinern zeigen die Seite faithful.
|
|
1033
|
+
Die Beispielseiten-Tabs liegen im Content (nicht in der Sidebar), bleiben also erreichbar. */
|
|
1034
|
+
@media (max-width: 1024px) {
|
|
1035
|
+
.ds-sidebar{display:none}
|
|
1036
|
+
.ds-content{padding-inline:0}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/* ── Sidebar ── */
|
|
1040
|
+
.nav-logo{padding:0 var(--s6) var(--s6);border-bottom:var(--bd);margin-bottom:var(--s5);display:flex;align-items:center;justify-content:space-between;gap:var(--s2)}
|
|
1041
|
+
/* --co-ink, nicht co-500: die Signalfarbe trägt auf Weiß nur 2,31:1. Das Ink-Token flippt mit dem
|
|
1042
|
+
Theme (Light co-700, Dark co-200), ein festes co-700 wäre im Dark 2,36:1 auf der Sidebar. */
|
|
1043
|
+
.nav-logo-text{font:500 0.75rem/1rem var(--font);letter-spacing:.02em;text-transform:uppercase;color:var(--co-ink);white-space:nowrap;overflow:hidden;transition:opacity var(--m-std),width var(--m-std)}
|
|
1044
|
+
|
|
1045
|
+
/* ── Sidebar toggle button ── */
|
|
1046
|
+
.sidebar-toggle{background:none;border:none;cursor:pointer;padding:4px;border-radius:var(--r-xs);color:var(--tx-secondary);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--m-fast),color var(--m-fast)}
|
|
1047
|
+
.sidebar-toggle:hover{background:var(--bg-overlay);color:var(--tx-primary)}
|
|
1048
|
+
.sidebar-toggle:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1049
|
+
.sidebar-toggle svg{transition:transform var(--m-std)}
|
|
1050
|
+
|
|
1051
|
+
/* ── Sidebar collapsed state ── */
|
|
1052
|
+
.ds-sidebar.collapsed{width:56px}
|
|
1053
|
+
.ds-sidebar.collapsed .nav-logo{padding:0 0 var(--s6);justify-content:center}
|
|
1054
|
+
.ds-sidebar.collapsed .nav-logo-text{opacity:0;width:0;overflow:hidden}
|
|
1055
|
+
.ds-sidebar.collapsed .sidebar-toggle svg{transform:rotate(180deg)}
|
|
1056
|
+
.ds-sidebar.collapsed .nav-section,.ds-sidebar.collapsed .nav-subnav{display:none}
|
|
1057
|
+
.ds-sidebar.collapsed .nav-item{justify-content:center;padding:var(--s2) 0;font-size:0;gap:0}
|
|
1058
|
+
.ds-sidebar.collapsed .nav-icon{width:20px;height:20px;opacity:.6}
|
|
1059
|
+
.ds-sidebar.collapsed .nav-item:hover .nav-icon{opacity:1}
|
|
1060
|
+
.ds-sidebar.collapsed .nav-item.active .nav-icon{opacity:1}
|
|
1061
|
+
/* .nav-section ist ein <h2> (Screenreader-Outline der Nav-Gruppen) — UA-Heading-Margins zurücksetzen */
|
|
1062
|
+
.nav-section{margin:0;padding:var(--s3) var(--s6) var(--s1);font:500 0.75rem/1rem var(--font);letter-spacing:.08em;text-transform:uppercase;color:var(--tx-muted)}
|
|
1063
|
+
/* Nav-Gruppen als Liste (Screenreader: „Liste, N Einträge“); Default-Einrückung/Bullets entfernen */
|
|
1064
|
+
.nav-list{list-style:none;margin:0;padding:0}
|
|
1065
|
+
/* Größerer Abstand vor jeder folgenden Gruppen-Überschrift (visuelle Trennung der Bereiche);
|
|
1066
|
+
die erste Gruppe braucht ihn nicht, sie ist bereits durch das Logo/den Rahmen getrennt. */
|
|
1067
|
+
.nav-list + .nav-section{margin-top:var(--s4)}
|
|
1068
|
+
.nav-item{display:flex;align-items:center;gap:var(--s2);padding:7px var(--s6);font:500 0.875rem/1.25rem var(--font);color:var(--tx-secondary);cursor:pointer;border-left:3px solid transparent;transition:background var(--m-fast),color var(--m-fast),border-color var(--m-fast);background:none;border-top:none;border-right:none;border-bottom:none;width:100%;text-align:left}
|
|
1069
|
+
.nav-item:hover{background:var(--bg-overlay);color:var(--tx-primary)}
|
|
1070
|
+
.nav-item:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1071
|
+
/* Aktiver Eintrag: Text co-700 (co-500 #00BEBE auf co-50 war nur 2,07:1 → co-700 = 4,95:1, WCAG 1.4.3).
|
|
1072
|
+
Akzentbalken co-600 (3,28:1 auf Weiß, WCAG 1.4.11). Zustand zusätzlich über font-weight (nicht nur Farbe → 1.4.1). */
|
|
1073
|
+
.nav-item.active{color:var(--co-700);background:var(--co-50);border-left-color:var(--co-600);font-weight:600}
|
|
1074
|
+
.nav-icon{width:18px;height:18px;flex-shrink:0;opacity:.7;fill:none;stroke:currentColor;stroke-width:1.5}
|
|
1075
|
+
.nav-item.active .nav-icon{opacity:1}
|
|
1076
|
+
.area-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
|
1077
|
+
|
|
1078
|
+
/* ── Sections ── */
|
|
1079
|
+
.ds-section{display:none}
|
|
1080
|
+
.ds-section.visible{display:block}
|
|
1081
|
+
.sec-title{font:400 2rem/2.5rem var(--font-display);color:var(--tx-primary);margin-bottom:var(--s2)}
|
|
1082
|
+
.sec-sub{font:400 1rem/1.5rem var(--font);color:var(--tx-secondary);margin-bottom:var(--s8)}
|
|
1083
|
+
.group-title{font:400 1.5rem/2rem var(--font-display);color:var(--tx-primary);margin:var(--s10) 0 var(--s4);padding-top:var(--s6);border-top:var(--bd)}
|
|
1084
|
+
.lbl{font:500 0.75rem/1rem var(--font);letter-spacing:.07em;text-transform:uppercase;color:var(--tx-muted);display:block;margin-bottom:var(--s2)}
|
|
1085
|
+
.row{display:flex;flex-wrap:wrap;gap:var(--s4);align-items:flex-start}
|
|
1086
|
+
.token{font-family:var(--font-mono);font-size:0.75rem;color:var(--co-700);background:var(--co-50);padding:2px 7px;border-radius:var(--r-xs)}
|
|
1087
|
+
|
|
1088
|
+
/* ── Theme switcher ── */
|
|
1089
|
+
.theme-bar{position:fixed;top:var(--s3);right:var(--s4);display:flex;gap:var(--s2);z-index:200;background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-full);padding:4px;box-shadow:var(--e2)}
|
|
1090
|
+
.tbtn{display:inline-flex;align-items:center;gap:6px;padding:5px var(--s3);border-radius:var(--r-full);border:none;cursor:pointer;font:500 0.75rem/1rem var(--font);background:transparent;color:var(--tx-secondary);transition:background var(--m-fast),color var(--m-fast)}
|
|
1091
|
+
.tbtn svg{width:14px;height:14px;flex:none}
|
|
1092
|
+
.tbtn:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1093
|
+
/* Aktiv-Fläche co-700 statt co-500: weiß auf #007575 = 5,5:1 (AA) — co-500 #00BEBE war nur 2,3:1 (Fail bei 12px/500) */
|
|
1094
|
+
.tbtn.active{background:var(--co-700);color:#fff}
|
|
1095
|
+
|
|
1096
|
+
/* ── Color palettes ── */
|
|
1097
|
+
.pal-group{margin-bottom:var(--s8)}
|
|
1098
|
+
.pal-label{font:500 0.875rem/1.25rem var(--font);color:var(--tx-secondary);margin-bottom:var(--s3);display:flex;align-items:center;gap:var(--s2)}
|
|
1099
|
+
/* Die Reihe ist eine Karte: Haarlinie plus Rundung, Inhalt geklippt. Ohne den Rahmen verliert sie
|
|
1100
|
+
im Light ihre Kante, weil die hellen Stufen (50, 100) und der weiße Beschriftungs-Streifen beide
|
|
1101
|
+
fast die Farbe der Seite haben (#E0F7F7 gegen Weiß sind 1,12:1). Im Dark trennt sich der Streifen
|
|
1102
|
+
von der Seite ohnehin, dort ist der Rahmen nur konsequent. Die Rundung liegt an der Karte, damit
|
|
1103
|
+
sie oben UND unten greift; das Klippen betrifft nur die Ecken, nicht den Streifen. */
|
|
1104
|
+
.pal-row{display:flex;gap:2px;border:1px solid var(--bd-c);border-radius:var(--r-md);overflow:hidden}
|
|
1105
|
+
/* Farbfeld oben, Beschriftung auf einem neutralen Streifen darunter. Vorher saß die Beschriftung
|
|
1106
|
+
AUF der Farbe, und dort lässt sich der Kontrast nicht garantieren: bei sieben von hundert Stufen
|
|
1107
|
+
liegt die Leuchtdichte so in der Mitte, dass weder weiße noch dunkle Schrift 4,5:1 erreicht
|
|
1108
|
+
(auf ki-700 schafft selbst reines Schwarz nur 4,82:1). Auf dem neutralen Streifen sind es überall
|
|
1109
|
+
6,28:1, in beiden Modi, und das Farbfeld bleibt unverdeckt. Der abzulesende Hexwert ist
|
|
1110
|
+
Information, keine Dekoration, deshalb hat er einen Grund, auf dem er trägt. */
|
|
1111
|
+
.swatch{position:relative;flex:1;min-height:104px;display:flex;flex-direction:column;justify-content:flex-end;padding:0;overflow:hidden}
|
|
1112
|
+
/* Keine Deckkraft-Absenkung auf der Beschriftung: opacity .75 kostete jedes Label rund ein
|
|
1113
|
+
Viertel Kontrast, und auf dem Swatch steht der Hexwert, den man ablesen soll. Die Farbe wird
|
|
1114
|
+
je Swatch gesetzt (helle Fläche → dunkler Text und umgekehrt), das reicht als Abstufung. */
|
|
1115
|
+
/* Der Streifen braucht Luft nach oben, sonst klebt die Beschriftung am Farbfeld. nowrap, weil ein
|
|
1116
|
+
Umbruch ("800 T") das Farbfeld dieser einen Spalte nach oben schöbe und die Reihe eine Stufe
|
|
1117
|
+
bekäme. */
|
|
1118
|
+
/* Linie zwischen Farbfeld und Beschriftung: im Light grenzt der weiße Streifen sonst nicht gegen
|
|
1119
|
+
die hellen Stufen ab. Sie sitzt auf der ersten Zeile des Streifens, also nur einmal je Spalte. */
|
|
1120
|
+
.swatch span{font-size:0.75rem;font-family:var(--font-mono);font-weight:600;line-height:1.5;background:var(--bg-surface);color:var(--tx-secondary);padding:5px 6px 0;white-space:nowrap}
|
|
1121
|
+
.swatch > span:first-of-type{border-top:1px solid var(--bd-c);padding-top:4px}
|
|
1122
|
+
/* Eingeblendeter Hex-Code (nur Tonal-Paletten): kräftiger als das Stufen-Label, damit als Referenz ablesbar */
|
|
1123
|
+
.swatch .swatch-hex{text-transform:uppercase;letter-spacing:.01em;padding:0 6px 5px}
|
|
1124
|
+
/* Unter 1024 px wird eine Spalte zu schmal für den Hexwert. Er entfällt dann; der Wert steht
|
|
1125
|
+
weiterhin im title-Attribut und wird per Klick kopiert (docs/main.js). Die Stufe bleibt. */
|
|
1126
|
+
@media (max-width:1024px){ .swatch .swatch-hex{display:none} }
|
|
1127
|
+
/* Klick-zum-Kopieren: Cursor + Fokus. Fokus-Ring als inset box-shadow (zwei Töne → auf hellen
|
|
1128
|
+
UND dunklen Swatches sichtbar), da .pal-row overflow:hidden einen äußeren Ring abschneiden würde. */
|
|
1129
|
+
.swatch.is-copyable,.clip-card.is-copyable{cursor:pointer}
|
|
1130
|
+
.swatch.is-copyable:focus-visible,.swatch.is-copyable.is-copied{outline:none;box-shadow:inset 0 0 0 2px rgba(255,255,255,.95),inset 0 0 0 4px rgba(17,17,17,.9);z-index:1}
|
|
1131
|
+
.clip-card.is-copyable:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
1132
|
+
/* Bestätigung: Häkchen-Overlay (fit auch auf schmalen Swatches; SR-Ansage übernimmt der aria-live-Bereich) */
|
|
1133
|
+
.swatch.is-copied::after{content:"✓";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(17,17,17,.82);color:#fff;font:700 1rem/1 var(--font);border-radius:inherit}
|
|
1134
|
+
.clip-card.is-copied{position:relative}
|
|
1135
|
+
.clip-card.is-copied::after{content:"✓ Kopiert";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(17,17,17,.82);color:#fff;font:600 0.875rem/1 var(--font)}
|
|
1136
|
+
.ai-warning{margin-top:var(--s3);padding:var(--s3) var(--s4);background:var(--ki-50);border-radius:var(--r-md);font-size:0.75rem;color:var(--ki-800);border:1px solid var(--ki-200)}
|
|
1137
|
+
.pal-note{margin-top:var(--s3);padding:var(--s3) var(--s4);background:var(--c-warning-bg);border-radius:var(--r-md);font-size:0.75rem;color:#5a3e00;border:1px solid #e8d080}
|
|
1138
|
+
.pal-thresholds{margin-top:var(--s2);padding:var(--s2) var(--s4);background:#EDF4FF;border-radius:var(--r-md);font-size:0.75rem;color:#1a3a6b;border:1px solid #b8d0f0;font-family:var(--font-mono)}
|
|
1139
|
+
.pal-thresholds .thr-badge{display:inline-block;padding:1px 6px;border-radius:3px;font-weight:700;margin-right:2px;font-size:0.75rem}
|
|
1140
|
+
.thr-aa-l{background:#dbeeff;color:#1a3a6b}
|
|
1141
|
+
.thr-aa{background:#c3f0e8;color:#0a4a38}
|
|
1142
|
+
.thr-aaa{background:#e8d0ff;color:#3a1070}
|
|
1143
|
+
|
|
1144
|
+
/* ── Area specimen text (default: dark brand shade for light bg) ── */
|
|
1145
|
+
[data-area="co"] .area-specimen-text{color:var(--co-700)}
|
|
1146
|
+
[data-area="ki"] .area-specimen-text{color:var(--ki-800)}
|
|
1147
|
+
[data-area="es"] .area-specimen-text{color:var(--es-700)}
|
|
1148
|
+
[data-area="wo"] .area-specimen-text{color:var(--wo-700)}
|
|
1149
|
+
|
|
1150
|
+
/* ── Area cards ── */
|
|
1151
|
+
.areas-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s6);margin-bottom:var(--s8)}
|
|
1152
|
+
@media(max-width:768px){.areas-grid{grid-template-columns:1fr}}
|
|
1153
|
+
.area-card{border-radius:var(--r-lg);border:var(--bd-strong);overflow:hidden;display:flex;flex-direction:column}
|
|
1154
|
+
.area-header{padding:var(--s5) var(--s6);color:#fff}
|
|
1155
|
+
.area-header h2{font:400 1rem/1.5rem var(--font-display);margin-bottom:4px}
|
|
1156
|
+
.area-header p{font:400 0.75rem/1rem var(--font)}
|
|
1157
|
+
.area-body{padding:var(--s4) var(--s6);background:var(--bg-surface);flex:1}
|
|
1158
|
+
.area-swatch-row{display:flex;gap:3px;margin-bottom:var(--s3)}
|
|
1159
|
+
.area-swatch{width:28px;height:28px;border-radius:var(--r-xs)}
|
|
1160
|
+
.area-meta{font:400 0.75rem/1rem var(--font);color:var(--tx-secondary)}
|
|
1161
|
+
.area-meta code{font-size:0.75rem;font-family:var(--font-mono)}
|
|
1162
|
+
|
|
1163
|
+
/* Utility: hartes Verstecken (überschreibt Inline-display) */
|
|
1164
|
+
.is-hidden{display:none!important}
|
|
1165
|
+
|
|
1166
|
+
/* ── Layout Grid (12 Spalten · Gutter: var(--s6)=24px · Container: 1280px) ── */
|
|
1167
|
+
.layout-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--s6)}
|
|
1168
|
+
.col-1{grid-column:span 1}.col-2{grid-column:span 2}.col-3{grid-column:span 3}
|
|
1169
|
+
.col-4{grid-column:span 4}.col-5{grid-column:span 5}.col-6{grid-column:span 6}
|
|
1170
|
+
.col-7{grid-column:span 7}.col-8{grid-column:span 8}.col-9{grid-column:span 9}
|
|
1171
|
+
.col-10{grid-column:span 10}.col-11{grid-column:span 11}.col-12{grid-column:span 12}
|
|
1172
|
+
/* Kollabiert auf 1 Spalte. Wichtig: auch die col-*-Spannweiten zurücksetzen — sonst spannen
|
|
1173
|
+
die Kinder weiter span 7/span 5/… und erzeugen bei nur einer 1fr-Spalte implizite Auto-Spalten,
|
|
1174
|
+
wodurch unterschiedlich gespannte Geschwister (z. B. col-7 Text vs. col-5 Bild) verschieden
|
|
1175
|
+
breit werden. Mit grid-column:auto ist jedes Kind exakt volle Breite. */
|
|
1176
|
+
@media(max-width:768px){
|
|
1177
|
+
.layout-grid{grid-template-columns:1fr}
|
|
1178
|
+
.layout-grid>[class*="col-"]{grid-column:auto}
|
|
1179
|
+
}
|
|
1180
|
+
/* Team-Kacheln („Wer wir sind“): statt einspaltig untereinander als 2×2-Raster, damit die
|
|
1181
|
+
vier Köpfe auf dem Phone kompakt bleiben. Override der col-3-Spannweite (3 → 1 Track). */
|
|
1182
|
+
@media(max-width:768px){
|
|
1183
|
+
.layout-grid[data-team-tiles]{grid-template-columns:1fr 1fr}
|
|
1184
|
+
.layout-grid[data-team-tiles] > [data-team-tile]{grid-column:auto}
|
|
1185
|
+
}
|
|
1186
|
+
/* Team-Roster („Die Menschen“, Über uns): ~70 Personen sollen mobil nicht einspaltig als
|
|
1187
|
+
endlose Liste laufen. Tablet (521–768px) → 3 Spalten (ab ~520px gibt das ≥ ~146px je Spalte,
|
|
1188
|
+
genug Platz). Phone (≤ 520px) → 2 Spalten, sonst zu gedrängt. minmax(0,1fr) verhindert
|
|
1189
|
+
Grid-Blowout durch lange Namen (Text wrappt). Engerer Gap (--s4). col-3-Spannweite → 1 Track.
|
|
1190
|
+
520px-Bruch konsistent mit dem Hero-CTA-Breakpoint. */
|
|
1191
|
+
@media(max-width:768px){
|
|
1192
|
+
.layout-grid[data-team-roster]{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s4)}
|
|
1193
|
+
.layout-grid[data-team-roster] > .col-3{grid-column:auto}
|
|
1194
|
+
}
|
|
1195
|
+
@media(max-width:520px){
|
|
1196
|
+
.layout-grid[data-team-roster]{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
1197
|
+
}
|
|
1198
|
+
/* Benefits-Grid (4 Kategorien) und Event-Meta-Strip (4 Key-Facts: Datum/Ort/Format/Eintritt):
|
|
1199
|
+
Tablet (521–768px) → 2×2 statt der einspaltigen layout-grid-Kollabierung; Smartphone (≤ 520px)
|
|
1200
|
+
→ 1×4 einspaltig. Desktop (> 768px) bleibt 4-spaltig. Die col-3-Spannweite setzt bereits die
|
|
1201
|
+
globale Regel oben zurück. 520px-Bruch konsistent mit Roster/Hero-CTAs. */
|
|
1202
|
+
@media(max-width:768px){
|
|
1203
|
+
.layout-grid[data-benefits],.layout-grid[data-event-meta]{grid-template-columns:1fr 1fr}
|
|
1204
|
+
}
|
|
1205
|
+
@media(max-width:520px){
|
|
1206
|
+
.layout-grid[data-benefits],.layout-grid[data-event-meta]{grid-template-columns:1fr}
|
|
1207
|
+
}
|
|
1208
|
+
/* Editorial-Split (Bild + Text nebeneinander): stapelt auf Mobile einspaltig, das Bild läuft
|
|
1209
|
+
full-width. Der inline Text-Cap (max-width:520px, gedacht für die Zeilenlänge NEBEN dem Bild)
|
|
1210
|
+
erzeugt dann eine Asymmetrie — Text schmaler als das Bild darüber. Unter dem Bild aufheben,
|
|
1211
|
+
damit der Fließtext bündig zur Bildbreite läuft. !important, weil der Cap inline gesetzt ist;
|
|
1212
|
+
greift nur auf .ep-section-sub INNERHALB eines layout-grid (Splits), nicht auf Sektions-Leads. */
|
|
1213
|
+
@media(max-width:768px){
|
|
1214
|
+
.layout-grid .ep-section-sub{max-width:none!important}
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/* ── Utility: visuell versteckt, aber für Screenreader lesbar ── */
|
|
1218
|
+
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
1219
|
+
|
|
1220
|
+
/* ── Type Scale Utilities (15 Tokens) ── */
|
|
1221
|
+
.type-display-lg{font:400 3.5625rem/4rem var(--font-display)}
|
|
1222
|
+
.type-display-md{font:400 2.8125rem/3.25rem var(--font-display)}
|
|
1223
|
+
.type-display-sm{font:400 2.25rem/2.75rem var(--font-display)}
|
|
1224
|
+
.type-headline-lg{font:400 2rem/2.5rem var(--font-display)}
|
|
1225
|
+
.type-headline-md{font:400 1.75rem/2.25rem var(--font-display)}
|
|
1226
|
+
.type-headline-sm{font:400 1.5rem/2rem var(--font-display)}
|
|
1227
|
+
.type-title-lg{font:500 1.375rem/1.75rem var(--font)}
|
|
1228
|
+
.type-title-md{font:500 1rem/1.5rem var(--font)}
|
|
1229
|
+
.type-title-sm{font:500 0.875rem/1.25rem var(--font)}
|
|
1230
|
+
.type-body-lg{font:400 1rem/1.5rem var(--font)}
|
|
1231
|
+
.type-body-md{font:400 0.875rem/1.25rem var(--font)}
|
|
1232
|
+
.type-body-sm{font:400 0.75rem/1rem var(--font)}
|
|
1233
|
+
.type-label-lg{font:500 0.875rem/1.25rem var(--font)}
|
|
1234
|
+
.type-label-md{font:500 0.75rem/1rem var(--font)}
|
|
1235
|
+
.type-label-sm{font:500 0.75rem/1rem var(--font);text-transform:uppercase;letter-spacing:.08em}
|
|
1236
|
+
|
|
1237
|
+
/* ── Sub-navigation ── */
|
|
1238
|
+
.nav-subnav{display:none;padding-bottom:var(--s2)}
|
|
1239
|
+
.nav-subnav.visible{display:block}
|
|
1240
|
+
.nav-sub-item{display:block;padding:5px var(--s6) 5px 36px;font:var(--ty-body-xs);color:var(--tx-secondary);text-decoration:none;transition:background var(--m-fast),color var(--m-fast);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
1241
|
+
.nav-sub-item::before{content:"–";opacity:.4;margin-right:6px;font-size:0.75rem}
|
|
1242
|
+
.nav-sub-item:hover{color:var(--tx-primary);background:var(--bg-overlay)}
|
|
1243
|
+
.nav-sub-item:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1244
|
+
|
|
1245
|
+
/* ── Scroll margin for jump targets ── */
|
|
1246
|
+
.group-title{scroll-margin-top:var(--s8)}
|
|
1247
|
+
|
|
1248
|
+
/* ── Back-to-top button ── */
|
|
1249
|
+
/* co-600 statt co-500: weißes Caret braucht ≥3:1 (1.4.11) — co-600 = 3,29:1 (Icon), und der Button vs.
|
|
1250
|
+
Seite ≥3:1 sowohl auf weiß (Light, 3,29) als auch auf bg-page (Dark, 3,32); co-500 verfehlt es im Light,
|
|
1251
|
+
co-700 im Dark. visibility (mit-transitioniert) nimmt den versteckten Button aus der Tab-Reihenfolge —
|
|
1252
|
+
sonst ist ein unsichtbares Fokusziel per Tab erreichbar. */
|
|
1253
|
+
.back-to-top{position:fixed;bottom:var(--s8);right:var(--s6);width:44px;height:44px;border-radius:var(--r-full);background:var(--co-600);color:#fff;border:none;cursor:pointer;box-shadow:var(--e3);display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--m-std),visibility var(--m-std),box-shadow var(--m-fast);z-index:150}
|
|
1254
|
+
.back-to-top.visible{opacity:1;visibility:visible;pointer-events:auto}
|
|
1255
|
+
.back-to-top:hover{box-shadow:var(--e4)}
|
|
1256
|
+
.back-to-top:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
1257
|
+
|
|
1258
|
+
/* === css/components.css === */
|
|
1259
|
+
/* ── Components ── */
|
|
1260
|
+
|
|
1261
|
+
/* ── Brand Wheel ── */
|
|
1262
|
+
.bw-wrap{display:flex;justify-content:center;padding:var(--s8) 0}
|
|
1263
|
+
.bw-svg{width:100%;max-width:480px;display:block}
|
|
1264
|
+
.bw-outer{fill:var(--co-50)}
|
|
1265
|
+
.bw-middle{fill:var(--co-200)}
|
|
1266
|
+
/* #fff on co-400 (#26C2C2) = 2.19:1 ❌. co-800 (#004F4F) = 9.42:1 ✓ AAA in beiden Modi.
|
|
1267
|
+
Inhaltlich getrieben (GELASSENHEIT muss lesbar sein); visuell wird das Rad damit dunkler im Zentrum. */
|
|
1268
|
+
.bw-inner{fill:var(--co-800)}
|
|
1269
|
+
.bw-divider{stroke:#fff;stroke-width:2;fill:none}
|
|
1270
|
+
.bw-ring-outline{fill:none;stroke:#fff;stroke-width:2}
|
|
1271
|
+
/* SVG-Text bleibt in px (Ausnahme von der rem-Konvention): skaliert über das viewBox
|
|
1272
|
+
der SVG mit, rem in SVG ist Browser-abhängig unzuverlässig. */
|
|
1273
|
+
.bw-label-core{fill:#fff;font-family:var(--font);font-size:17px;font-weight:700;letter-spacing:2px}
|
|
1274
|
+
.bw-label-segment{fill:var(--co-800);font-family:var(--font);font-size:13px;font-weight:700;letter-spacing:1px}
|
|
1275
|
+
.bw-label-attr{fill:var(--co-700);font-family:var(--font);font-size:12px;font-weight:600;letter-spacing:.8px}
|
|
1276
|
+
.bw-pillar-card{flex:1;min-width:180px;padding:var(--s5);border-radius:var(--r-lg);background:var(--n-0);border:var(--bd-strong)}
|
|
1277
|
+
.bw-pillar-title{font-size:0.875rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;margin-bottom:var(--s2);color:var(--co-700)}
|
|
1278
|
+
.bw-pillar-attrs{font-size:0.875rem;color:var(--tx-secondary);line-height:1.6}
|
|
1279
|
+
|
|
1280
|
+
/* ── Buttons ── */
|
|
1281
|
+
.btn{display:inline-flex;align-items:center;gap:var(--s2);font:var(--ty-label-md);letter-spacing:.05em;text-transform:uppercase;padding:10px 24px;border-radius:var(--r-full);border:none;cursor:pointer;transition:box-shadow var(--m-fast),transform var(--m-fast),filter var(--m-fast);min-height:44px;text-decoration:none}
|
|
1282
|
+
.btn:hover,.btn:focus,.btn:active{text-decoration:none}
|
|
1283
|
+
.btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
1284
|
+
.btn:active{transform:scale(.97)}
|
|
1285
|
+
.btn[disabled]{opacity:.38;cursor:not-allowed;pointer-events:none}
|
|
1286
|
+
.btn-sm{padding:6px 16px;font-size:0.75rem;line-height:1rem;min-height:36px}
|
|
1287
|
+
.btn-lg{padding:14px 32px;font-size:1rem;line-height:1.5rem;min-height:52px}
|
|
1288
|
+
.btn-filled{background:var(--c500);color:#fff;box-shadow:var(--e1)}
|
|
1289
|
+
.btn-filled:hover{filter:brightness(.92);box-shadow:var(--e2)}
|
|
1290
|
+
.btn-tonal{background:var(--c50);color:var(--c500);border:1.5px solid rgba(0,0,0,.12)}
|
|
1291
|
+
.btn-tonal:hover{filter:brightness(.96);box-shadow:var(--e1)}
|
|
1292
|
+
.btn-elevated{background:var(--bg-surface);color:var(--c500);box-shadow:var(--e1)}
|
|
1293
|
+
.btn-elevated:hover{box-shadow:var(--e2)}
|
|
1294
|
+
.btn-outlined{background:transparent;color:var(--c500);border:2px solid var(--c500)}
|
|
1295
|
+
.btn-outlined:hover{background:var(--c50)}
|
|
1296
|
+
.btn-text{background:transparent;color:var(--c500);padding:10px 12px}
|
|
1297
|
+
.btn-text:hover{background:var(--c50)}
|
|
1298
|
+
|
|
1299
|
+
/* ── Button brand-area color variants ── */
|
|
1300
|
+
.btn-co {--c500:var(--co-700);--c50:var(--co-50)}
|
|
1301
|
+
.btn-ki {--c500:var(--ki-800);--c50:var(--ki-50)}
|
|
1302
|
+
.btn-es {--c500:var(--es-700);--c50:var(--es-50)}
|
|
1303
|
+
.btn-wo {--c500:var(--wo-700);--c50:var(--wo-50)}
|
|
1304
|
+
/* Modifier: invertiert auf dunklem Bereichs-Band (z. B. .ep-cta-band) — kombiniert mit .btn-co/.btn-ki/.btn-es/.btn-wo. Background wird weiß, Text trägt die Bereichsfarbe. */
|
|
1305
|
+
.btn-on-band{--c500:#fff;--c50:rgba(255,255,255,.1)}
|
|
1306
|
+
.btn-co.btn-on-band{color:var(--co-700)}
|
|
1307
|
+
.btn-ki.btn-on-band{color:var(--ki-800)}
|
|
1308
|
+
.btn-es.btn-on-band{color:var(--es-700)}
|
|
1309
|
+
.btn-wo.btn-on-band{color:var(--wo-700)}
|
|
1310
|
+
/* Full-width centered submit button */
|
|
1311
|
+
.btn-full {width:100%;justify-content:center}
|
|
1312
|
+
|
|
1313
|
+
/* ── Showcase containers ── */
|
|
1314
|
+
.ds-card {border:var(--bd-strong);border-radius:var(--r-lg);overflow:hidden;display:flex;flex-direction:column;flex:1}
|
|
1315
|
+
.ds-surface{border:var(--bd-strong);border-radius:var(--r-lg);padding:var(--s6);background:var(--bg-surface)}
|
|
1316
|
+
.ds-inner {padding:var(--s6);background:var(--bg-surface);flex:1}
|
|
1317
|
+
/* Formular-Karten in gleich hohen Grid-Spalten: das Textarea-Feld füllt den Leerraum, damit der
|
|
1318
|
+
Submit-Button unten bündig zur Nachbar-Karte sitzt. flex-basis:auto (natürliche Höhe) + grow,
|
|
1319
|
+
kein Schrumpfen unter die natürliche Größe; min-height als Boden. Nur .field mit Textarea wächst. */
|
|
1320
|
+
.ds-inner-fill{display:flex;flex-direction:column}
|
|
1321
|
+
.ds-inner-fill .field:has(textarea){flex:1 1 auto;display:flex;flex-direction:column}
|
|
1322
|
+
.ds-inner-fill .field:has(textarea) textarea{flex:1 1 auto;min-height:96px}
|
|
1323
|
+
.clip-card {border-radius:var(--r-md);overflow:hidden;border:var(--bd-strong)}
|
|
1324
|
+
|
|
1325
|
+
/* ── Badges & Chips ── */
|
|
1326
|
+
.badge{display:inline-flex;align-items:center;gap:var(--s1);padding:3px 10px;border-radius:var(--r-full);font:var(--ty-label-xs);letter-spacing:.04em}
|
|
1327
|
+
.badge-ok{background:var(--c-success-bg);color:var(--badge-ok-text)}
|
|
1328
|
+
.badge-warn{background:var(--c-warning-bg);color:var(--badge-warn-text)}
|
|
1329
|
+
.badge-err{background:var(--c-error-bg);color:var(--badge-err-text)}
|
|
1330
|
+
.badge-neu{background:var(--badge-neu-bg);color:var(--badge-neu-text)}
|
|
1331
|
+
/* Bereichs-Badges: --XX-50-Grund + --XX-800-Text. Dark-Overrides (dark-mode.css) heben den Text auf -200/-100, Grund bleibt die dunkle -50-Kachel. */
|
|
1332
|
+
/* Füllung über --XX-fill, nicht --XX-50: die Füllung muss als Fläche lesen (1,3:1 gegen jeden
|
|
1333
|
+
Grund), --XX-50 trug im Light nur 1,06 bis 1,14:1. Siehe Token-Kommentar in tokens.css. */
|
|
1334
|
+
.badge[data-area="co"]{background:var(--co-fill);color:var(--co-800)}
|
|
1335
|
+
.badge[data-area="ki"]{background:var(--ki-fill);color:var(--ki-800)}
|
|
1336
|
+
.badge[data-area="es"]{background:var(--es-fill);color:var(--es-800)}
|
|
1337
|
+
.badge[data-area="wo"]{background:var(--wo-fill);color:var(--wo-800)}
|
|
1338
|
+
/* text-decoration:none, damit der Chip auch als <a> trägt (Tag-Link, Sprungmarke, externer Verweis)
|
|
1339
|
+
und nicht unterstrichen rendert. Auf <button> ohne Wirkung. */
|
|
1340
|
+
.chip{display:inline-flex;align-items:center;gap:var(--s1);padding:6px var(--s4);border-radius:var(--r-sm);font:var(--ty-label-md);border:1.5px solid var(--n-200);cursor:pointer;background:var(--bg-surface);color:var(--tx-primary);min-height:32px;text-decoration:none;transition:background var(--m-fast),border-color var(--m-fast),color var(--m-fast)}
|
|
1341
|
+
.chip:hover{background:var(--bg-overlay);border-color:var(--n-400)}
|
|
1342
|
+
.chip:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1343
|
+
.chip[aria-pressed="true"]{background:var(--n-700);border-color:var(--n-700);color:#fff}
|
|
1344
|
+
.chip[aria-pressed="true"]:hover{background:var(--n-800);border-color:var(--n-800)}
|
|
1345
|
+
/* Area-aware Chips: Outline + Bereichs-Textfarbe (inaktiv) für ruhige Filter-Leiste, dezenter Tonal-Hint beim Hover, gefüllte dunklere Variante mit weißer Schrift (aktiv, AA-konform) */
|
|
1346
|
+
/* Rahmen = hellerer Ton als Text (Nicht-Text 3:1 vs. Text 4,5:1) — bei co jedoch co-600 statt co-500,
|
|
1347
|
+
da co-500 #00BEBE nur 2,3:1 auf Weiß erreicht (WCAG 1.4.11); co-600 #009E9E = 3,28:1, bleibt < co-700-Text */
|
|
1348
|
+
.chip[data-area="co"]{border-color:var(--co-600);color:var(--co-700)}
|
|
1349
|
+
.chip[data-area="ki"]{border-color:var(--ki-700);color:var(--ki-800)}
|
|
1350
|
+
.chip[data-area="es"]{border-color:var(--es-500);color:var(--es-700)}
|
|
1351
|
+
.chip[data-area="wo"]{border-color:var(--wo-500);color:var(--wo-700)}
|
|
1352
|
+
.chip[data-area="co"]:hover{background:var(--co-50);border-color:var(--co-600)}
|
|
1353
|
+
.chip[data-area="ki"]:hover{background:var(--ki-50);border-color:var(--ki-700)}
|
|
1354
|
+
.chip[data-area="es"]:hover{background:var(--es-50);border-color:var(--es-500)}
|
|
1355
|
+
.chip[data-area="wo"]:hover{background:var(--wo-50);border-color:var(--wo-500)}
|
|
1356
|
+
.chip[data-area="co"][aria-pressed="true"]{background:var(--co-700);border-color:var(--co-700);color:#fff}
|
|
1357
|
+
.chip[data-area="ki"][aria-pressed="true"]{background:var(--ki-800);border-color:var(--ki-800);color:#fff}
|
|
1358
|
+
.chip[data-area="es"][aria-pressed="true"]{background:var(--es-700);border-color:var(--es-700);color:#fff}
|
|
1359
|
+
.chip[data-area="wo"][aria-pressed="true"]{background:var(--wo-700);border-color:var(--wo-700);color:#fff}
|
|
1360
|
+
.chip[data-area][aria-pressed="true"]:hover{filter:brightness(.92)}
|
|
1361
|
+
|
|
1362
|
+
/* ── Segmented Control ──
|
|
1363
|
+
Native <input type="radio"> als verbundene Button-Gruppe (2–4 kurze Optionen).
|
|
1364
|
+
Der :checked-Zustand ist nur per Selektor stylbar (nicht inline), daher als echte
|
|
1365
|
+
Komponente. Das native Input bleibt fokussierbar (visuell versteckt), Auswahl per
|
|
1366
|
+
Klick aufs Label und per Pfeiltasten. Aktives Segment = solide Bereichsfüllung
|
|
1367
|
+
(Light co-700/weiß, Dark co-300/co-900) — AA in beiden Modi. overflow:hidden
|
|
1368
|
+
clippt die Füllung sauber zur Rundung; der Fokusring liegt daher per :has() auf
|
|
1369
|
+
dem Container (dessen eigener outset-Schatten wird vom overflow NICHT geclippt). */
|
|
1370
|
+
/* Bereichs-Varianten wie bei .btn: Default ist Corporate, .seg-ki/-es/-wo überschreiben die
|
|
1371
|
+
Füllung des gewählten Segments. Ohne diese Varianten trägt ein Bereichsformular mitten in
|
|
1372
|
+
seinen Feldern einen Corporate-Akzent, was der Regel „ein Formular, eine Brand Area“
|
|
1373
|
+
widerspricht. Der Fokusring bleibt bewusst Corporate (siehe Don'ts unter Dropdowns). */
|
|
1374
|
+
/* Rahmen über --field-border: n-200 trug als Bedienelement-Grenze nur 1,53:1 und verfehlte die
|
|
1375
|
+
3:1-Schwelle aus WCAG 1.4.11. --field-border ist genau dafür da (Light n-400, 3,92:1). */
|
|
1376
|
+
.seg{display:inline-flex;border:1.5px solid var(--field-border);border-radius:var(--r-sm);overflow:hidden;background:var(--bg-surface);--seg-fill:var(--co-700);--seg-on:#fff}
|
|
1377
|
+
.seg-ki{--seg-fill:var(--ki-800)}
|
|
1378
|
+
.seg-es{--seg-fill:var(--es-700)}
|
|
1379
|
+
.seg-wo{--seg-fill:var(--wo-700)}
|
|
1380
|
+
.seg:has(input:focus-visible){box-shadow:var(--focus-aa)}
|
|
1381
|
+
.seg-option:not(:last-child){border-right:1.5px solid var(--n-200)}
|
|
1382
|
+
.seg-option input{position:absolute;width:1px;height:1px;opacity:0}
|
|
1383
|
+
.seg-option label{display:flex;align-items:center;min-height:40px;padding:var(--s2) var(--s5);font:var(--ty-label-md);color:var(--tx-secondary);white-space:nowrap;cursor:pointer;transition:background var(--m-fast),color var(--m-fast)}
|
|
1384
|
+
.seg-option label:hover{background:var(--bg-overlay);color:var(--tx-primary)}
|
|
1385
|
+
.seg-option input:checked + label{background:var(--seg-fill);color:var(--seg-on)}
|
|
1386
|
+
|
|
1387
|
+
/* ── Area Tabs ── */
|
|
1388
|
+
.area-tabs{display:flex;gap:2px;border-bottom:var(--bd);margin-bottom:var(--s6)}
|
|
1389
|
+
.atab{padding:var(--s2) var(--s4);font:var(--ty-label-md);cursor:pointer;border-bottom:3px solid transparent;margin-bottom:-1px;color:var(--tx-secondary);transition:color var(--m-fast),border-color var(--m-fast);min-height:40px;display:flex;align-items:center;gap:var(--s2);background:none;border-top:none;border-left:none;border-right:none}
|
|
1390
|
+
.atab:hover{color:var(--tx-primary)}
|
|
1391
|
+
.atab:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1392
|
+
.atab.active{color:var(--atab-color);border-bottom-color:var(--atab-color)}
|
|
1393
|
+
.atab-content{display:none}
|
|
1394
|
+
.atab-content.visible{display:block}
|
|
1395
|
+
|
|
1396
|
+
/* ── Cards ── */
|
|
1397
|
+
/* Die Karte ist eine vertikale Spalte: Bild, Body, optionaler Footer. Das steht hier und nicht im
|
|
1398
|
+
style-Attribut, weil das dokumentierte Rezept es voraussetzt: .card-body{flex:1} kann die
|
|
1399
|
+
Resthöhe nur in einem Flex-Container einnehmen, und ohne diese Resthöhe hat
|
|
1400
|
+
.card-cta-link--pinned kein margin-top:auto, an dem es sich ausrichten könnte. Die Karten in
|
|
1401
|
+
einem .layout-grid werden von außen auf gleiche Höhe gezogen; der Body nimmt den Überschuss
|
|
1402
|
+
auf, damit die CTA-Zeilen nebeneinanderliegender Karten auf einer Linie sitzen.
|
|
1403
|
+
.card-featured bleibt display:block (weiter unten, spätere Regel gewinnt): dort liegt der Body
|
|
1404
|
+
absolut, eine Flex-Spalte hätte da nichts zu verteilen. */
|
|
1405
|
+
.card{background:var(--bg-surface);border-radius:var(--r-lg);border:var(--bd-strong);overflow:hidden;display:flex;flex-direction:column;transition:box-shadow var(--m-std),transform var(--m-std)}
|
|
1406
|
+
/* Card-Varianten */
|
|
1407
|
+
/* Elevation = Interaktivität, und zwar an der FLÄCHE: Schatten trägt eine Karte nur, wenn die Karte
|
|
1408
|
+
selbst der klickbare Bereich ist. Buttons im .card-footer machen die Fläche nicht klickbar, die
|
|
1409
|
+
Interaktion liegt dann in den Buttons; so eine Karte ruht flach mit dem --bd-Rahmen aus .card.
|
|
1410
|
+
Deshalb hängt die ganze Variante an a.*: eine <article>/<div>-Karte bekommt den Schatten auch
|
|
1411
|
+
dann nicht, wenn die Klasse gesetzt ist. Das ist der Riegel, nicht nur eine Empfehlung. */
|
|
1412
|
+
a.card-elevated{box-shadow:var(--e1);border:none;background:var(--bg-surface)}
|
|
1413
|
+
a.card-elevated:hover{box-shadow:var(--e2);transform:translateY(-2px)}
|
|
1414
|
+
|
|
1415
|
+
.card-media{width:100%;aspect-ratio:16/9;display:flex;align-items:center;justify-content:center}
|
|
1416
|
+
/* Der Body ordnet seine Kinder, also gehört ihm auch der Abstand zwischen ihnen: eine Flex-Spalte
|
|
1417
|
+
mit gap:var(--s3) als einziger vertikaler Rhythmus der Karte. Vorher trug jedes Kind seine
|
|
1418
|
+
eigene Außenmarge, und wer den Body flexte, bekam Marge PLUS Gap (im Flex-Layout kollabieren
|
|
1419
|
+
sie nicht). Darum haben .card-eyebrow und .card-cta-link hier keine Marge mehr, und die Pill
|
|
1420
|
+
bekommt ihre unten zurückgenommen.
|
|
1421
|
+
flex:1 lässt den Body die Resthöhe der Karte einnehmen. Nötig für .card-cta-link--pinned
|
|
1422
|
+
(margin-top:auto braucht freien Raum im Container) und für gleich hohe Karten im Grid: ohne das
|
|
1423
|
+
sammelt sich der Überschuss unter dem Body, statt in ihm. Auf einer nicht-flexen Karte ist die
|
|
1424
|
+
Deklaration wirkungslos, nicht schädlich. */
|
|
1425
|
+
.card-body{padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);flex:1}
|
|
1426
|
+
.card-eyebrow{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase}
|
|
1427
|
+
/* Area-branded card media + eyebrow (token-driven, dark-mode overridable) */
|
|
1428
|
+
.card[data-area="co"] .card-media{background:var(--co-50);color:var(--co-700)}
|
|
1429
|
+
.card[data-area="ki"] .card-media{background:var(--ki-50);color:var(--ki-700)}
|
|
1430
|
+
.card[data-area="es"] .card-media{background:var(--es-50);color:var(--es-600)}
|
|
1431
|
+
.card[data-area="wo"] .card-media{background:var(--wo-50);color:var(--wo-700)}
|
|
1432
|
+
.card[data-area="co"] .card-eyebrow{color:var(--co-700)}
|
|
1433
|
+
.card[data-area="ki"] .card-eyebrow{color:var(--ki-800)}
|
|
1434
|
+
.card[data-area="es"] .card-eyebrow{color:var(--es-700)}
|
|
1435
|
+
.card[data-area="wo"] .card-eyebrow{color:var(--wo-700)}
|
|
1436
|
+
/* card-title und card-text: line-clamp + min-height halten Karten in Grids visuell ausgerichtet,
|
|
1437
|
+
unabhängig davon ob Titel/Anreißer im aktuellen CMS-Stand 1, 2 oder 3 Zeilen lang sind.
|
|
1438
|
+
line-clamp kappt zu lange Inhalte; min-height (in lh-Units, skaliert mit Typografie-Tokens)
|
|
1439
|
+
reserviert die Maximum-Höhe, damit Karten in einer Row nicht durch Längen-Varianz „springen“.
|
|
1440
|
+
Trade-Off: bei aktuell kurzem Content sieht das wie ein Hohlraum aus, ist aber gewollt — das Layout
|
|
1441
|
+
muss morgen mit einer 2-zeiligen Headline umgehen, ohne dass jemand CSS-Klassen umtauschen muss. */
|
|
1442
|
+
/* Äußerer Container: reserviert min. 2-Zeilen-Höhe und zentriert den Inhalt vertikal mittig.
|
|
1443
|
+
Inneres <span> trägt das Line-Clamping (kappt zu lange Titel auf 2 Zeilen). */
|
|
1444
|
+
/* Title Small (18px Sans 500) gibt eine klare Hierarchie-Stufe zur Section-H2 (Headline-md, 28px Serif)
|
|
1445
|
+
und vermeidet, dass die Card-Titel mit den Sektion-Überschriften um Aufmerksamkeit konkurrieren. */
|
|
1446
|
+
.card-title{font:var(--ty-title-sm);color:var(--tx-primary);min-height:2lh;display:grid;align-content:center}
|
|
1447
|
+
.card-title>*{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
|
|
1448
|
+
/* Hero-Variante: Editorial-Treatment für Featured-Cards (genau ein Termin oder ein Beitrag hervorgehoben).
|
|
1449
|
+
Headline-Sm (24px Serif) als Mid-Tier zwischen Section-H2 (28px) und Standard-Card-Title (20px Sans),
|
|
1450
|
+
saubere 4-px-Treppe in der Hierarchie. Kein min-height (kein Nachbar zum Abgleichen). */
|
|
1451
|
+
.card-title-hero{font:var(--ty-headline-sm);color:var(--tx-primary);margin:0;text-wrap:balance}
|
|
1452
|
+
.card-text{font:var(--ty-body-md);color:var(--tx-secondary);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3;overflow:hidden;min-height:3lh}
|
|
1453
|
+
/* Mobile (≤ 768px): .layout-grid wird einspaltig, die Cards stehen ohne Nachbarn full-width.
|
|
1454
|
+
Dann sind die min-height-Reservierungen (Titel 2lh, Text 3lh) — die nur die Gleichhöhe
|
|
1455
|
+
nebeneinanderstehender Cards sichern — leerer Raum und erzeugen große Lücken. Aufheben.
|
|
1456
|
+
Das line-clamp (Titel 2, Text 3 Zeilen) bleibt, lange Inhalte kürzen also weiterhin.
|
|
1457
|
+
.ep-cards (auto-fit) bleibt bewusst unberührt: dort stehen Cards auch mobil noch mehrspaltig. */
|
|
1458
|
+
@media(max-width:768px){
|
|
1459
|
+
.layout-grid .card-title,.layout-grid .card-text{min-height:0}
|
|
1460
|
+
}
|
|
1461
|
+
/* Wie im Featured-Body: die Eigenmarge der Pill (--s5, gedacht für den normalen Fluss) würde sich
|
|
1462
|
+
zum gap des Bodys addieren, statt zu kollabieren. Der Abstand kommt aus dem Container. Nur
|
|
1463
|
+
direkte Kinder, eine Pill tiefer im Body steht in einem eigenen Layout. */
|
|
1464
|
+
.card-body>.pill{margin-bottom:0}
|
|
1465
|
+
/* Kompakter Meta-Block (Datum + Ort) — kleinerer Gap zwischen den Zeilen, damit das Paar als eine Einheit gelesen wird,
|
|
1466
|
+
nicht als zwei unabhängige Items. Sitzt selbst im Card-Body und nutzt dessen Gap (--s3) zur Pill darüber und zum Titel darunter. */
|
|
1467
|
+
.card-meta{display:flex;flex-direction:column;gap:var(--s1)}
|
|
1468
|
+
.card-footer{padding:var(--s3) var(--s5);border-top:var(--bd);display:flex;align-items:center;justify-content:flex-end;gap:var(--s2)}
|
|
1469
|
+
|
|
1470
|
+
/* ── Featured-Card: horizontale Großkarte ──
|
|
1471
|
+
Genau ein Beitrag oder Termin auf der Bühne: Bild links, Content rechts.
|
|
1472
|
+
Die Bildspalte trägt .card-media und damit dasselbe aspect-ratio:16/9 wie die Cards im
|
|
1473
|
+
Listing-Grid. Das ist der Zweck der Klasse: Redaktion pflegt EIN Bild in EINEM Zuschnitt
|
|
1474
|
+
für Featured UND Grid, statt je Slot einen eigenen.
|
|
1475
|
+
|
|
1476
|
+
Das BILD bestimmt die Kartenhöhe, nicht der Text. Darum liegt .card-featured-body absolut:
|
|
1477
|
+
als normale Spalte zieht seine Inhaltshöhe die Zeile auf und streckt das Bild mit — genau
|
|
1478
|
+
daran driftete das Verhältnis vorher auf 1,62. Ein aspect-ratio auf der Karte genügt dafür
|
|
1479
|
+
nicht, es ist eine Wunschgröße und verliert gegen die Inhaltshöhe (gemessen 1,50). Absolut
|
|
1480
|
+
positioniert trägt der Body nichts zur Höhe bei, das 16/9 gilt unabhängig von der Textlänge.
|
|
1481
|
+
|
|
1482
|
+
Zu viel Text wird gekappt, statt das Verhältnis zu brechen: .card-text bringt sein
|
|
1483
|
+
line-clamp mit, und als schrumpfendes Flex-Item gibt der Lead nach, bevor Pill, Meta,
|
|
1484
|
+
Titel oder CTA wegfallen. 60/40 statt 50/50, weil ein 16/9-Bild auf halber Kartenbreite
|
|
1485
|
+
zu flach für den Content-Block ist: bei 60 % bleiben rund 26 px Reserve und drei
|
|
1486
|
+
Lead-Zeilen, bei 50 % schrumpft der Lead auf null. Beide Prozentwerte gehören zusammen
|
|
1487
|
+
und müssen 100 % ergeben, sonst klafft eine Lücke. */
|
|
1488
|
+
.card-featured{display:block;position:relative;overflow:hidden;container-type:inline-size}
|
|
1489
|
+
.card-featured>.card-media{width:60%}
|
|
1490
|
+
.card-featured>.card-media>img{width:100%;height:100%;object-fit:cover}
|
|
1491
|
+
.card-featured-body{position:absolute;top:0;right:0;bottom:0;width:40%;padding:var(--s6) var(--s8);display:flex;flex-direction:column;justify-content:center;gap:var(--s4);overflow:hidden}
|
|
1492
|
+
/* Die Pill bringt eine Eigenmarge von --s5 mit, gedacht für den normalen Fluss (Pill über der H1
|
|
1493
|
+
im Article-Header). Hier trägt der Body den Abstand als gap:var(--s4), und beide addieren sich:
|
|
1494
|
+
im Flex-Layout kollabieren Marge und Gap nicht. Ergebnis wären 36 px unter der Pill statt 16 px,
|
|
1495
|
+
und der Meta-Block löst sich vom Bereichs-Signal, mit dem er als Meta-Header zusammengehört. Der
|
|
1496
|
+
Abstand gehört dem Container, nicht der Pill, also wird ihre Marge hier zurückgenommen. Nur für
|
|
1497
|
+
direkte Kinder: eine Pill tiefer im Body (etwa in einer Zeile neben einem Titel) steht in einem
|
|
1498
|
+
eigenen Layout und regelt ihren Abstand dort selbst. */
|
|
1499
|
+
.card-featured-body>.pill{margin-bottom:0}
|
|
1500
|
+
/* min-height:3lh reserviert im Grid Platz für den Gleichhöhen-Abgleich. Die Featured-Card
|
|
1501
|
+
steht allein, hat keinen Nachbarn, und der reservierte Platz ginge zulasten des Bildes. */
|
|
1502
|
+
.card-featured-body>.card-text{min-height:0}
|
|
1503
|
+
/* Auch der Titel braucht einen Riegel, sonst frisst ein langer Titel die Höhe, die der Lead
|
|
1504
|
+
braucht, und danach die von Pill und CTA (gemessen mit einem 18-Wort-Titel: Lead auf null
|
|
1505
|
+
Zeilen, Pill und CTA aus der Karte geschoben). Drei Zeilen sind für eine Hero-Card reichlich.
|
|
1506
|
+
Nur hier, nicht global: .card-title-hero bleibt außerhalb der Featured-Card unbeschnitten. */
|
|
1507
|
+
.card-featured-body>.card-title-hero{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3;overflow:hidden}
|
|
1508
|
+
/* Drei Stufen, alle an der KARTENBREITE per @container, nicht am Viewport: die Kartenbreite
|
|
1509
|
+
hängt am Platz im Layout (Sidebar, Section-Padding, Spaltenbreite). Im Doku-Mockup ist die
|
|
1510
|
+
Karte bei 1180 px Viewport nur 814 px breit, bei 1024 px dagegen 958 px — eine
|
|
1511
|
+
Viewport-Regel träfe dort das Falsche.
|
|
1512
|
+
|
|
1513
|
+
Die Stufen greifen über die Reihenfolge: die 1000er-Regel gilt ab hier abwärts, die
|
|
1514
|
+
900er-Regel überschreibt sie darunter wieder. Gleiche Spezifität, die spätere gewinnt.
|
|
1515
|
+
|
|
1516
|
+
1000 px abwärts (Tablet-Landscape): nebeneinander BLEIBEN, aber verdichtet. Das Bild auf
|
|
1517
|
+
65 % statt 60 %, denn breiteres Bild heißt bei 16/9 auch höheres Bild und damit mehr Platz
|
|
1518
|
+
für den Content-Block; dazu kleineres Padding. Ohne das schrumpft der Lead hier auf eine
|
|
1519
|
+
oder null Zeilen. Gemessen bei 958 px Kartenbreite: Karte 350 px hoch, drei Lead-Zeilen,
|
|
1520
|
+
rund 22 px Reserve (Veranstaltungs-Karte mit dreizeiligem Meta-Strip: 30 px). */
|
|
1521
|
+
@container (max-width:1000px){
|
|
1522
|
+
.card-featured>.card-media{width:65%}
|
|
1523
|
+
.card-featured-body{width:35%;padding:var(--s4) var(--s6)}
|
|
1524
|
+
/* Lead auf zwei Zeilen: drei passen hier nicht mehr vollständig, und ein Lead, der als
|
|
1525
|
+
Flex-Item unter seine line-clamp-Höhe gedrückt wird, endet mitten in der Zeile statt mit
|
|
1526
|
+
Auslassungspunkten. Mit zwei Zeilen bleibt die Kante bei üblichen Titellängen sauber.
|
|
1527
|
+
Rest-Fall: bei einem Titel, der den 3-Zeilen-Riegel voll ausschöpft, wird auch die zweite
|
|
1528
|
+
Lead-Zeile angeschnitten. Das ist bewusst so gelassen — irgendetwas muss dann nachgeben,
|
|
1529
|
+
und eine halbe Lead-Zeile ist der geringste Schaden. Titel kürzen behebt es an der
|
|
1530
|
+
Quelle. Die Karte bleibt in jedem Fall geschlossen: Pill und CTA werden nicht mehr
|
|
1531
|
+
hinausgeschoben, dafür sorgt der Titel-Riegel. */
|
|
1532
|
+
.card-featured-body>.card-text{-webkit-line-clamp:2;line-clamp:2}
|
|
1533
|
+
}
|
|
1534
|
+
/* 900 px abwärts (Portrait, Smartphone, schmale Container): gestapelt wie die Grid-Cards.
|
|
1535
|
+
Bild full-width im 16/9 obenauf, Body zurück in den Fluss, nichts mehr zu kappen. Tiefer
|
|
1536
|
+
als 900 px nebeneinander zu bleiben lohnt nicht: die Textspalte wäre unter 250 px breit,
|
|
1537
|
+
rund 30 Zeichen pro Zeile. */
|
|
1538
|
+
@container (max-width:900px){
|
|
1539
|
+
.card-featured>.card-media{width:100%}
|
|
1540
|
+
.card-featured-body{position:static;width:auto;padding:var(--s6)}
|
|
1541
|
+
/* Lead zurück auf drei Zeilen: das Kürzen auf zwei gilt nur der knappen Höhe der
|
|
1542
|
+
Tablet-Stufe. Gestapelt gibt es keine feste Höhe zu halten, also auch keinen Grund,
|
|
1543
|
+
eine Zeile zu opfern. Ohne diese Rücknahme wirkt die 1000er-Regel bis aufs Handy durch. */
|
|
1544
|
+
.card-featured-body>.card-text{-webkit-line-clamp:3;line-clamp:3}
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
/* ── Blockquote ── */
|
|
1548
|
+
.bq{padding:var(--s5) var(--s6);border-left:4px solid var(--bq-accent,var(--co-500));background:var(--bq-bg,var(--co-50));border-radius:var(--r-md);margin:0}
|
|
1549
|
+
.bq[data-area="co"]{--bq-accent:var(--co-500);--bq-bg:var(--co-50)}
|
|
1550
|
+
.bq[data-area="ki"]{--bq-accent:var(--ki-500);--bq-bg:var(--ki-50)}
|
|
1551
|
+
.bq[data-area="es"]{--bq-accent:var(--es-500);--bq-bg:var(--es-50)}
|
|
1552
|
+
.bq[data-area="wo"]{--bq-accent:var(--wo-500);--bq-bg:var(--wo-50)}
|
|
1553
|
+
/* fill:currentColor ist nötig, damit color (Bereichsakzent) den Glyph färbt — sonst SVG-Default schwarz. */
|
|
1554
|
+
.bq-icon{display:block;width:20px;height:20px;color:var(--bq-accent,var(--co-500));fill:currentColor;opacity:.35;margin-bottom:var(--s3)}
|
|
1555
|
+
.bq blockquote{font:var(--ty-serif-lg);color:var(--tx-primary);margin:0 0 var(--s3);quotes:none}
|
|
1556
|
+
.bq-caption{display:flex;flex-direction:column;gap:2px}
|
|
1557
|
+
.bq-name{font:var(--ty-name);color:var(--tx-primary)}
|
|
1558
|
+
.bq-role{font:var(--ty-body-xs);color:var(--tx-secondary);font-style:normal}
|
|
1559
|
+
|
|
1560
|
+
/* ── Testimonial Card ── */
|
|
1561
|
+
/* Statisch (Konvention „Elevation = Interaktivität“): flach mit --bd-strong-Rahmen + Top-Akzent, kein Schatten. */
|
|
1562
|
+
.testimonial{background:var(--bg-surface);border:var(--bd-strong);border-top:4px solid var(--t-accent,var(--co-500));border-radius:var(--r-lg);padding:var(--s6);margin:0;display:flex;flex-direction:column;gap:var(--s4)}
|
|
1563
|
+
.testimonial[data-area="co"]{--t-accent:var(--co-500)}
|
|
1564
|
+
.testimonial[data-area="ki"]{--t-accent:var(--ki-500)}
|
|
1565
|
+
.testimonial[data-area="es"]{--t-accent:var(--es-500)}
|
|
1566
|
+
.testimonial[data-area="wo"]{--t-accent:var(--wo-500)}
|
|
1567
|
+
.testimonial-icon{width:32px;height:32px;color:var(--t-accent,var(--co-500));fill:currentColor;opacity:.2;flex-shrink:0}
|
|
1568
|
+
.testimonial blockquote{font:var(--ty-serif-sm);color:var(--tx-primary);margin:0;quotes:none;flex:1}
|
|
1569
|
+
.testimonial-footer{display:flex;align-items:center;gap:var(--s3);padding-top:var(--s4);border-top:var(--bd);margin-top:auto}.testimonial-name{font:var(--ty-name);color:var(--tx-primary);margin:0}
|
|
1570
|
+
.testimonial-role{font:var(--ty-body-xs);color:var(--tx-secondary);margin:0;font-style:normal}
|
|
1571
|
+
/* Team-Stimmen: editoriale Reihen, Foto seitlich (abwechselnd L/R), fotostark für Repräsentation. Eigene Variante, lässt .testimonial unberührt. */
|
|
1572
|
+
.team-voices{display:flex;flex-direction:column;gap:var(--s6)}
|
|
1573
|
+
.team-voice{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);align-items:stretch;background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-lg);overflow:hidden}
|
|
1574
|
+
/* Bereichs-Rahmen: dieselben Stufen wie beim Bereichs-Chip, weil sie dort schon auf die
|
|
1575
|
+
3:1-Schwelle für grafische Objekte ausgelegt sind. Vorher -200 für alle vier, das trug auf Weiß
|
|
1576
|
+
nur 1,27:1 (ki) bis 2,03:1 (es), der Rahmen war als Bereichssignal nicht wahrnehmbar. Jetzt
|
|
1577
|
+
3,29:1 (co) bis 5,66:1 (es). Das Quote-Icon bleibt dekorativ (opacity .25), der Rahmen ist damit
|
|
1578
|
+
das tragende Farbsignal. Dark-Werte in dark-mode.css. */
|
|
1579
|
+
.team-voice[data-area="co"]{--t-accent:var(--co-500);border-color:var(--co-600)}
|
|
1580
|
+
.team-voice[data-area="ki"]{--t-accent:var(--ki-500);border-color:var(--ki-700)}
|
|
1581
|
+
.team-voice[data-area="es"]{--t-accent:var(--es-500);border-color:var(--es-500)}
|
|
1582
|
+
.team-voice[data-area="wo"]{--t-accent:var(--wo-500);border-color:var(--wo-500)}
|
|
1583
|
+
.team-voice-media{margin:0}
|
|
1584
|
+
.team-voice-media img{display:block;width:100%;height:100%;min-height:300px;object-fit:cover}
|
|
1585
|
+
.team-voice-body{padding:var(--s8);display:flex;flex-direction:column;gap:var(--s5);justify-content:center}
|
|
1586
|
+
.team-voice-icon{width:36px;height:36px;color:var(--t-accent,var(--co-500));fill:currentColor;opacity:.25;flex-shrink:0}
|
|
1587
|
+
.team-voice-quote{font:var(--ty-serif-md);color:var(--tx-primary);margin:0;quotes:none}
|
|
1588
|
+
.team-voice-footer{display:flex;flex-direction:column;gap:var(--s1)}
|
|
1589
|
+
.team-voice-name{font:var(--ty-name);color:var(--tx-primary);margin:0}
|
|
1590
|
+
.team-voice-role{font:var(--ty-body-sm);color:var(--tx-secondary);margin:0}
|
|
1591
|
+
.team-voice:nth-child(even){grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
|
|
1592
|
+
.team-voice:nth-child(even) .team-voice-media{grid-column:2;grid-row:1}
|
|
1593
|
+
.team-voice:nth-child(even) .team-voice-body{grid-column:1;grid-row:1}
|
|
1594
|
+
@media(max-width:768px){
|
|
1595
|
+
.team-voice,.team-voice:nth-child(even){grid-template-columns:1fr}
|
|
1596
|
+
.team-voice:nth-child(even) .team-voice-media{grid-column:1;grid-row:1}
|
|
1597
|
+
.team-voice:nth-child(even) .team-voice-body{grid-column:1;grid-row:2}
|
|
1598
|
+
/* Gestapelt verbraucht das Quote-Icon eine eigene Zeile + Gaps und frisst viel Höhe.
|
|
1599
|
+
Stattdessen Pull-Quote-Stil: 2-Spalten-Grid mit Icon im schmalen linken Gutter, Zitat
|
|
1600
|
+
und Footer rechts daneben/darunter ausgerichtet. Icon kleiner, Body-Padding reduziert. */
|
|
1601
|
+
.team-voice-body{display:grid;grid-template-columns:auto 1fr;align-items:start;column-gap:var(--s2);row-gap:var(--s3);padding:var(--s6)}
|
|
1602
|
+
.team-voice-icon{width:26px;height:26px;grid-column:1;grid-row:1;margin-top:2px}
|
|
1603
|
+
.team-voice-quote{grid-column:2;grid-row:1}
|
|
1604
|
+
.team-voice-footer{grid-column:2;grid-row:2}
|
|
1605
|
+
}
|
|
1606
|
+
/* Stat Card */
|
|
1607
|
+
/* Statisch (Konvention „Elevation = Interaktivität“): flach mit --bd-strong-Rahmen + Top-Akzent, kein Schatten. */
|
|
1608
|
+
.card-stat{background:var(--bg-surface);border:var(--bd-strong);border-top:4px solid var(--st-accent,var(--co-500));border-radius:var(--r-lg);padding:var(--s5) var(--s6);display:flex;flex-direction:column;gap:var(--s2)}
|
|
1609
|
+
.card-stat[data-area="co"]{--st-accent:var(--co-500)}
|
|
1610
|
+
.card-stat[data-area="ki"]{--st-accent:var(--ki-500)}
|
|
1611
|
+
.card-stat[data-area="es"]{--st-accent:var(--es-500)}
|
|
1612
|
+
.card-stat[data-area="wo"]{--st-accent:var(--wo-500)}
|
|
1613
|
+
.card-stat-value{font:var(--ty-display-md);color:var(--tx-primary);margin:0}
|
|
1614
|
+
.card-stat[data-area="co"] .card-stat-value{color:var(--co-700)}
|
|
1615
|
+
.card-stat[data-area="ki"] .card-stat-value{color:var(--ki-700)}
|
|
1616
|
+
.card-stat[data-area="es"] .card-stat-value{color:var(--es-700)}
|
|
1617
|
+
.card-stat[data-area="wo"] .card-stat-value{color:var(--wo-700)}
|
|
1618
|
+
.card-stat-label{font:var(--ty-body-md);color:var(--tx-secondary);margin:0}
|
|
1619
|
+
.card-stat-trend{display:inline-flex;align-items:center;gap:var(--s1);font:600 0.75rem/1rem var(--font);border-radius:var(--r-full);padding:2px var(--s2);margin-top:var(--s1)}
|
|
1620
|
+
.card-stat-trend.up{background:var(--c-success-bg);color:var(--badge-ok-text)}
|
|
1621
|
+
.card-stat-trend.down{background:var(--c-error-bg);color:var(--badge-err-text)}
|
|
1622
|
+
/* Stat-Strip — flache Bandstreifen-Variante (ohne Border, ohne Shadow) */
|
|
1623
|
+
.card-stat-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--s6);padding:var(--s10) var(--s8);background:var(--n-50);text-align:center}
|
|
1624
|
+
.card-stat-flat{display:flex;flex-direction:column;gap:var(--s1);align-items:center}
|
|
1625
|
+
.card-stat-flat-value{font:var(--ty-display-sm);color:var(--tx-primary);margin:0}
|
|
1626
|
+
.card-stat-flat[data-area="co"] .card-stat-flat-value{color:var(--co-700)}
|
|
1627
|
+
.card-stat-flat[data-area="ki"] .card-stat-flat-value{color:var(--ki-700)}
|
|
1628
|
+
.card-stat-flat[data-area="es"] .card-stat-flat-value{color:var(--es-700)}
|
|
1629
|
+
.card-stat-flat[data-area="wo"] .card-stat-flat-value{color:var(--wo-700)}
|
|
1630
|
+
.card-stat-flat-label{font:var(--ty-body-xs);color:var(--tx-secondary);margin:0}
|
|
1631
|
+
|
|
1632
|
+
/* ── Forms ── */
|
|
1633
|
+
.field{margin-bottom:var(--s6)}
|
|
1634
|
+
.field label{display:flex;align-items:center;gap:var(--s2);font:var(--ty-label-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary);margin-bottom:var(--s2)}
|
|
1635
|
+
.req{color:var(--c-error);font-size:0.875rem}
|
|
1636
|
+
.field input,.field textarea,.field select{width:100%;padding:var(--s3) var(--s4);font:var(--ty-body-md);color:var(--tx-primary);background:var(--bg-surface);border:2px solid var(--field-border);border-radius:var(--r-md);outline:none;transition:border-color var(--m-fast),box-shadow var(--m-fast);min-height:44px}
|
|
1637
|
+
.field select{appearance:none;-webkit-appearance:none;height:52px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%234A6565' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19.5 8.25l-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--s4) center;padding-right:var(--s10)}
|
|
1638
|
+
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--co-500);box-shadow:var(--focus-ring)}
|
|
1639
|
+
.field textarea{resize:vertical;max-width:100%}
|
|
1640
|
+
/* Placeholder explizit auf tx-secondary statt UA-Default. Chrome zeichnet Placeholder sonst mit
|
|
1641
|
+
rgb(117,117,117): im Dark sind das auf der Feldfüllung 2,8:1 und damit ein AA-Verstoß, im Light
|
|
1642
|
+
4,6:1 und damit knapp bestanden, aber ohne Reserve und vom Browser abhängig. Suchfeld,
|
|
1643
|
+
Footer-Newsletter, Combobox und Nav-Suche setzten das bereits, die Standard-Felder waren der
|
|
1644
|
+
Ausreißer. tx-secondary ist theme-aware und gemessen: Light 6,3:1, Dark 7,1:1. */
|
|
1645
|
+
.field input::placeholder,.field textarea::placeholder,
|
|
1646
|
+
[role="search"] input::placeholder{color:var(--tx-secondary)}
|
|
1647
|
+
.field.has-error input,.field.has-error select,.field.has-error textarea{border-color:var(--c-error)}
|
|
1648
|
+
/* Hilfetext unter einem Feld. --tx-secondary statt --tx-muted: Helper sitzt immer auf
|
|
1649
|
+
--bg-surface, dort erreicht --tx-muted im Dark Mode nur 4,1:1 und verfehlt AA für Kleintext
|
|
1650
|
+
(siehe Kontrast-Tabelle in der Doku). --tx-secondary liegt bei 6,3:1 Light / 4,9:1 Dark. */
|
|
1651
|
+
.helper{font:var(--ty-body-xs);color:var(--tx-secondary);margin-top:var(--s1)}
|
|
1652
|
+
.error-msg{font:var(--ty-label-sm);color:var(--c-error);margin-top:var(--s1);display:flex;align-items:center;gap:var(--s1)}
|
|
1653
|
+
|
|
1654
|
+
/* ── Buchungsformular ──
|
|
1655
|
+
Komposition aus .field-Feldern für verbindliche Buchungen (Seminartermin, Platzkontingent).
|
|
1656
|
+
Neu gegenüber der Standard-Form: Fieldset-Gliederung, bedingte Blöcke (hidden-Attribut, kein
|
|
1657
|
+
disabled), ein Teilnehmenden-Repeater und eine Live-Preiszeile. Bereichsfarbe kommt von außen
|
|
1658
|
+
(.btn-wo, accent-color), die Klassen selbst bleiben bereichsneutral. */
|
|
1659
|
+
.bk-fieldset{border:0;padding:0;margin:0 0 var(--s8);min-inline-size:0}
|
|
1660
|
+
/* Trennlinie nur zwischen den Gruppen oberster Ebene, nicht vor der ersten. Der Kindselektor ist
|
|
1661
|
+
wichtig: Untergruppen liegen innerhalb einer Gruppe und dürfen keine Linie bekommen, sonst
|
|
1662
|
+
trennt sie die Linie von der Entscheidung, zu der sie gehören. */
|
|
1663
|
+
[data-booking] > .bk-fieldset + .bk-fieldset{border-top:var(--bd);padding-top:var(--s8)}
|
|
1664
|
+
/* Untergruppe: gliedert innerhalb einer Gruppe (Radio-Gruppe, bedingter Block) und trägt deshalb
|
|
1665
|
+
ein Label auf Feldebene statt einer Überschrift. Kein Rahmen, keine Linie, nur Abstand. */
|
|
1666
|
+
.bk-subgroup{border:0;padding:0;margin:0 0 var(--s6);min-inline-size:0}
|
|
1667
|
+
.bk-subgroup[hidden]{display:none}
|
|
1668
|
+
.bk-subgroup:last-child{margin-bottom:0}
|
|
1669
|
+
/* Mittlere Stufe: 14 px halbfett, gemischte Schreibweise, --tx-primary. Damit sind drei Ebenen
|
|
1670
|
+
unterscheidbar (20 px Gruppe / 14 px Untergruppe / 12 px Versal-Feldlabel). Dieselben Versalien
|
|
1671
|
+
wie beim Feldlabel zu nehmen wäre derselbe Fehler wie vorher, nur eine Ebene tiefer. */
|
|
1672
|
+
.bk-sublegend{display:block;font:var(--ty-name);color:var(--tx-primary);padding:0;margin-bottom:var(--s3)}
|
|
1673
|
+
.bk-fieldset::after{content:"";display:block;clear:both}
|
|
1674
|
+
/* Gruppenüberschrift eine echte Stufe über dem Feldlabel: 20 px, gemischte Schreibweise,
|
|
1675
|
+
--tx-primary gegen 12 px Versalien in --tx-secondary. Vorher waren beide typografisch
|
|
1676
|
+
identisch, dadurch war die Fieldset-Gliederung semantisch da, aber optisch unsichtbar.
|
|
1677
|
+
float statt display:block, weil ein gefloatetes <legend> nicht mehr in die obere Rahmenkante
|
|
1678
|
+
gerendert wird und die Trennlinie deshalb durchgehend bleibt. */
|
|
1679
|
+
.bk-legend{float:left;width:100%;font:var(--ty-title-sm);color:var(--tx-primary);margin-bottom:var(--s4);padding:0}
|
|
1680
|
+
/* Ohne clear würde das erste Element der Gruppe neben dem 100 % breiten Float landen und sein
|
|
1681
|
+
Label auf null Breite gequetscht. Alle Geschwister, nicht nur das erste: der absolut positionierte Entfernen-Button steht
|
|
1682
|
+
dazwischen und nimmt kein clear an. */
|
|
1683
|
+
.bk-legend ~ *{clear:both}
|
|
1684
|
+
.bk-intro{font:var(--ty-body-sm);color:var(--tx-secondary);margin:calc(-1 * var(--s2)) 0 var(--s4)}
|
|
1685
|
+
/* Zweispalter, die auf Mobile einspaltig werden (der Inline-Zweispalter älterer Formulare tut das nicht). */
|
|
1686
|
+
.bk-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:0 var(--s4)}
|
|
1687
|
+
.bk-grid-plz{display:grid;grid-template-columns:minmax(96px,1fr) 2fr;gap:0 var(--s4)}
|
|
1688
|
+
/* Nur das Eingabefeld ist schmal, nicht der ganze .field-Wrapper: sonst würde die
|
|
1689
|
+
Fehlermeldung darunter in eine 140-px-Spalte gequetscht. */
|
|
1690
|
+
.bk-count input{max-width:140px}
|
|
1691
|
+
/* Teilnehmenden-Block: <fieldset> mit <legend>, damit Screenreader beim Betreten „Teilnehmende 3“
|
|
1692
|
+
ansagen und „Vorname“ nicht dreimal gleich klingt. Nur Rahmen, bewusst ohne eigene Fläche,
|
|
1693
|
+
sonst entsteht im Dark Mode eine dritte Flächenstufe über .bg-page < .bg-surface. */
|
|
1694
|
+
.bk-person{position:relative;border:var(--bd-strong);border-radius:var(--r-md);padding:var(--s5);margin-bottom:var(--s4);min-inline-size:0}
|
|
1695
|
+
.bk-person > .field:last-of-type{margin-bottom:0}
|
|
1696
|
+
.bk-person::after{content:"";display:block;clear:both}
|
|
1697
|
+
/* Wie .bk-legend gefloatet, damit die Legende in den Innenabstand rutscht statt in die
|
|
1698
|
+
Rahmenkante. Nur so liegt der Entfernen-Button auf einer Linie mit „Teilnehmende N“ und
|
|
1699
|
+
nicht neben dem ersten Feldlabel, wo er wie dessen Aktion aussieht. */
|
|
1700
|
+
.bk-person-title{float:left;width:100%;font:var(--ty-label-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary);padding:0;margin-bottom:var(--s4)}
|
|
1701
|
+
.bk-person-title ~ *{clear:both}
|
|
1702
|
+
/* Absolut positioniert, weil <legend> das erste Kind des Fieldsets bleiben muss und sich
|
|
1703
|
+
deshalb nicht mit dem Button in eine Flex-Zeile setzen lässt.
|
|
1704
|
+
Achtung: jede Autorenregel mit display schlägt das hidden-Attribut (hier .btn{display:inline-flex}),
|
|
1705
|
+
deshalb muss [hidden] explizit zurückgenommen werden. Gilt genauso für .bk-person-hint und
|
|
1706
|
+
.bk-success. Wer im DS mit hidden arbeitet, braucht diese Zeile. */
|
|
1707
|
+
.bk-person-remove{position:absolute;top:var(--s3);right:var(--s4)}
|
|
1708
|
+
.bk-person-remove[hidden]{display:none}
|
|
1709
|
+
.bk-person-hint{display:block;margin:0 0 var(--s4)}
|
|
1710
|
+
.bk-person-hint[hidden]{display:none}
|
|
1711
|
+
/* Fehlerübersicht am Formularkopf: Sprungliste statt einer Salve gleichzeitiger Alerts. */
|
|
1712
|
+
.bk-errors{border:2px solid var(--c-error);border-radius:var(--r-md);padding:var(--s5);margin-bottom:var(--s6)}
|
|
1713
|
+
.bk-errors[hidden]{display:none}
|
|
1714
|
+
.bk-errors:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
1715
|
+
.bk-errors-title{font:var(--ty-title-sm);color:var(--c-error);margin:0 0 var(--s3)}
|
|
1716
|
+
.bk-errors ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--s2)}
|
|
1717
|
+
.bk-errors a{font:var(--ty-body-md);color:var(--c-error);text-decoration:underline}
|
|
1718
|
+
.bk-errors a:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-xs)}
|
|
1719
|
+
.bk-summary{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s2);background:var(--bg-overlay);border-radius:var(--r-md);padding:var(--s4);margin-bottom:var(--s5);font:var(--ty-body-md);color:var(--tx-secondary)}
|
|
1720
|
+
.bk-summary-total{font:var(--ty-title-sm);color:var(--tx-primary)}
|
|
1721
|
+
/* Bestellübersicht unmittelbar vor dem zahlungspflichtigen Button: was gebucht wird, für wen,
|
|
1722
|
+
wie viele Plätze, Gesamtbetrag. Der bloße Betrag reicht hier nicht, die gebuchte Leistung steht
|
|
1723
|
+
sonst über tausend Pixel weiter oben verstreut. */
|
|
1724
|
+
/* Oben --s8: die Übersicht ist ein eigener Block und darf nicht am letzten Häkchen kleben.
|
|
1725
|
+
Das Bestätigungs-Häkchen darüber gibt nur --s4 mit, das reicht als Abstand nicht. */
|
|
1726
|
+
.bk-order{border:var(--bd-strong);border-radius:var(--r-md);background:var(--bg-overlay);padding:var(--s5);margin:var(--s8) 0 var(--s5)}
|
|
1727
|
+
.bk-order-title{font:var(--ty-name);color:var(--tx-primary);margin:0 0 var(--s4)}
|
|
1728
|
+
.bk-order-list{margin:0;display:flex;flex-direction:column;gap:var(--s2)}
|
|
1729
|
+
.bk-order-list > div{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:var(--s2)}
|
|
1730
|
+
.bk-order-list dt{font:var(--ty-body-sm);color:var(--tx-secondary)}
|
|
1731
|
+
.bk-order-list dd{margin:0;font:var(--ty-body-md);color:var(--tx-primary);text-align:right}
|
|
1732
|
+
/* Noch nicht ausgefüllte Zeile bleibt lesbar, tritt aber zurück. */
|
|
1733
|
+
.bk-order-list dd[data-empty]{color:var(--tx-secondary)}
|
|
1734
|
+
.bk-order-total{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s2);margin-top:var(--s4);padding-top:var(--s4);border-top:var(--bd)}
|
|
1735
|
+
.bk-order-total-label{font:var(--ty-body-md);color:var(--tx-secondary)}
|
|
1736
|
+
.bk-order-total-value{font:var(--ty-title-sm);color:var(--tx-primary)}
|
|
1737
|
+
.bk-order-note{font:var(--ty-body-xs);color:var(--tx-secondary);margin:var(--s1) 0 0;text-align:right}
|
|
1738
|
+
.bk-consent{display:flex;align-items:flex-start;gap:var(--s3);margin-bottom:var(--s4)}
|
|
1739
|
+
.bk-consent label{font:var(--ty-body-md);color:var(--tx-secondary);cursor:pointer}
|
|
1740
|
+
/* Freiwilliges Opt-in vom rechtlich erforderlichen Teil absetzen. Gleiche Optik direkt unter
|
|
1741
|
+
zwei Pflicht-Häkchen liest sich sonst wie ein Dark Pattern, auch wenn keines gemeint ist. */
|
|
1742
|
+
.bk-consent-optional{border-top:var(--bd);padding-top:var(--s4);margin-top:var(--s5)}
|
|
1743
|
+
.bk-success{display:flex;align-items:flex-start;gap:var(--s3);background:var(--c-success-bg);color:var(--c-success);border-radius:var(--r-md);padding:var(--s5)}
|
|
1744
|
+
/* display:flex würde das hidden-Attribut aushebeln, deshalb explizit zurücknehmen. */
|
|
1745
|
+
.bk-success[hidden]{display:none}
|
|
1746
|
+
.bk-success:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
1747
|
+
@media (max-width:768px){
|
|
1748
|
+
.bk-grid-2,.bk-grid-plz{grid-template-columns:1fr}
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
/* ── Dropdowns: Custom Select & Combobox ──
|
|
1752
|
+
Zwei Auswahl-Komponenten über das native <select> hinaus:
|
|
1753
|
+
.ep-select — gestylte Einzelauswahl mit Listbox-Popup, Häkchen, Bereichs-Akzent.
|
|
1754
|
+
.ep-combobox — Tipp-Filter über langen Listen; .is-multi ergänzt entfernbare Chips.
|
|
1755
|
+
Trigger spiegelt .field select (52 px, 2 px --field-border, --r-md); Popup spiegelt .ep-nav-sub
|
|
1756
|
+
(bg-surface, --e3, --bd, --r-md). Bereichs-Akzent über --sel-500/--sel-50 (Default = Corporate),
|
|
1757
|
+
per [data-area] auf ki/es/wo umschaltbar — wie Buttons/Chips. Der Akzent erscheint NUR im
|
|
1758
|
+
gewählten Eintrag (Häkchen + Tönung); Fokusring/Fokusrahmen bleiben neutral-Teal wie bei .field. */
|
|
1759
|
+
.ep-select,.ep-combobox{position:relative;margin-bottom:var(--s6);--sel-500:var(--co-700);--sel-50:var(--co-50)}
|
|
1760
|
+
.ep-select[data-area="ki"],.ep-combobox[data-area="ki"]{--sel-500:var(--ki-800);--sel-50:var(--ki-50)}
|
|
1761
|
+
.ep-select[data-area="es"],.ep-combobox[data-area="es"]{--sel-500:var(--es-700);--sel-50:var(--es-50)}
|
|
1762
|
+
.ep-select[data-area="wo"],.ep-combobox[data-area="wo"]{--sel-500:var(--wo-700);--sel-50:var(--wo-50)}
|
|
1763
|
+
|
|
1764
|
+
/* Label — identische Metriken wie .field label */
|
|
1765
|
+
.ep-select-label{display:flex;align-items:center;gap:var(--s2);font:var(--ty-label-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary);margin-bottom:var(--s2)}
|
|
1766
|
+
|
|
1767
|
+
/* Trigger (Select) / Control (Combobox) — spiegeln .field select */
|
|
1768
|
+
.ep-select-trigger,.ep-combobox-control{display:flex;align-items:center;gap:var(--s2);width:100%;min-height:52px;padding:var(--s3) var(--s4);font:var(--ty-body-md);color:var(--tx-primary);background:var(--bg-surface);border:2px solid var(--field-border);border-radius:var(--r-md);transition:border-color var(--m-fast),box-shadow var(--m-fast);text-align:left}
|
|
1769
|
+
.ep-select-trigger{justify-content:space-between;cursor:pointer}
|
|
1770
|
+
.ep-select-value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1771
|
+
/* Platzhalter (noch keine Auswahl): gedämpft wie .field-Placeholder, AA in beiden Modi */
|
|
1772
|
+
.ep-select-trigger.is-placeholder .ep-select-value{color:var(--tx-secondary)}
|
|
1773
|
+
.ep-select-caret{flex-shrink:0;width:24px;height:24px;color:var(--n-500);stroke:var(--n-500);transition:transform var(--m-fast)}
|
|
1774
|
+
.ep-select.is-open .ep-select-caret,.ep-combobox.is-open .ep-select-caret{transform:rotate(180deg)}
|
|
1775
|
+
|
|
1776
|
+
/* Combobox: textbares Feld im Control, ohne eigenen Rahmen. Chevron + Lösch-Button sind absolut
|
|
1777
|
+
und vertikal zentriert (s. u.), daher Platz rechts reservieren (--cb-pad-r). Bei Multi-Select
|
|
1778
|
+
umbricht das Control mehrzeilig — die absolute Position hält Chevron/Button trotzdem mittig. */
|
|
1779
|
+
.ep-combobox-control{position:relative;cursor:text;padding-right:var(--cb-pad-r,var(--s10))}
|
|
1780
|
+
.ep-combobox-control.has-clear{--cb-pad-r:calc(var(--s10) + var(--s8))} /* zusätzlich Platz für den Lösch-Button */
|
|
1781
|
+
.ep-combobox-input{flex:1;min-width:0;border:none;outline:none;background:none;font:var(--ty-body-md);color:var(--tx-primary);padding:0}
|
|
1782
|
+
.ep-combobox-input::placeholder{color:var(--tx-secondary)}
|
|
1783
|
+
/* Chevron absolut, vertikal zentriert über die volle Control-Höhe (Multi umbricht mehrzeilig) */
|
|
1784
|
+
.ep-combobox .ep-select-caret{position:absolute;right:var(--s4);top:50%;margin:0;transform:translateY(-50%);cursor:pointer}
|
|
1785
|
+
.ep-combobox.is-open .ep-select-caret{transform:translateY(-50%) rotate(180deg)}
|
|
1786
|
+
/* Lösch-Button: erscheint (per JS, [hidden] entfernt) sobald Text im Feld steht, leert es mit einem Klick.
|
|
1787
|
+
Ebenfalls absolut + vertikal zentriert, links vom Chevron. display:inline-flex (Autor-Regel) schlägt
|
|
1788
|
+
das UA-[hidden] → Ausblenden explizit wiederherstellen. */
|
|
1789
|
+
.ep-combobox-clear{position:absolute;right:var(--s10);top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:none;color:var(--tx-secondary);border-radius:var(--r-full);cursor:pointer;transition:background var(--m-fast),color var(--m-fast)}
|
|
1790
|
+
.ep-combobox-clear:hover{background:var(--bg-overlay);color:var(--tx-primary)}
|
|
1791
|
+
.ep-combobox-clear:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1792
|
+
.ep-combobox-clear[hidden]{display:none}
|
|
1793
|
+
|
|
1794
|
+
/* Fokus — neutral-Teal wie .field (Bereichsfarbe trägt nur der gewählte Eintrag) */
|
|
1795
|
+
.ep-select-trigger:focus-visible{outline:none;border-color:var(--co-500);box-shadow:var(--focus-ring)}
|
|
1796
|
+
.ep-combobox-control:focus-within{outline:none;border-color:var(--co-500);box-shadow:var(--focus-ring)}
|
|
1797
|
+
|
|
1798
|
+
/* Popup — gemeinsame Fläche für beide Komponenten, spiegelt .ep-nav-sub */
|
|
1799
|
+
.ep-select-menu,.ep-combobox-menu{position:absolute;top:calc(100% + var(--s1));left:0;right:0;z-index:20;display:none;flex-direction:column;gap:2px;max-height:288px;overflow-y:auto;margin:0;padding:var(--s2);list-style:none;background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-md);box-shadow:var(--e3)}
|
|
1800
|
+
.ep-select.is-open .ep-select-menu,.ep-combobox.is-open .ep-combobox-menu{display:flex}
|
|
1801
|
+
.ep-select-menu:focus,.ep-combobox-menu:focus{outline:none}
|
|
1802
|
+
|
|
1803
|
+
/* Option — Hover/Tastaturcursor + gewählter Zustand tragen den Bereichs-Akzent (wie .ep-nav-sub-btn) */
|
|
1804
|
+
.ep-select-option{display:flex;align-items:center;gap:var(--s2);padding:var(--s2) var(--s3);border-radius:var(--r-sm);font:var(--ty-body-md);color:var(--tx-primary);cursor:pointer;white-space:nowrap;transition:background var(--m-fast),color var(--m-fast)}
|
|
1805
|
+
/* display:flex (Autor-Regel) schlägt das UA-[hidden]{display:none} — daher das Ausblenden gefilterter
|
|
1806
|
+
bzw. bereits gewählter Optionen explizit wiederherstellen (Attribut-Selektor, höhere Spezifität). */
|
|
1807
|
+
.ep-select-option[hidden]{display:none}
|
|
1808
|
+
.ep-select-option:hover,.ep-select-option.is-active{background:var(--sel-50);color:var(--sel-500)}
|
|
1809
|
+
.ep-select-option[aria-selected="true"]{background:var(--sel-50);color:var(--sel-500);font-weight:600}
|
|
1810
|
+
/* Häkchen hält immer seinen Platz (Textbündigkeit), sichtbar nur im gewählten Eintrag */
|
|
1811
|
+
.ep-select-check{flex-shrink:0;width:20px;height:20px;color:var(--sel-500);stroke:var(--sel-500);opacity:0}
|
|
1812
|
+
.ep-select-option[aria-selected="true"] .ep-select-check{opacity:1}
|
|
1813
|
+
.ep-combobox-empty{padding:var(--s2) var(--s3);font:var(--ty-body-sm);color:var(--tx-muted)}
|
|
1814
|
+
|
|
1815
|
+
/* Multi-Select: gewählte Werte als entfernbare Chips im Control */
|
|
1816
|
+
.ep-combobox.is-multi .ep-combobox-control{flex-wrap:wrap;gap:var(--s1);padding:6px var(--cb-pad-r,var(--s10)) 6px var(--s3)}
|
|
1817
|
+
.ep-combobox.is-multi .ep-combobox-input{flex:1 0 80px;min-height:28px}
|
|
1818
|
+
.ep-combobox-token{display:inline-flex;align-items:center;gap:2px;padding:2px 2px 2px 10px;border-radius:var(--r-full);background:var(--sel-50);color:var(--sel-500);font:var(--ty-label-sm);max-width:100%}
|
|
1819
|
+
.ep-combobox-token-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1820
|
+
.ep-combobox-token-remove{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;flex-shrink:0;border:none;background:none;color:inherit;border-radius:var(--r-full);cursor:pointer;transition:background var(--m-fast)}
|
|
1821
|
+
.ep-combobox-token-remove:hover{background:color-mix(in srgb,var(--sel-500) 22%,transparent)}
|
|
1822
|
+
.ep-combobox-token-remove:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
1823
|
+
|
|
1824
|
+
/* Disabled */
|
|
1825
|
+
.ep-select.is-disabled .ep-select-trigger,.ep-combobox.is-disabled .ep-combobox-control{opacity:.5;cursor:not-allowed;pointer-events:none}
|
|
1826
|
+
|
|
1827
|
+
/* ── Typography specimens ── */
|
|
1828
|
+
.type-row{display:flex;align-items:baseline;gap:var(--s6);padding:var(--s4) 0;border-bottom:var(--bd)}
|
|
1829
|
+
.type-row:last-child{border-bottom:none}
|
|
1830
|
+
.type-meta{width:200px;flex-shrink:0;display:flex;flex-direction:column;gap:3px}
|
|
1831
|
+
.type-name{font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.07em;color:var(--tx-muted)}
|
|
1832
|
+
.type-spec{font:var(--ty-label-xs);color:var(--tx-muted);margin-top:2px}
|
|
1833
|
+
/* --co-ink statt co-600: co-600 trug auf Weiß nur 3,29:1 (Normaltext braucht 4,5:1). Das Ink-Token
|
|
1834
|
+
flippt mit dem Theme (Light co-700 5,52:1, Dark co-200 11,19:1); ein festes co-700 wäre im Dark
|
|
1835
|
+
mit 3,17:1 dunkel-auf-dunkel. */
|
|
1836
|
+
.type-rem{font:var(--ty-body-xs);color:var(--co-ink);margin-top:1px}
|
|
1837
|
+
.type-token{font:400 0.75rem/1rem var(--font-mono);color:var(--tx-muted);margin-top:2px;letter-spacing:-.01em}
|
|
1838
|
+
.type-sample{flex:1;color:var(--tx-primary)}
|
|
1839
|
+
|
|
1840
|
+
/* ── Spacing ── */
|
|
1841
|
+
.sp-item{display:flex;align-items:center;gap:var(--s4);padding:var(--s2) 0}
|
|
1842
|
+
.sp-bar{height:20px;background:var(--co-50);border:1px solid var(--co-500);border-radius:2px;flex-shrink:0}
|
|
1843
|
+
|
|
1844
|
+
/* ── Elevation ── */
|
|
1845
|
+
.el-card{background:var(--bg-surface);border-radius:var(--r-lg);padding:var(--s6);width:100%;text-align:center;font:var(--ty-body-md);color:var(--tx-secondary)}
|
|
1846
|
+
.el-lbl{font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.07em;color:var(--tx-muted);margin-bottom:var(--s2);display:block}
|
|
1847
|
+
|
|
1848
|
+
/* ── Nav demo ── */
|
|
1849
|
+
.nav-demo{background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--e1)}
|
|
1850
|
+
.doc-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--co-700);margin-bottom:var(--s3)}
|
|
1851
|
+
|
|
1852
|
+
/* ── Snackbar ── */
|
|
1853
|
+
.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
|
+
.snack-def{background:var(--n-700);color:var(--n-0)}
|
|
1855
|
+
.snack-ok{background:#0d5e39;color:#d6f5e8}
|
|
1856
|
+
.snack-err{background:#7a1515;color:#fde8e8}
|
|
1857
|
+
.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
|
+
|
|
1859
|
+
/* ── Footer ──
|
|
1860
|
+
Zwei-Band-Layout: heller Main-Bereich (.footer-main) + dunkler Bottom-Streifen (.footer-btm).
|
|
1861
|
+
Beide Bänder voll-breit; Inhalt jeweils auf 1280 px gedeckelt + zentriert
|
|
1862
|
+
(analog zum oberen Inhaltsbereich in .ep-page, components.css:454). */
|
|
1863
|
+
.footer{display:flex;flex-direction:column}
|
|
1864
|
+
|
|
1865
|
+
/* Main-Band: neutrales Hellgrau mit dunklem Text. --n-50 #F5F7F7 grenzt sich subtil von der weißen Page-bg ab. */
|
|
1866
|
+
.footer-main{background:var(--n-50);color:var(--tx-primary);padding-block:var(--s10);padding-inline:max(var(--s8), calc(50% - 640px))}
|
|
1867
|
+
|
|
1868
|
+
/* 3-Spalten-Grid: Brand+Kontakt | Wichtige Inhalte | Contentletter (etwas breiter für das Formular) */
|
|
1869
|
+
.footer-grid{display:grid;grid-template-columns:1.2fr 1fr 1.3fr;gap:var(--s10)}
|
|
1870
|
+
|
|
1871
|
+
/* Section-Headlines im Display-Serif. Gleicher Style für Brand, Nav-Header und Contentletter-Header. */
|
|
1872
|
+
/* Footer-Headlines auf Title Medium (sans 500, 18/26 px) — der Footer rückt damit visuell in den Hintergrund:
|
|
1873
|
+
keine editoriale Serifen-Prominenz mehr, sondern eine ruhige Utility-Typografie. */
|
|
1874
|
+
.footer-brand{font:var(--ty-title-sm);color:var(--tx-primary);margin:0 0 var(--s4)}
|
|
1875
|
+
.footer-htitle{font:var(--ty-title-sm);color:var(--tx-primary);margin:0 0 var(--s4);text-transform:none;letter-spacing:0}
|
|
1876
|
+
|
|
1877
|
+
.footer-nav-list{list-style:none;padding:0;margin:0}
|
|
1878
|
+
/* Inline-Links auf hellem Footer-bg. --tx-primary auf --n-50 ≈ 9.8:1 ✓ AAA. */
|
|
1879
|
+
.footer-link{font:var(--ty-body-md);color:var(--tx-primary);text-decoration:underline;text-underline-offset:3px;padding:0}
|
|
1880
|
+
.footer-link:hover{color:var(--co-700)}
|
|
1881
|
+
.footer-link:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:2px}
|
|
1882
|
+
/* In Nav-Listen: Block-Layout + vertikale Tap-Area. padding 6px 0 ≈ 32 px Tap-Area. */
|
|
1883
|
+
.footer-nav-list .footer-link{display:block;padding:6px 0}
|
|
1884
|
+
|
|
1885
|
+
/* Address-Block: semantisch <address>, Stack aus Adresse / Maps-Links / Telefon-Block. */
|
|
1886
|
+
.footer-address{font-style:normal;color:var(--tx-primary);margin:0}
|
|
1887
|
+
.footer-address p{font:var(--ty-body-md);margin:0 0 var(--s3)}
|
|
1888
|
+
.footer-address-maps{font:var(--ty-body-sm)}
|
|
1889
|
+
|
|
1890
|
+
/* Body-Link: Inline-Link im Fließtext (Querverweise zwischen Doku-Abschnitten).
|
|
1891
|
+
Light: --co-700 #007575 auf #fff = 5.53:1 ✓ AA. Dark-Override in dark-mode.css → --co-200. */
|
|
1892
|
+
.body-link{color:var(--co-700);text-decoration:underline;text-underline-offset:2px}
|
|
1893
|
+
.body-link:hover{color:var(--co-800)}
|
|
1894
|
+
.body-link:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:2px}
|
|
1895
|
+
/* Utility: Corporate-Brand-Text mit Dark-Override. */
|
|
1896
|
+
.t-co{color:var(--co-700)}
|
|
1897
|
+
/* Bereichs-Text-Utilities analog .t-co (Eyebrows, Labels, inline-Akzenttext); ki nutzt -800 (700 verfehlt AA). Dark-Overrides in dark-mode.css heben auf -200/-100. */
|
|
1898
|
+
.t-ki{color:var(--ki-800)}
|
|
1899
|
+
.t-es{color:var(--es-700)}
|
|
1900
|
+
.t-wo{color:var(--wo-700)}
|
|
1901
|
+
/* Bereichsgebundene Seiten und Blöcke können den co-Default-Akzent (.t-co an Icons, Bullets, Eyebrows)
|
|
1902
|
+
auf ihre Bereichsfarbe umstellen: data-accent am Seiten- oder Bereichs-Container. Nicht an .ep-page
|
|
1903
|
+
gebunden, damit auch ein einzelner Block (z.B. ein Buchungsformular in einer Sektion) den Scope
|
|
1904
|
+
aufspannen kann. ki nutzt -800 (700 verfehlt AA). */
|
|
1905
|
+
[data-accent="ki"] .t-co{color:var(--ki-800)}
|
|
1906
|
+
[data-accent="es"] .t-co{color:var(--es-700)}
|
|
1907
|
+
[data-accent="wo"] .t-co{color:var(--wo-700)}
|
|
1908
|
+
[data-accent="ki"] .body-link{color:var(--ki-800)}
|
|
1909
|
+
[data-accent="es"] .body-link{color:var(--es-700)}
|
|
1910
|
+
[data-accent="wo"] .body-link{color:var(--wo-700)}
|
|
1911
|
+
[data-accent="ki"] .body-link:hover{color:var(--ki-800)}
|
|
1912
|
+
[data-accent="es"] .body-link:hover{color:var(--es-800)}
|
|
1913
|
+
[data-accent="wo"] .body-link:hover{color:var(--wo-800)}
|
|
1914
|
+
/* Footer + Topnav bleiben Chrome (co), auch auf area-getönten Seiten: data-accent tönt nur den
|
|
1915
|
+
Seiteninhalt um, nicht die Navigation. Sonst wäre die aktive Sektion (.t-co am Nav-Toggle) z.B. auf
|
|
1916
|
+
einer wo-Seite grün statt Petrol — inkonsistent zur Nav aller anderen Seiten.
|
|
1917
|
+
Gleiche Spezifität wie die Akzent-Regeln darüber, gewinnen per Quellreihenfolge. */
|
|
1918
|
+
[data-accent] .footer .body-link{color:var(--co-700)}
|
|
1919
|
+
[data-accent] .footer .body-link:hover{color:var(--co-800)}
|
|
1920
|
+
[data-accent] .ep-topnav .t-co{color:var(--co-700)}
|
|
1921
|
+
|
|
1922
|
+
/* Bottom-Band: dunkler Streifen mit Copyright + Legal links und Social rechts. */
|
|
1923
|
+
.footer-btm{background:var(--n-700);color:var(--n-300);padding-block:var(--s4);padding-inline:max(var(--s8), calc(50% - 640px));display:flex;align-items:center;font:var(--ty-body-xs);flex-wrap:wrap;gap:var(--s2) var(--s5)}
|
|
1924
|
+
.footer-btm-link{color:var(--n-300);text-decoration:none;padding:6px 0}
|
|
1925
|
+
.footer-btm-link:hover{color:var(--n-200);text-decoration:underline}
|
|
1926
|
+
.footer-btm-link:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:2px}
|
|
1927
|
+
|
|
1928
|
+
/* Social-Icons rechtsbündig in der Bottom-Bar. Klick-Target 40x40 (WCAG 2.5.8 AAA), Icon 22x22 px. */
|
|
1929
|
+
.footer-social{display:flex;align-items:center;gap:var(--s2)}
|
|
1930
|
+
.footer-btm .footer-social{margin-left:auto}
|
|
1931
|
+
.footer-social a{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--r-sm);transition:background var(--m-fast)}
|
|
1932
|
+
.footer-social a:hover{background:rgba(255,255,255,.08)}
|
|
1933
|
+
.footer-social a:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-sm)}
|
|
1934
|
+
.footer-social img{max-width:22px;max-height:22px;object-fit:contain;display:block}
|
|
1935
|
+
|
|
1936
|
+
/* Contentletter-Form (3. Spalte). Sichtbare Labels über jedem Input (Ihr Name / Ihre E-Mail-Adresse).
|
|
1937
|
+
Consent vor Submit (DSGVO). Inputs auf weißem Background für ruhigen Kontrast im hellen Main-Band. */
|
|
1938
|
+
.footer-newsletter-desc{font:var(--ty-body-md);color:var(--tx-secondary);margin:0 0 var(--s5)}
|
|
1939
|
+
.footer-newsletter-form{display:flex;flex-direction:column}
|
|
1940
|
+
/* In flex-direction:column streckt der Default align-items:stretch jeden Block auf die volle Spaltenbreite.
|
|
1941
|
+
Inputs sollen das (width:100%), aber der Submit-Button soll auf seine natürliche Pill-Breite zurückfallen. */
|
|
1942
|
+
.footer-newsletter-form button[type="submit"]{align-self:flex-start}
|
|
1943
|
+
.footer-field{display:block;margin-bottom:var(--s4)}
|
|
1944
|
+
/* Label folgt der Form-Komponente: uppercase + letter-spacing, --ty-label-sm, --tx-secondary.
|
|
1945
|
+
So liest der Footer-Form identisch zu den Kontaktformularen (.field label) und unterscheidet
|
|
1946
|
+
sich klar von den Mixed-Case-Headlines (.footer-htitle), die in Title-sm sitzen. */
|
|
1947
|
+
.footer-field-label{display:block;font:var(--ty-label-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary);margin-bottom:var(--s2)}
|
|
1948
|
+
.footer-newsletter-form input[type="text"],
|
|
1949
|
+
.footer-newsletter-form input[type="email"]{display:block;width:100%;border:1px solid var(--field-border);background:var(--bg-surface);padding:0 var(--s3);height:44px;border-radius:var(--r-md);font:var(--ty-body-md);color:var(--tx-primary)}
|
|
1950
|
+
/* tx-secondary auf bg-surface = 6,28:1 ✓ AA (Light). tx-muted wäre 3,92:1, knapp unter AA. */
|
|
1951
|
+
.footer-newsletter-form input::placeholder{color:var(--tx-secondary)}
|
|
1952
|
+
/* Focus-Ring auf Token: var(--focus-ring) ist Dual-Shadow (--co-50 außen, --co-500 innen) und
|
|
1953
|
+
AA-konsistent mit allen anderen Form-Komponenten (.field, .footer-link, .footer-btm-link). */
|
|
1954
|
+
.footer-newsletter-form input:focus{outline:none;border-color:var(--co-500);box-shadow:var(--focus-ring)}
|
|
1955
|
+
/* Error-State, analog zu .field.has-error: --c-error-Border + Inline-Fehlertext mit Icon. */
|
|
1956
|
+
.footer-field.has-error input{border-color:var(--c-error)}
|
|
1957
|
+
.footer-field .error-msg{display:flex;gap:var(--s2);align-items:center;font:var(--ty-body-sm);color:var(--c-error);margin-top:var(--s2)}
|
|
1958
|
+
/* Consent als <label> mit Checkbox + Text — implizite Verknüpfung, keine IDs nötig (Footer in 10 Tabpanels). */
|
|
1959
|
+
.footer-newsletter-consent{display:flex;align-items:flex-start;gap:var(--s2);font:var(--ty-body-sm);color:var(--tx-secondary);cursor:pointer;margin-bottom:var(--s4)}
|
|
1960
|
+
.footer-newsletter-consent input[type="checkbox"]{width:16px;height:16px;margin-top:2px;accent-color:var(--co-500);flex-shrink:0;cursor:pointer}
|
|
1961
|
+
/* Konsistenter Focus-Ring (Cutout-Effekt) statt Browser-Default — passt zu Footer-Links und Submit-Button. */
|
|
1962
|
+
.footer-newsletter-consent input[type="checkbox"]:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:2px}
|
|
1963
|
+
|
|
1964
|
+
/* Mobile (< 768px): Footer-Grid stapelt einspaltig, Bottom-Bar bleibt Flex-Wrap.
|
|
1965
|
+
Padding-block etwas reduziert für kompakte Höhe auf Mobile. */
|
|
1966
|
+
@media (max-width: 768px) {
|
|
1967
|
+
.footer-grid{grid-template-columns:1fr;gap:var(--s8)}
|
|
1968
|
+
.footer-main{padding-block:var(--s8)}
|
|
1969
|
+
.footer-btm .footer-social{margin-left:0}
|
|
1970
|
+
}
|
|
1971
|
+
/* Tablet (769–1024px): Zwischenstufe für fix-spaltige Layouts, damit sie nicht direkt
|
|
1972
|
+
von voller Desktop-Breite auf 1-spaltig springen. Die auto-fit-Grids (.ep-cards,
|
|
1973
|
+
.a11y-grid, .card-stat-strip, .ep-tabs) regeln diesen Bereich bereits selbst — daher
|
|
1974
|
+
hier nur der 3-spaltige Footer auf 2 Spalten. */
|
|
1975
|
+
@media (min-width: 769px) and (max-width: 1024px) {
|
|
1976
|
+
.footer-grid{grid-template-columns:1fr 1fr;gap:var(--s8) var(--s10)}
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
/* ── A11y ── */
|
|
1980
|
+
.a11y-card{background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-lg);padding:var(--s5);margin-bottom:var(--s4)}
|
|
1981
|
+
.a11y-card h3{font:var(--ty-title-sm);margin-bottom:var(--s2)}
|
|
1982
|
+
.a11y-card p{font:var(--ty-body-md);color:var(--tx-secondary);margin-bottom:var(--s3)}
|
|
1983
|
+
.a11y-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s4);margin-bottom:var(--s4)}
|
|
1984
|
+
.a11y-grid .a11y-card{margin-bottom:0}
|
|
1985
|
+
.a11y-kbd{display:inline-block;background:var(--n-100);border:1px solid var(--n-300);border-radius:4px;padding:2px 7px;font-family:var(--font-mono);font-size:0.75rem;color:var(--tx-primary);box-shadow:0 1px 0 var(--n-300)}
|
|
1986
|
+
.a11y-table{width:100%;border-collapse:collapse;font:var(--ty-body-md);margin:var(--s3) 0}
|
|
1987
|
+
.a11y-table th{text-align:left;padding:var(--s2) var(--s3);background:var(--n-50);border-bottom:2px solid var(--n-200);font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary)}
|
|
1988
|
+
.a11y-table td{padding:var(--s2) var(--s3);border-bottom:var(--bd);vertical-align:top;line-height:1.5}
|
|
1989
|
+
.a11y-table tr:last-child td{border-bottom:none}
|
|
1990
|
+
.a11y-rule{display:flex;gap:var(--s3);align-items:flex-start;padding:var(--s3) 0;border-bottom:var(--bd)}
|
|
1991
|
+
.a11y-rule:last-child{border-bottom:none}
|
|
1992
|
+
.a11y-rule-icon{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:0.875rem;font-weight:700;flex-shrink:0;margin-top:1px}
|
|
1993
|
+
.a11y-ok .a11y-rule-icon{background:#E6F9F1;color:#0a5c38}
|
|
1994
|
+
.a11y-fail .a11y-rule-icon{background:#FDEAEA;color:#9b2020}
|
|
1995
|
+
.code-block{background:var(--bg-code);color:#c4e8b8;border-radius:var(--r-md);padding:var(--s4);font-family:var(--font-mono);font-size:0.8125rem;line-height:1.6;overflow-x:auto;margin:var(--s3) 0}
|
|
1996
|
+
.code-block .k{color:#79b8ff}.code-block .v{color:#00BEBE}.code-block .s{color:#f0c070}.code-block .c{color:#739373}/* Kommentarfarbe: #6a8a6a trug auf --bg-code nur 4,43:1 und verfehlte AA knapp. Farbton und Saettigung bleiben, nur heller: Light 4,99:1, Dark 5,84:1. */
|
|
1997
|
+
/* ── Code-Block Komponente (Wissensbeitrag) ── */
|
|
1998
|
+
.cb-wrap{border-radius:var(--r-sm);overflow:hidden;border:1px solid var(--n-200);margin:var(--s3) 0}
|
|
1999
|
+
.cb-header{display:flex;align-items:center;justify-content:space-between;padding:var(--s2) var(--s5);background:var(--n-100);border-bottom:1px solid var(--n-200)}
|
|
2000
|
+
.cb-lang{font:var(--ty-label-xs-strong);text-transform:uppercase;letter-spacing:.08em;color:var(--co-700)}
|
|
2001
|
+
.cb-copy{background:none;border:1px solid var(--n-200);border-radius:var(--r-xs);color:var(--n-500);font:var(--ty-label-xs);font-family:var(--font);padding:3px 10px;cursor:pointer;transition:background var(--m-fast),color var(--m-fast)}
|
|
2002
|
+
.cb-copy:hover{background:var(--n-200);color:var(--n-600)}
|
|
2003
|
+
.cb-copy:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
2004
|
+
.cb-body{background:var(--n-50);padding:var(--s5) var(--s6);overflow-x:auto;font-family:var(--font-mono);font-size:0.8125rem;line-height:1.7;color:var(--n-700);margin:0;white-space:pre}
|
|
2005
|
+
/* Semantisches <code> im <pre> (a11y): der Browser-Default (code{font-family:monospace})
|
|
2006
|
+
würde sonst eine andere Schrift als der Rest des Blocks zeigen, obwohl .cb-body die
|
|
2007
|
+
Schrift schon per var(--font-mono) setzt. font:inherit gleicht das exakt an. */
|
|
2008
|
+
.cb-body code{font:inherit}
|
|
2009
|
+
/* .cb-body ist jetzt per tabindex="0" fokussierbar (horizontales Scrollen per Tastatur).
|
|
2010
|
+
Der Ring sitzt auf .cb-wrap statt auf .cb-body selbst: .cb-wrap clippt per overflow:hidden
|
|
2011
|
+
die Ecken, ein box-shadow-Ring direkt auf .cb-body würde dort abgeschnitten. Gleiches
|
|
2012
|
+
:has()-Muster wie bei .seg weiter oben in dieser Datei. */
|
|
2013
|
+
.cb-body:focus-visible{outline:none}
|
|
2014
|
+
.cb-wrap:has(.cb-body:focus-visible){box-shadow:var(--focus-ring)}
|
|
2015
|
+
/* .c = Kommentar. Vorher n-400 (#6E8585), das auf dem n-50-Grund der Blöcke nur 3,65:1 trug.
|
|
2016
|
+
--tx-muted ist theme-aware und semantisch die gedämpfte Stufe: Light 4,51:1, Dark 8,9:1.
|
|
2017
|
+
Wer --tx-muted oder --n-50 anfasst, prüft diesen Wert mit, die Reserve ist knapp. */
|
|
2018
|
+
.cb-body .k{color:var(--es-600)}.cb-body .v{color:var(--co-700)}.cb-body .s{color:var(--wo-600)}.cb-body .c{color:var(--tx-muted)}.cb-body .fn{color:var(--ro-600)}
|
|
2019
|
+
/* Zeilennummern */
|
|
2020
|
+
.cb-body.cb-numbered{line-height:0}
|
|
2021
|
+
.cb-numbered .cb-ln{display:flex;gap:var(--s3);line-height:1.6}
|
|
2022
|
+
.cb-numbered .cb-ln::before{content:attr(data-n);color:var(--n-300);font-size:0.75rem;min-width:20px;text-align:right;flex-shrink:0;user-select:none}
|
|
2023
|
+
/* Terminal */
|
|
2024
|
+
.cb-terminal .cb-header{background:#080f08}
|
|
2025
|
+
.cb-terminal .cb-lang{color:#5CE8A0}
|
|
2026
|
+
.cb-terminal .cb-body{background:#0b110b;color:#b8d8b8}
|
|
2027
|
+
/* Die Terminal-Variante hat einen fest dunklen Grund in BEIDEN Modi. Der theme-aware --tx-muted
|
|
2028
|
+
der Standard-Blöcke liegt hier im Light bei 3,94:1 und verfehlt AA. Deshalb der nicht flippende
|
|
2029
|
+
n-400 (4,87:1 in beiden Modi). Heute steht in keinem Terminal-Block ein Kommentar, die Regel
|
|
2030
|
+
verhindert, dass die Kombination später still durchfällt. */
|
|
2031
|
+
.cb-terminal .cb-body .c{color:var(--n-400)}
|
|
2032
|
+
.cb-terminal .cb-prompt{color:#5CE8A0;user-select:none}
|
|
2033
|
+
/* Deckkraft .65, nicht .55: auf dem Terminal-Grund trug .55 nur 4,20:1, .65 gibt 5,07:1.
|
|
2034
|
+
Die Ausgabe bleibt damit sichtbar gedämpft gegenüber dem Prompt, erfüllt aber AA. */
|
|
2035
|
+
.cb-terminal .cb-out{color:rgba(180,210,180,.65)}
|
|
2036
|
+
/* Kopier-Button im Terminal: der neutrale n-500 der hellen Variante trägt auf dem dunklen
|
|
2037
|
+
Terminal-Header nur 3,09:1. n-200 gibt 12,70:1 und passt zur hellen Schrift daneben. */
|
|
2038
|
+
.cb-terminal .cb-copy{color:var(--n-200)}
|
|
2039
|
+
/* Inline code in Fließtext */
|
|
2040
|
+
.cb-prose code{font-family:var(--font-mono);font-size:.875em;background:var(--co-50);color:var(--co-700);padding:2px 6px;border-radius:var(--r-xs);border:1px solid var(--co-100)}
|
|
2041
|
+
.contrast-row{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) 0;border-bottom:var(--bd);flex-wrap:wrap}
|
|
2042
|
+
.contrast-row:last-child{border-bottom:none}
|
|
2043
|
+
/* Keine Doppellinie: folgt direkt eine Gruppen-Überschrift (mit eigenem border-top als Trenner),
|
|
2044
|
+
lässt die letzte Zeile ihre Unterlinie weg — sonst stehen zwei parallele Linien untereinander. */
|
|
2045
|
+
.contrast-row:has(+ .group-title){border-bottom:none}
|
|
2046
|
+
.cswatch{width:48px;height:48px;border-radius:var(--r-md);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:0.875rem}
|
|
2047
|
+
.cinfo{flex:1;min-width:160px}
|
|
2048
|
+
.cname{font:var(--ty-label-md)}
|
|
2049
|
+
.cratio{font-size:0.8125rem;color:var(--tx-secondary);font-family:var(--font-mono)}
|
|
2050
|
+
.cbadge{display:inline-flex;align-items:center;padding:3px var(--s2);border-radius:var(--r-full);font:var(--ty-label-xs)}
|
|
2051
|
+
.c-aa{background:var(--cbadge-aa-bg);color:var(--cbadge-aa-text)}
|
|
2052
|
+
.c-aaa{background:var(--cbadge-aaa-bg);color:var(--cbadge-aaa-text)}
|
|
2053
|
+
.c-fail-badge{background:var(--cbadge-fail-bg);color:var(--cbadge-fail-text)}
|
|
2054
|
+
/* Modus-Pill für Kontrast-Zeilen. Macht explizit, ob ein Kontrast-Wert sich auf Light, Dark oder beide Themes bezieht.
|
|
2055
|
+
Neutral gestaltet (Border statt Fill), damit das WCAG-Badge daneben optisch dominiert. */
|
|
2056
|
+
.a11y-mode{display:inline-flex;align-items:center;padding:1px 7px;border-radius:var(--r-full);font:var(--ty-label-xs);letter-spacing:.04em;border:var(--bd);background:transparent;color:var(--tx-secondary);margin-right:var(--s2);vertical-align:middle;white-space:nowrap}
|
|
2057
|
+
|
|
2058
|
+
/* ── Slider ── */
|
|
2059
|
+
.field-slider{display:flex;flex-direction:column;gap:var(--s2);--sl-thumb:22px}
|
|
2060
|
+
.field-slider-header{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s2)}
|
|
2061
|
+
.field-slider-label{font:var(--ty-label-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary)}
|
|
2062
|
+
.field-slider-output{font:600 0.875rem/1.25rem var(--font);color:var(--sl-text,var(--co-700));min-width:56px;text-align:right}
|
|
2063
|
+
/* Ticks exakt auf die Thumb-Position ausgerichtet: der Thumb-Mittelpunkt läuft von
|
|
2064
|
+
--sl-thumb/2 bis (Breite − --sl-thumb/2). Jeder Tick trägt --tick-p (0..1) als
|
|
2065
|
+
Bruchteil des Wertebereichs und wird über seiner Mitte zentriert. (Früher
|
|
2066
|
+
justify-content:space-between → Label-Mitten trafen die Positionen nicht.) */
|
|
2067
|
+
.field-slider-ticks{position:relative;height:16px;font:var(--ty-caption);color:var(--tx-muted)}
|
|
2068
|
+
.field-slider-ticks>*{position:absolute;transform:translateX(-50%);white-space:nowrap;left:calc(var(--sl-thumb) / 2 + var(--tick-p, 0) * (100% - var(--sl-thumb)))}
|
|
2069
|
+
.slider{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:var(--r-full);background:var(--n-200);outline:none;cursor:pointer;display:block;margin:var(--s3) 0 var(--s1)}
|
|
2070
|
+
.slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:var(--sl-thumb);height:var(--sl-thumb);border-radius:50%;background:var(--sl-color,var(--co-500));border:3px solid var(--bg-surface);box-shadow:var(--e2);cursor:pointer;transition:transform var(--m-fast),box-shadow var(--m-fast)}
|
|
2071
|
+
.slider::-moz-range-thumb{width:var(--sl-thumb);height:var(--sl-thumb);border-radius:50%;background:var(--sl-color,var(--co-500));border:3px solid var(--bg-surface);box-shadow:var(--e2);cursor:pointer;transition:transform var(--m-fast),box-shadow var(--m-fast);box-sizing:border-box}
|
|
2072
|
+
.slider:hover:not(:disabled)::-webkit-slider-thumb{transform:scale(1.2);box-shadow:var(--e3)}
|
|
2073
|
+
.slider:hover:not(:disabled)::-moz-range-thumb{transform:scale(1.2);box-shadow:var(--e3)}
|
|
2074
|
+
.slider:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2075
|
+
.slider:disabled{opacity:.38;cursor:not-allowed}
|
|
2076
|
+
/* --sl-color = Thumb (helle Markenfarbe, grafisch: 3:1 genügt) · --sl-text = Wert-Anzeige
|
|
2077
|
+
(Normaltext 14px/600 → 4,5:1 nötig, daher dunklere Töne; -500 fiel bis 2,3:1 durch, WCAG 1.4.3) */
|
|
2078
|
+
.slider-co{--sl-color:var(--co-500);--sl-text:var(--co-700)} /* co-700 #007575 = 5,5:1 */
|
|
2079
|
+
.slider-ki{--sl-color:var(--ki-700);--sl-text:var(--ki-800)} /* ki-800 #475705 = 8,0:1 (ki-700 nur 4,35:1) */
|
|
2080
|
+
.slider-es{--sl-color:var(--es-500);--sl-text:var(--es-700)} /* es-700 #1B3D9A = 9,6:1 */
|
|
2081
|
+
.slider-wo{--sl-color:var(--wo-500);--sl-text:var(--wo-700)} /* wo-700 #285E1A = 7,8:1 (wo-500 nur 3,3:1) */
|
|
2082
|
+
|
|
2083
|
+
/* ── Bild-Slider (Carousel) ── */
|
|
2084
|
+
/* Basis: Crossfade — alle Slides als Grid-Items in derselben Zelle übereinander gestapelt; aktive Slide trägt .active und ist sichtbar */
|
|
2085
|
+
.img-slider{position:relative;border-radius:var(--r-lg);overflow:hidden;user-select:none}
|
|
2086
|
+
.img-slider-track{display:grid;grid-template-columns:1fr;grid-template-rows:1fr}
|
|
2087
|
+
.img-slide{grid-column:1/-1;grid-row:1/-1;opacity:0;transition:opacity 600ms ease;pointer-events:none}
|
|
2088
|
+
.img-slide.active{opacity:1;pointer-events:auto}
|
|
2089
|
+
.img-slide-media{width:100%;aspect-ratio:16/9;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--n-100)}
|
|
2090
|
+
.img-slide-media img{width:100%;height:100%;object-fit:cover;display:block}
|
|
2091
|
+
.img-slide-caption{padding:var(--s4) var(--s6);background:var(--bg-surface);border-top:var(--bd);min-height:112px;overflow:hidden}
|
|
2092
|
+
.img-slide-caption-title{font:var(--ty-serif-md);color:var(--tx-primary);margin:0 0 var(--s1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
2093
|
+
.img-slide-caption-text{font:var(--ty-body-md);color:var(--tx-secondary);margin:0;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
|
2094
|
+
.img-slider-btn{position:absolute;top:calc(50% - 28px);transform:translateY(-50%);width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.9);backdrop-filter:blur(4px);border:none;box-shadow:var(--e2);display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:2;transition:background var(--m-fast),box-shadow var(--m-fast);color:#333E48}/* Kreis ist in beiden Modi fest weiß → Chevron fest dunkel (nicht tx-primary, das im Dark auf hell flippt → hell-auf-weiß) */
|
|
2095
|
+
.img-slider-btn:hover{background:#fff;box-shadow:var(--e3)}
|
|
2096
|
+
.img-slider-btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2097
|
+
.img-slider-prev{left:var(--s4)}
|
|
2098
|
+
.img-slider-next{right:var(--s4)}
|
|
2099
|
+
.img-slider-dots{display:flex;justify-content:center;padding:var(--s4) 0;background:var(--bg-surface);position:relative;z-index:2}
|
|
2100
|
+
/* Dot-Pattern: 24×24 Hit-Area (WCAG 2.5.5 AA) + 12×12 sichtbarer Punkt via ::before, gap:0 */
|
|
2101
|
+
.img-dot{width:24px;height:24px;border-radius:50%;border:none;background:transparent;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}
|
|
2102
|
+
.img-dot::before{content:'';width:12px;height:12px;border-radius:50%;background:var(--n-200);transition:background var(--m-fast),transform var(--m-fast)}
|
|
2103
|
+
.img-dot:hover::before{background:var(--n-400)}
|
|
2104
|
+
.img-dot.active::before{background:var(--co-500);transform:scale(1.25)}
|
|
2105
|
+
.img-dot:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:50%}
|
|
2106
|
+
/* Hero-Variante — vollflächig, 21:9-Format, Caption als Overlay über dem Bild */
|
|
2107
|
+
.img-slider-hero{border-radius:0}
|
|
2108
|
+
.img-slider-hero .img-slider-track{aspect-ratio:21/9;min-height:300px;max-height:clamp(480px,75vh,900px)}
|
|
2109
|
+
.img-slider-hero .img-slide-media{height:100%;aspect-ratio:auto;min-height:0}
|
|
2110
|
+
.img-slider-hero .img-slide-caption{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(to top,rgba(0,0,0,.72) 0%,transparent 100%);border-top:none;padding:var(--s10) var(--s8) var(--s10);height:auto;overflow:visible}
|
|
2111
|
+
.img-slider-hero .img-slide-caption-title{color:#fff;font-size:clamp(1.25rem, 0.943rem + 1.36vw, 2rem);line-height:1.25}
|
|
2112
|
+
.img-slider-hero .img-slide-caption-text{color:rgba(255,255,255,.8);height:auto;overflow:visible}
|
|
2113
|
+
.img-slider-hero .img-slider-btn{top:50%}
|
|
2114
|
+
.img-slider-hero .img-slider-dots{position:absolute;bottom:var(--s4);left:0;right:0;background:none;border:none;padding:0}
|
|
2115
|
+
.img-slider-hero .img-dot::before{background:rgba(255,255,255,.35)}
|
|
2116
|
+
.img-slider-hero .img-dot.active::before{background:#fff}
|
|
2117
|
+
|
|
2118
|
+
/* ── Hero-Image (statische Variante der Slider-Hero, ohne Track/Buttons/Dots) ── */
|
|
2119
|
+
.hero-image{position:relative;overflow:hidden;margin:0}
|
|
2120
|
+
.hero-image-media{width:100%;aspect-ratio:21/9;min-height:300px;max-height:clamp(480px,75vh,900px);overflow:hidden;background:var(--n-100);display:flex;align-items:center;justify-content:center}
|
|
2121
|
+
.hero-image-media img{width:100%;height:100%;object-fit:cover;display:block}
|
|
2122
|
+
/* Scrim über dem Hero-Foto. Zwei Anforderungen, die sich gegenseitig begrenzen:
|
|
2123
|
+
|
|
2124
|
+
(1) KONTRAST. Der Eyebrow ist das erste Kind und sitzt damit im obersten, schwächsten Abschnitt
|
|
2125
|
+
des Verlaufs. Mit dem früheren Verlauf (.85 / .65 bei 50% / transparent) stand er dort auf Alpha
|
|
2126
|
+
0,30: über einer ausgebrannt hellen Bildstelle sind das 1,90:1, gemessen lagen bis zu 63% der
|
|
2127
|
+
Eyebrow-Fläche unter 4,5:1. Der text-shadow hilft optisch, zählt für WCAG nicht.
|
|
2128
|
+
|
|
2129
|
+
(2) KEINE SICHTBARE KANTE. Ein Verlauf wird nicht dort auffällig, wo er steil ist, sondern dort,
|
|
2130
|
+
wo seine Steilheit springt. Entscheidend ist die Rate, mit der die Deckkraft an der OBERKANTE
|
|
2131
|
+
einsetzt. Gemessen am gerenderten Bild (zweite Ableitung der Zeilenhelligkeit, über die Breite
|
|
2132
|
+
gemittelt): früherer Verlauf 7,9. Ein Zwischenstand, der die Deckkraft auf kurzer Strecke aufbaute,
|
|
2133
|
+
kam auf 21 bis 25 und zeichnete eine sichtbare Linie quer durchs Bild, unabhängig davon, wie viele
|
|
2134
|
+
Stützstellen er hatte. Mehr Stops helfen also nicht.
|
|
2135
|
+
|
|
2136
|
+
Was hilft, ist eine längere Auslaufstrecke: die Deckkraft muss über genügend Pixel von 0 auf ihren
|
|
2137
|
+
Wert kommen. Der Text endet 132px über der Unterkante; mit 96px Polsterung darüber ist der Kasten
|
|
2138
|
+
228px hoch, der Eyebrow sitzt bei 58%, und der Auslauf läuft mit 0,0066 pro Pixel, also etwas
|
|
2139
|
+
sanfter als beim früheren Verlauf (0,0076). Gemessene Kantigkeit 9,2 gegenüber 7,9. Deckkraft am
|
|
2140
|
+
Eyebrow 0,63 statt 0,30.
|
|
2141
|
+
|
|
2142
|
+
Die Polsterung ist fluide, weil 96px auf einem 300px hohen Mobil-Hero zu viel wären. */
|
|
2143
|
+
.hero-image-caption{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(to top,rgba(0,0,0,.85) 0%,rgba(0,0,0,.63) 58%,transparent 100%);padding:clamp(var(--s10), 6.7vw, calc(var(--s16) + var(--s8))) var(--s8) var(--s10);margin:0}
|
|
2144
|
+
.hero-image-caption-eyebrow{font:var(--ty-label-xs);letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.85);margin:0 0 var(--s2);text-shadow:0 1px 2px rgba(0,0,0,.5)}
|
|
2145
|
+
.hero-image-caption-title{font:var(--ty-serif-md);color:#fff;font-size:clamp(1.25rem, 0.943rem + 1.36vw, 2rem);line-height:1.25;margin:0 0 var(--s1);text-shadow:0 1px 3px rgba(0,0,0,.4)}
|
|
2146
|
+
.hero-image-caption-text{font:var(--ty-body-md);color:rgba(255,255,255,.92);margin:0;text-shadow:0 1px 2px rgba(0,0,0,.5)}
|
|
2147
|
+
|
|
2148
|
+
/* ── Störer (Hero-Overlay, Startseite) ──
|
|
2149
|
+
Kompakte Verweiskacheln auf je einen aktuellen Inhalt: nächste Veranstaltung, neuer
|
|
2150
|
+
Wissensbeitrag, Pressemitteilung, Info (neue Seminar-Landingpage, neues Produkt). Ein bis
|
|
2151
|
+
drei Kacheln als Set oben rechts über dem Hero-Bild, Default sind zwei. Der Wrapper
|
|
2152
|
+
.stoerer-hero umschließt Hero + Set und spannt den Positionsrahmen auf; .hero-image bleibt
|
|
2153
|
+
unangetastet und funktioniert weiter ohne Störer.
|
|
2154
|
+
|
|
2155
|
+
VIER ENTSCHEIDUNGEN, DIE ABSICHT SIND
|
|
2156
|
+
|
|
2157
|
+
(1) EINE FARBE FÜR ALLE VIER TYPEN. Der Inhaltstyp steht im Label und im Icon, nicht in der
|
|
2158
|
+
Fläche. Vier Bereichsfarben nebeneinander würden gegeneinander und gegen die Hero-Headline
|
|
2159
|
+
arbeiten; die Kacheln sind ein Set und müssen als eines lesen. Der Akzent ist deshalb
|
|
2160
|
+
durchgehend Corporate (--co-ink), wie bei der Topnav: der Störer ist Chrome über dem Bild,
|
|
2161
|
+
kein Bereichsinhalt. Aus demselben Grund gibt es hier kein data-area.
|
|
2162
|
+
|
|
2163
|
+
(2) DECKENDE FLÄCHE, KEIN GLAS. Über einem Foto ist der Grund unbekannt: eine
|
|
2164
|
+
halbtransparente Kachel trägt je nach Bildstelle 2:1 oder 12:1, und keine Regel kann das
|
|
2165
|
+
absichern (der Grund steht nicht in der Elternkette, `npm run check:contrast` zählt solchen
|
|
2166
|
+
Text nur, statt ihn zu werten). Auf --bg-surface steht der Text dagegen auf einer bekannten
|
|
2167
|
+
Fläche: Light 5,52 bis 10,90:1, Dark 8,32 bis 10,48:1. Das Bild bleibt sichtbar, weil die
|
|
2168
|
+
Kacheln klein sind, nicht weil sie durchscheinen.
|
|
2169
|
+
|
|
2170
|
+
(3) RAHMEN IN BEIDEN MODI. Karten im DS verlassen sich im Light auf --e1 und bekommen erst
|
|
2171
|
+
im Dark einen Rahmen (CONTRIBUTING §5). Hier liegt die Kachel aber auf einem Foto statt auf
|
|
2172
|
+
einer bekannten Fläche: auf einer ausgebrannt hellen Bildstelle trägt der schwarze Schatten
|
|
2173
|
+
nichts mehr, und die weiße Kachel hat dort keine Kante. Deshalb --bd-strong schon im Light.
|
|
2174
|
+
|
|
2175
|
+
(4) OVERLAY NACH HERO-BREITE, NICHT NACH VIEWPORT-BREITE. Bei 21:9 gilt Hero-Höhe = Breite
|
|
2176
|
+
× 9/21 (der max-height-Deckel liegt bei mindestens 480px und greift hier nie). Eine Kachel ist
|
|
2177
|
+
126px hoch (12px Polsterung, 100px Inhalt, 1px Rand je Seite), drei Kacheln plus zwei Abstände
|
|
2178
|
+
und 24px Rand oben brauchen 426px Hero-Höhe, also 994px Hero-Breite. Ob die vorhanden ist, sagt
|
|
2179
|
+
die Breite des Heros und nicht die des Fensters: mit einer Media Query auf 1025px ragte ein
|
|
2180
|
+
Dreier-Set in der Doku-Vorschau (Hero 898px im 1200px-Fenster) 41px in die Sub-Sektion. Die
|
|
2181
|
+
Entscheidung hängt deshalb an einer Container-Query auf .stoerer-hero. Darunter steht das Set
|
|
2182
|
+
als normaler Block unter dem Hero; eine Kachel, die halb in die Sub-Sektion ragt, ist kein
|
|
2183
|
+
Overlay mehr, sondern ein Unfall. Die Schwelle liegt bei 1025px, dem Desktop-Tier der
|
|
2184
|
+
Responsive-Strategie, und damit über dem Rechenwert von 994px. Ohne Container-Query-Support
|
|
2185
|
+
greift die Regel nicht und das Set bleibt in jeder Breite ein Block unter dem Hero, also der
|
|
2186
|
+
funktionierende Fall.
|
|
2187
|
+
|
|
2188
|
+
MASSE IN REM, NICHT PX (WCAG 1.4.4). Die Schwelle stand zuerst als 1025px da und skalierte damit
|
|
2189
|
+
nicht mit der Browser-Standardschriftgröße: bei 200% Textgröße wuchs die Kachel von 126 auf 290px,
|
|
2190
|
+
das Overlay blieb aber an und ragte gemessen 96px in die Sub-Sektion. In rem (64,0625rem = 1025px
|
|
2191
|
+
bei Default-Wurzel) wandert die Schwelle mit: bei 200% verlangt sie 2050px Hero-Breite, das Set
|
|
2192
|
+
fällt also in den Block-Zweig, statt kaputt zu überlappen. Dieselbe Rechnung gilt für die
|
|
2193
|
+
Kachelbreite (22,5rem) und das Grid-Minimum (16,25rem). */
|
|
2194
|
+
.stoerer-hero{position:relative;container-type:inline-size;--stoerer-w:22.5rem}
|
|
2195
|
+
.stoerer-set{padding:var(--s8)}
|
|
2196
|
+
.ep-page .stoerer-set{padding-inline:max(var(--s8),calc(50% - 640px))}
|
|
2197
|
+
/* Mobil derselbe Innenabstand wie .ep-section: 32 → 24px. Im Block-Zweig steht das Set in der
|
|
2198
|
+
Sektionslogik der Seite, nicht mehr als Overlay, und folgt deshalb deren Rhythmus. */
|
|
2199
|
+
@media(max-width:768px){
|
|
2200
|
+
.stoerer-set,.ep-page .stoerer-set{padding-inline:var(--s6)}
|
|
2201
|
+
}
|
|
2202
|
+
/* min(16.25rem,100%) statt 16.25rem als Boden: bei 320px Viewport (WCAG 1.4.10 Reflow) ist der
|
|
2203
|
+
Grund nur 256px breit, ein starrer 260px-Boden ragte dort in die Polsterung. Mit min() weicht die
|
|
2204
|
+
Spalte auf 100% aus, statt den Grund zu sprengen. */
|
|
2205
|
+
.stoerer-list{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(16.25rem,100%),1fr));gap:var(--s3)}
|
|
2206
|
+
/* Die Kachel IST der klickbare Bereich, trägt also Elevation (CONTRIBUTING §4). Eine Spalte:
|
|
2207
|
+
Thema, Titel, Meta. Das Typ-Glyph sitzt IM Thema-Label, nicht in einer eigenen Spalte rechts.
|
|
2208
|
+
|
|
2209
|
+
WARUM NICHT RECHTS, MIT TRENNER
|
|
2210
|
+
Material trennt die Slots einer Listenzeile nach Aufgabe: das Leading-Element „represents the
|
|
2211
|
+
item's subject or category“, das Trailing-Element trägt „secondary information, actions, or status
|
|
2212
|
+
indicators“. Unser Glyph ist ein reiner Typ-Marker, also eine Kategorie, und gehört damit nach
|
|
2213
|
+
vorn. Rechts hinter einer Trennlinie stand es im Slot für Aktionen und Status, auf einer
|
|
2214
|
+
vollständig klickbaren Kachel also doppeldeutig: es kann als Button lesen.
|
|
2215
|
+
NN/g ergänzt die andere Richtung: „a text label must be present alongside an icon to clarify its
|
|
2216
|
+
meaning“. Die Bedeutung trägt das Label, das Glyph ist Wiedererkennungshilfe, und die wirkt am
|
|
2217
|
+
besten direkt neben dem Wort, das sie doppelt.
|
|
2218
|
+
Messbarer Nebengewinn: ohne Icon-Spalte (24px Glyph + 16px Polsterung + 1px Trenner + 16px
|
|
2219
|
+
Spaltenabstand = 57px) wächst die Textspalte von 269 auf 326px, also um 21%. Damit klammern die
|
|
2220
|
+
realistischen Titel der Startseite nicht mehr. Die Kachelhöhe bleibt bei 126px, weil das 16px-Glyph
|
|
2221
|
+
in die 16px hohe Label-Zeile passt.
|
|
2222
|
+
Preis: das Glyph wird stiller (16px statt 24px, Stroke micro statt sm). Das ist vertretbar, weil es
|
|
2223
|
+
aria-hidden ist und nichts trägt, was das Label nicht schon sagt. Wer einen kräftigen Typ-Marker
|
|
2224
|
+
braucht, setzt ihn ins Leading, oben auf Label-Höhe, nicht zurück nach rechts. */
|
|
2225
|
+
.stoerer{display:flex;flex-direction:column;gap:var(--s1);padding:var(--s3) var(--s4);border-radius:var(--r-md);background:var(--bg-surface);border:var(--bd-strong);box-shadow:var(--e1);text-decoration:none;color:inherit;transition:box-shadow var(--m-fast),transform var(--m-fast),background var(--m-fast)}
|
|
2226
|
+
.stoerer:hover{background:var(--bg-surface-hover);box-shadow:var(--e3);transform:translateY(-2px)}
|
|
2227
|
+
/* Zweites Hover-Signal, das nicht an Farbe oder Schatten hängt: über einem Foto ist der
|
|
2228
|
+
Schatten-Zuwachs je nach Bildstelle kaum zu sehen, die Unterstreichung immer. */
|
|
2229
|
+
.stoerer:hover .stoerer-title>*{text-decoration:underline;text-underline-offset:2px}
|
|
2230
|
+
.stoerer:focus-visible{outline:none;box-shadow:var(--focus-ring),var(--e3)}
|
|
2231
|
+
/* Thema-Zeile trägt das Glyph als Leading-Element. align-items:center stimmt optisch, solange das
|
|
2232
|
+
Label einzeilig bleibt, und das ist die Regel (ein bis drei Wörter). */
|
|
2233
|
+
.stoerer-topic{display:flex;align-items:center;gap:var(--s2);font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;color:var(--co-ink)}
|
|
2234
|
+
/* Zwei Zeilen fest: min-height reserviert die Höhe, das innere Element kappt längere Titel per
|
|
2235
|
+
line-clamp mit Auslassungszeichen. Beides zusammen hält alle Kacheln eines Sets auf gleicher
|
|
2236
|
+
Höhe, unabhängig von der Titellänge im CMS (dieselbe Mechanik wie .card-title). */
|
|
2237
|
+
.stoerer-title{font:var(--ty-title-sm);color:var(--tx-primary);min-height:2lh}
|
|
2238
|
+
.stoerer-title>*{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
|
|
2239
|
+
.stoerer-meta{font:var(--ty-body-sm);color:var(--tx-secondary)}
|
|
2240
|
+
/* 16px = Micro auf der Icon-Skala, dort gehört Stroke 1 dazu (24px trüge 1.25). Farbe erbt das
|
|
2241
|
+
Glyph vom Thema-Label über currentColor, es braucht keine eigene. */
|
|
2242
|
+
.stoerer-icon{width:16px;height:16px;flex-shrink:0;stroke-width:var(--icon-stroke-micro)}
|
|
2243
|
+
|
|
2244
|
+
@container (min-width:64.0625rem){
|
|
2245
|
+
/* Overlay oben rechts: die Caption liegt unten links, die Sub-Sektion darunter, oben rechts
|
|
2246
|
+
ist die freie Zone. Der Abstand liegt in top/right statt im Padding, sonst wächst die
|
|
2247
|
+
absolut positionierte Box über die Kachelbreite hinaus. */
|
|
2248
|
+
.stoerer-set,.ep-page .stoerer-set{position:absolute;top:var(--s6);right:var(--s8);padding:0}
|
|
2249
|
+
.ep-page .stoerer-set{right:max(var(--s8),calc(50% - 640px))}
|
|
2250
|
+
.stoerer-list{display:flex;flex-direction:column;width:var(--stoerer-w)}
|
|
2251
|
+
/* Die Caption-Spalte endet vor den Kacheln, sonst läuft eine lange Headline darunter.
|
|
2252
|
+
max-width auf die Kinder, nicht Padding auf die Caption: der Gradient bleibt vollbreit.
|
|
2253
|
+
Der .stoerer-hero-Präfix bleibt stehen, obwohl derzeit nur .stoerer-hero ein Container ist:
|
|
2254
|
+
sonst greift die Regel auf jeden Hero, sobald irgendein Vorfahre ein Container wird. */
|
|
2255
|
+
.stoerer-hero .hero-image-caption>*{max-width:calc(100% - var(--stoerer-w) - var(--s6))}
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
@media(prefers-reduced-motion:reduce){.img-slide{transition:none}}
|
|
2259
|
+
|
|
2260
|
+
/* ── Logo-Tiles (geteilt vom Logo-Karussell) ── */
|
|
2261
|
+
/* Logos sitzen randlos auf der weißen Platte (.logo-carousel) — keine Einzel-Box, kein Hover-Lift:
|
|
2262
|
+
Logos sind nicht klickbar, ein Lift wäre falsche Interaktions-Andeutung („Elevation = Interaktivität“).
|
|
2263
|
+
Einheitliche, großzügige Logo-Höhe (100px) statt der alten 72px-Kachel mit nur ~48px nutzbarer Höhe. */
|
|
2264
|
+
.logo-tile{flex-shrink:0;display:flex;align-items:center;justify-content:center;padding:var(--s2) var(--s4)}
|
|
2265
|
+
.logo-tile img{max-height:100px;max-width:100%;width:auto;height:auto;object-fit:contain}
|
|
2266
|
+
.logo-placeholder{font:700 1rem/1.2 var(--font);letter-spacing:.04em;color:var(--n-500);text-align:center;user-select:none}
|
|
2267
|
+
|
|
2268
|
+
/* ── Logo-Carousel: diskrete Sets von 5 Logos, automatischer Crossfade, pausierbar ── */
|
|
2269
|
+
/* Helle Platte in BEIDEN Modi: Kundenlogos liegen oft farbig oder dunkel vor und haben keine
|
|
2270
|
+
Dark-Variante, auf theme-reaktivem Grund würden sie im Dark unsichtbar. Die Platte bleibt also
|
|
2271
|
+
hell, wird im Dark aber über --bg-plate gedämpft (#E8EDED statt #FFFFFF): eine reinweiße Fläche
|
|
2272
|
+
dieser Größe stünde mit 17,51:1 gegen die Seite und blendet. Dunkle Logos darauf 14,73:1. */
|
|
2273
|
+
.logo-carousel{position:relative;background:var(--bg-plate);border:var(--bd-strong);border-radius:var(--r-lg);padding:var(--s8) var(--s6)}
|
|
2274
|
+
.logo-carousel-track{position:relative;display:grid;align-items:center;min-height:124px}
|
|
2275
|
+
.logo-carousel-slide{grid-row:1;grid-column:1;display:grid;grid-template-columns:repeat(5,1fr);gap:var(--s5);opacity:0;transition:opacity .5s ease;pointer-events:none}
|
|
2276
|
+
.logo-carousel-slide[aria-hidden="false"]{opacity:1;pointer-events:auto}
|
|
2277
|
+
.logo-carousel .logo-tile{width:auto;min-width:0}
|
|
2278
|
+
.logo-carousel-dots{display:flex;justify-content:center;margin-top:var(--s5)}
|
|
2279
|
+
/* Identischer Pattern wie .img-dot: 24×24 Hit-Area + 12×12 sichtbarer Punkt, gap:0 */
|
|
2280
|
+
.logo-carousel-dot{width:24px;height:24px;border-radius:50%;border:none;background:transparent;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}
|
|
2281
|
+
.logo-carousel-dot::before{content:'';width:12px;height:12px;border-radius:50%;background:var(--n-200);transition:background var(--m-fast),transform var(--m-fast)}
|
|
2282
|
+
.logo-carousel-dot:hover::before{background:var(--n-400)}
|
|
2283
|
+
.logo-carousel-dot[aria-selected="true"]::before{background:var(--co-500);transform:scale(1.25)}
|
|
2284
|
+
.logo-carousel-dot:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:50%}
|
|
2285
|
+
.logo-carousel-pause{position:absolute;top:var(--s2);right:var(--s2);z-index:2;background:var(--bg-surface);border:var(--bd);border-radius:var(--r-full);width:32px;height:32px;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:var(--e1);transition:box-shadow var(--m-fast),opacity var(--m-fast);opacity:0;color:var(--n-500)}
|
|
2286
|
+
.logo-carousel:hover .logo-carousel-pause,.logo-carousel:focus-within .logo-carousel-pause{opacity:1}
|
|
2287
|
+
.logo-carousel.paused .logo-carousel-pause{opacity:1}
|
|
2288
|
+
.logo-carousel-pause:hover{color:var(--n-700);box-shadow:var(--e2)}
|
|
2289
|
+
.logo-carousel-pause:focus-visible{outline:none;box-shadow:var(--focus-ring);opacity:1}
|
|
2290
|
+
.logo-carousel-pause .icon-play{display:none}
|
|
2291
|
+
.logo-carousel.paused .logo-carousel-pause .icon-pause{display:none}
|
|
2292
|
+
.logo-carousel.paused .logo-carousel-pause .icon-play{display:block}
|
|
2293
|
+
/* Reduced Motion: Transition aus, Autoplay wird per JS deaktiviert */
|
|
2294
|
+
@media(prefers-reduced-motion:reduce){.logo-carousel-slide{transition:none}}
|
|
2295
|
+
|
|
2296
|
+
/* ── Grid ── */
|
|
2297
|
+
.grid-vis{border:var(--bd-strong);border-radius:var(--r-md);overflow:hidden}
|
|
2298
|
+
.grid-12{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--s3);padding:var(--s3);background:var(--bg-overlay)}
|
|
2299
|
+
.gcol{border-radius:var(--r-xs);padding:var(--s3);background:var(--co-50);border:1px solid var(--co-500);font:var(--ty-label-xs);color:var(--co-700);text-align:center}
|
|
2300
|
+
|
|
2301
|
+
/* ── Token ── */
|
|
2302
|
+
/* Die Token-Blöcke tragen ihre Überschrift als .group-title wie jede andere Doku-Sektion,
|
|
2303
|
+
damit sie in der Sub-Navigation erscheinen und die Heading-Ebene nicht überspringen. */
|
|
2304
|
+
.token-section{margin-bottom:var(--s8)}
|
|
2305
|
+
.ico-48{width:48px;height:48px}
|
|
2306
|
+
|
|
2307
|
+
/* ── Example Pages ── */
|
|
2308
|
+
/* Beispielseiten-Auswahl: nach IA gruppiert (Allgemein/Leistungen/Wissen/Unternehmen/Veranstaltungen),
|
|
2309
|
+
je Gruppe eine dezente Label-Zeile über den Pills. Gekürzte Pill-Labels (voller Name via aria-label). */
|
|
2310
|
+
/* Alle Gruppen als Spalten nebeneinander (füllt die Breite, hält die Leiste flach);
|
|
2311
|
+
klappt auf schmalen Screens automatisch auf weniger Spalten um. */
|
|
2312
|
+
.ep-tabs{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--s6) var(--s8);align-items:start;margin-bottom:var(--s8)}
|
|
2313
|
+
.ep-tab-group{display:flex;flex-direction:column;gap:var(--s3)}
|
|
2314
|
+
.ep-tab-group-label{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;color:var(--tx-secondary)}
|
|
2315
|
+
.ep-tab-group-row{display:flex;gap:var(--s2);flex-wrap:wrap}
|
|
2316
|
+
/* min-height 44px = Touch-Target AAA (WCAG 2.5.5), analog zu .btn; border via --field-border
|
|
2317
|
+
(modusabhängig, ≥ 3:1 für die Bedienelement-Kontur nach WCAG 1.4.11: light #6E8585 = 3,9:1,
|
|
2318
|
+
dark #C9D3D3 = 5,8:1 — das feste --n-200 fiel im Light-Mode auf 1,5:1 durch). */
|
|
2319
|
+
.ep-tab{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:7px var(--s4);border-radius:var(--r-full);border:1px solid var(--field-border);font:var(--ty-label-sm);cursor:pointer;background:var(--bg-surface);color:var(--tx-secondary);transition:all var(--m-fast)}
|
|
2320
|
+
.ep-tab:hover{background:var(--bg-overlay);color:var(--tx-primary);border-color:var(--field-border)}
|
|
2321
|
+
.ep-tab:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2322
|
+
/* Aktiv: gefüllt mit co-700 (nicht co-500), damit weißer Text AA erreicht (#fff auf
|
|
2323
|
+
co-700 = 5,52:1; auf dem hellen co-500 wären es nur 2,3:1). Spiegelt .btn-filled/.btn-co. */
|
|
2324
|
+
.ep-tab.active{background:var(--co-700);color:#fff;border-color:var(--co-700);box-shadow:var(--e1)}
|
|
2325
|
+
.ep-tab.active:hover{background:var(--co-700);color:#fff;border-color:var(--co-700)}
|
|
2326
|
+
/* Hierarchie in einer Gruppe (Leistungen, Unternehmen): Oberpunkte stapeln untereinander,
|
|
2327
|
+
Unterpunkte eingerückt mit dezenter Leitlinie (wie ein Nav-Baum). */
|
|
2328
|
+
.ep-tab-group-row.is-tree{flex-direction:column;align-items:flex-start}
|
|
2329
|
+
.ep-tab-node{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s2)}
|
|
2330
|
+
.ep-tab-parent{display:flex;align-items:center;gap:var(--s2)}
|
|
2331
|
+
.ep-tab-toggle{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;flex-shrink:0;border-radius:var(--r-full);border:1px solid var(--field-border);background:var(--bg-surface);color:var(--tx-secondary);cursor:pointer;padding:0;transition:all var(--m-fast)}
|
|
2332
|
+
.ep-tab-toggle:hover{background:var(--bg-overlay);color:var(--tx-primary);border-color:var(--field-border)}
|
|
2333
|
+
.ep-tab-toggle:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2334
|
+
.ep-tab-toggle-caret{width:14px;height:14px;transition:transform var(--m-fast)}
|
|
2335
|
+
.ep-tab-node.is-open .ep-tab-toggle-caret{transform:rotate(180deg)}
|
|
2336
|
+
/* Unterpunkte standardmäßig eingeklappt, per Toggle (.is-open) aufklappbar */
|
|
2337
|
+
.ep-tab-children{display:none;flex-wrap:wrap;gap:var(--s2);margin-left:var(--s4);padding-left:var(--s4);border-left:1px solid var(--n-200)}
|
|
2338
|
+
.ep-tab-node.is-open > .ep-tab-children{display:flex}
|
|
2339
|
+
/* position:relative, damit .skip-link (position:absolute) sich am ep-Page-Frame orientiert
|
|
2340
|
+
und nicht außerhalb der Preview-Karte erscheint. overflow:hidden clipped die negative
|
|
2341
|
+
top-Position im Default — Skip-Link ist also unsichtbar bis Focus, dann poppt er rein. */
|
|
2342
|
+
.ep-page{display:none;border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--e3);border:var(--bd-strong);position:relative}
|
|
2343
|
+
.ep-page.visible{display:block}
|
|
2344
|
+
/* Beispielseiten nutzen die volle verfügbare Breite bis zum rechten Fensterrand (kein 1280/1500-Deckel):
|
|
2345
|
+
.ds-content ist flex:1 und füllt Fensterbreite − Sidebar. Der Karten-Rahmen (.ep-page: Radius/Schatten)
|
|
2346
|
+
und der Außenabstand (.ds-content padding --s6) bleiben; der Seiteninhalt bleibt über das Content-Gutter
|
|
2347
|
+
(padding-inline: max(--s8, calc(50% − 640px)), s.u.) in einer zentrierten 1280-Lesespalte, Hero/Bänder
|
|
2348
|
+
laufen full-bleed über die Kartenbreite. */
|
|
2349
|
+
/* Breite an data-section (vom Inline-Head-Script vor dem Paint gesetzt) — verhindert den Layout-Sprung,
|
|
2350
|
+
den :has() allein verursacht (greift erst, wenn JS die Sektion nach dem Paint sichtbar macht).
|
|
2351
|
+
:has bleibt als Laufzeit-Backup für Wechsel, die nicht über activateSection laufen. */
|
|
2352
|
+
html[data-section="examples"] .ds-content,
|
|
2353
|
+
.ds-content:has(#sec-examples.visible){max-width:none}
|
|
2354
|
+
/* Inhalt der Sektionen folgt aber dem 1280px-Spec — Hintergründe bleiben volle Panel-Breite,
|
|
2355
|
+
Content wird über fluides Inline-Padding zentriert (kein zusätzlicher Wrapper nötig). */
|
|
2356
|
+
.ep-page .ep-topnav,
|
|
2357
|
+
.ep-page .ep-section,
|
|
2358
|
+
.ep-page .card-stat-strip,
|
|
2359
|
+
.ep-page .ep-cta-band,
|
|
2360
|
+
.ep-page .ep-media-band,
|
|
2361
|
+
.ep-page .hero-image-caption{padding-inline:max(var(--s8), calc(50% - 640px))}
|
|
2362
|
+
/* Akzent-Bänder: gerundete Ecken wie Karten & übrige Bilder (r-lg). Radius aufs <img>, da das
|
|
2363
|
+
<figure> durch das Content-Gutter-Padding breiter ist als das sichtbare Bild. */
|
|
2364
|
+
.ep-page .ep-media-band img{border-radius:var(--r-lg)}
|
|
2365
|
+
/* .footer hat eigene Bänder (.footer-main/.footer-btm) mit eigenem padding-inline.
|
|
2366
|
+
Auf .footer hier kein Padding setzen — sonst doppelte Einrückung und der Background-Streifen
|
|
2367
|
+
reicht nicht bis zur .ep-page-Kante. */
|
|
2368
|
+
.ep-topnav{display:flex;align-items:center;padding:var(--s4) var(--s8);background:var(--bg-surface);border-bottom:var(--bd);gap:var(--s8);flex-wrap:wrap}
|
|
2369
|
+
/* Kontakt-Button (letztes Direct-Child) wird nach rechts gedrückt; Nav hängt direkt am Logo */
|
|
2370
|
+
.ep-topnav > :last-child{margin-left:auto}
|
|
2371
|
+
.ep-logo{font:500 1.5rem/2rem var(--font);letter-spacing:.03em;flex-shrink:0;display:flex;align-items:center;color:inherit;text-decoration:none;border-radius:var(--r-xs)}
|
|
2372
|
+
a.ep-logo{cursor:pointer}
|
|
2373
|
+
a.ep-logo:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2374
|
+
.ep-logo img{display:block;height:24px;width:auto}
|
|
2375
|
+
/* Theme-aware logo swap: default für hellen, light für dunklen Hintergrund.
|
|
2376
|
+
img.-Präfix (Element+Klasse, 0,1,1) ist nötig: .ep-logo img{display:block} (0,1,1) schlägt sonst
|
|
2377
|
+
die reine .logo-themed-light-Klasse (0,1,0) → im Light bliebe das WEISSE Logo sichtbar (weiß-auf-weiß
|
|
2378
|
+
unsichtbar, belegte aber ~Logobreite und schob .ep-nav-links nach rechts). Dark-Regeln (0,2,1) gewinnen. */
|
|
2379
|
+
img.logo-themed-light{display:none}
|
|
2380
|
+
[data-theme="dark"] img.logo-themed-default{display:none}
|
|
2381
|
+
[data-theme="dark"] img.logo-themed-light{display:block}
|
|
2382
|
+
.ep-nav-links{display:flex;gap:var(--s6);font:var(--ty-label-md);align-items:center}
|
|
2383
|
+
/* Top-Level-Links: Akzent-Unterstrich bei Hover/aktiv (statt Opacity-Fade). Der aktive Zustand
|
|
2384
|
+
ist nicht nur farbig (co-700), sondern zusätzlich durch den Unterstrich markiert (kein
|
|
2385
|
+
reiner Farb-Indikator → WCAG 1.4.1). */
|
|
2386
|
+
.ep-nav-btn{position:relative;background:none;border:none;cursor:pointer;font:inherit;color:inherit;padding:0;text-decoration:none;transition:color var(--m-fast)}
|
|
2387
|
+
.ep-nav-btn:link,.ep-nav-btn:visited{color:inherit;text-decoration:none}
|
|
2388
|
+
/* Aktiv-Unterstrich: co-700 statt co-500 → 5,52:1 auf weiß (WCAG 1.4.11 ≥3:1; co-500 lag bei 2,31:1).
|
|
2389
|
+
Dark-Override auf co-200 in dark-mode.css. Farbe spiegelt die Aktiv-Textfarbe. */
|
|
2390
|
+
.ep-nav-btn::after{content:"";position:absolute;left:0;right:0;bottom:-6px;height:2px;border-radius:1px;background:var(--co-700);opacity:0;transition:opacity var(--m-fast)}
|
|
2391
|
+
/* Unterstrich (::after) = ausschließlich Aktiv-Indikator (aria-current). Hover/Öffnen markieren nur
|
|
2392
|
+
über Petrol-Farbe (+ Caret-Dreh beim Toggle), damit das Aufklapp-Menü nicht an der Linie klebt. */
|
|
2393
|
+
.ep-nav-btn:hover{color:var(--co-700)}
|
|
2394
|
+
.ep-nav-btn:focus-visible{outline:none;box-shadow:var(--focus-aa);border-radius:2px}
|
|
2395
|
+
.ep-nav-btn[aria-current="page"]{color:var(--co-700)}
|
|
2396
|
+
.ep-nav-btn[aria-current="page"]::after{opacity:1}
|
|
2397
|
+
/* Aktive Sektion: trägt das Submenü die aktive Seite, bekommt der Parent-LINK denselben Unterstrich —
|
|
2398
|
+
nicht-farblicher Indikator (WCAG 1.4.1), damit die aktive Sektion nicht nur über Petrol-Farbe hängt.
|
|
2399
|
+
(Der Unterstrich sitzt am .ep-nav-btn-Link, nicht am Caret-Button — dieser hat kein ::after.) */
|
|
2400
|
+
.ep-nav-has-sub:has(.ep-nav-sub-btn[aria-current="page"]) .ep-nav-btn::after{opacity:1}
|
|
2401
|
+
/* Submenü unter "Leistungen"/"Unternehmen" — Hover/Focus-Within zeigt die Einträge */
|
|
2402
|
+
.ep-nav-item{position:relative;display:inline-flex;align-items:center;gap:var(--s1)}
|
|
2403
|
+
/* Caret-Disclosure-Button: nur der Pfeil (das Label ist der separate .ep-nav-btn-Link daneben).
|
|
2404
|
+
Eigene Hit-Area ≥24×24 (WCAG 2.5.8) + eigener Fokus-Ring, da nicht mehr Teil des Link-Buttons. */
|
|
2405
|
+
.ep-nav-item-toggle{font:inherit;color:inherit;background:none;border:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;min-width:24px;min-height:24px;padding:0 4px;border-radius:var(--r-sm);line-height:1}
|
|
2406
|
+
.ep-nav-item-toggle:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
2407
|
+
.ep-nav-item-caret{width:10px;height:10px;display:inline-block;color:currentColor;opacity:.6;transition:transform var(--m-fast)}
|
|
2408
|
+
/* Disclosure-Menü (.is-open ↔ aria-expanded, via main.js): Öffnen schließt offene Geschwister
|
|
2409
|
+
(closeAllNavItems), Escape/Außenklick schließen. Reveal keift ausschließlich an .is-open (nie an
|
|
2410
|
+
reinem CSS-:hover), damit aria-expanded mitläuft und nie zwei Menüs gleichzeitig offen sind.
|
|
2411
|
+
Geöffnet wird per Klick/Tap, Tastatur ODER — nur auf pointer:fine — per Hover (JS-gesteuert, mit
|
|
2412
|
+
Intent-Delay). Beim Öffnen färbt sich der Toggle Petrol und der Caret dreht; Hover gibt schon vorab
|
|
2413
|
+
die Petrol-Färbung als Affordanz. KEIN Unterstrich (bleibt der aktiven Seite vorbehalten). */
|
|
2414
|
+
.ep-nav-has-sub:hover .ep-nav-item-toggle,.ep-nav-has-sub.is-open .ep-nav-item-toggle{color:var(--co-700)}
|
|
2415
|
+
.ep-nav-has-sub.is-open .ep-nav-item-caret{transform:rotate(180deg)}
|
|
2416
|
+
.ep-nav-sub{display:none;position:absolute;top:calc(100% + var(--s4));left:0;background:var(--bg-surface);box-shadow:var(--e3);border:var(--bd-strong);border-radius:var(--r-md);padding:var(--s2);min-width:240px;flex-direction:column;gap:2px;z-index:10}
|
|
2417
|
+
.ep-nav-has-sub.is-open .ep-nav-sub{display:flex}
|
|
2418
|
+
/* Unsichtbare Hover-Brücke über den Gap (top:100% + s4): hält den Zeiger beim Weg vom Caret ins
|
|
2419
|
+
Flyout im Item, damit mouseleave nicht zu früh feuert (WCAG 1.4.13 „hoverable“). Nur pointer:fine
|
|
2420
|
+
und nur solange offen — mobil ist .ep-nav-sub statisch, dort keine Brücke. */
|
|
2421
|
+
@media (hover:hover) and (pointer:fine){
|
|
2422
|
+
.ep-nav-has-sub.is-open .ep-nav-sub::before{content:"";position:absolute;left:0;right:0;top:calc(-1*var(--s4));height:var(--s4)}
|
|
2423
|
+
}
|
|
2424
|
+
/* Sub-Items: gleiche Größe wie Top-Level (label-md), kein Umbruch, markenfarbiger Hover.
|
|
2425
|
+
Aktiver Eintrag mit Tönungsfläche + co-700 + Fettung (Fläche/Fettung = nicht-farbige Indikatoren). */
|
|
2426
|
+
.ep-nav-sub-btn{padding:var(--s2) var(--s4);border-radius:var(--r-sm);text-decoration:none;color:var(--tx-primary);font:var(--ty-label-md);white-space:nowrap;transition:background var(--m-fast),color var(--m-fast)}
|
|
2427
|
+
.ep-nav-sub-btn:hover{background:var(--co-50);color:var(--co-700)}
|
|
2428
|
+
.ep-nav-sub-btn:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
2429
|
+
.ep-nav-sub-btn[aria-current="page"]{background:var(--co-50);color:var(--co-700);font-weight:600}
|
|
2430
|
+
/* Hamburger (per JS injiziert) — nur unter dem Mobile-Breakpoint sichtbar */
|
|
2431
|
+
.ep-nav-burger{display:none;align-items:center;justify-content:center;width:48px;height:48px;flex-shrink:0;border:1px solid var(--n-200);border-radius:var(--r-sm);background:var(--bg-surface);color:var(--tx-primary);cursor:pointer;padding:0}
|
|
2432
|
+
.ep-nav-burger:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2433
|
+
.ep-nav-burger .icon-close{display:none}
|
|
2434
|
+
.ep-topnav.nav-open .ep-nav-burger .icon-menu{display:none}
|
|
2435
|
+
.ep-topnav.nav-open .ep-nav-burger .icon-close{display:inline}
|
|
2436
|
+
|
|
2437
|
+
/* ── Topnav-Aktionen: Suche + Theme-Umschalter ──
|
|
2438
|
+
Per JS in jede .ep-topnav injiziert (wie der Hamburger). Rechts gebündelt, direkt vor dem CTA.
|
|
2439
|
+
Bleibt Corporate-Chrome (co) auch auf data-accent-Seiten, analog zu den Nav-Links. */
|
|
2440
|
+
.ep-nav-actions{display:inline-flex;align-items:center;gap:var(--s1);margin-left:auto}
|
|
2441
|
+
/* CTA (letztes Child) trägt sonst selbst margin-left:auto → würde den rechten Cluster auseinanderreißen.
|
|
2442
|
+
Wenn die Aktionen das Schieben übernehmen, bekommt der CTA nur noch einen kleinen Abstand.
|
|
2443
|
+
:not(.ep-nav-actions) → greift nur, wenn NACH den Aktionen noch ein CTA folgt; fehlt der CTA
|
|
2444
|
+
(Aktionen sind selbst letztes Child), behält .ep-nav-actions sein margin-left:auto und bleibt rechts. */
|
|
2445
|
+
.ep-topnav:has(.ep-nav-actions) > :last-child:not(.ep-nav-actions){margin-left:var(--s3)}
|
|
2446
|
+
.ep-nav-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;flex-shrink:0;border:1px solid transparent;border-radius:var(--r-full);background:none;color:var(--tx-secondary);cursor:pointer;transition:background var(--m-fast),color var(--m-fast)}
|
|
2447
|
+
.ep-nav-icon-btn:hover{background:var(--co-50);color:var(--co-700)}
|
|
2448
|
+
.ep-nav-icon-btn:focus-visible{outline:none;box-shadow:var(--focus-aa)}
|
|
2449
|
+
.ep-nav-icon-btn svg{width:22px;height:22px}
|
|
2450
|
+
/* Theme-Umschalter: Mond im Light (Klick → Dark), Sonne im Dark (Klick → Light) */
|
|
2451
|
+
.ep-nav-theme-toggle .ep-nav-icon-sun{display:none}
|
|
2452
|
+
[data-theme="dark"] .ep-nav-theme-toggle .ep-nav-icon-sun{display:block}
|
|
2453
|
+
[data-theme="dark"] .ep-nav-theme-toggle .ep-nav-icon-moon{display:none}
|
|
2454
|
+
/* Such-Popover: Disclosure unter dem Such-Button, spiegelt .ep-nav-sub (bg-surface, --e3, --bd) */
|
|
2455
|
+
.ep-nav-search{position:relative;display:inline-flex}
|
|
2456
|
+
.ep-nav-search.is-open .ep-nav-search-toggle{background:var(--co-50);color:var(--co-700)}
|
|
2457
|
+
.ep-nav-search-pop{display:none;position:absolute;top:calc(100% + var(--s3));right:0;z-index:10;width:320px;max-width:90vw;padding:var(--s4);background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-md);box-shadow:var(--e3)}
|
|
2458
|
+
.ep-nav-search.is-open .ep-nav-search-pop{display:block}
|
|
2459
|
+
.ep-nav-search-form{display:flex;gap:var(--s2);align-items:center}
|
|
2460
|
+
.ep-nav-search-input{flex:1;min-width:0;height:44px;padding:0 var(--s3);font:var(--ty-body-md);color:var(--tx-primary);background:var(--bg-surface);border:2px solid var(--field-border);border-radius:var(--r-md);outline:none;transition:border-color var(--m-fast),box-shadow var(--m-fast)}
|
|
2461
|
+
.ep-nav-search-input:focus{border-color:var(--co-500);box-shadow:var(--focus-ring)}
|
|
2462
|
+
.ep-nav-search-input::placeholder{color:var(--tx-secondary)}
|
|
2463
|
+
@media(max-width:760px){
|
|
2464
|
+
/* Erste Zeile: Logo links, dann Aktionen (Suche/Theme) + Kontakt + Burger rechtsaußen.
|
|
2465
|
+
Der Burger ist bewusst das äußerste rechte Element: So bleibt der Toggle beim Öffnen
|
|
2466
|
+
(Burger → X) an Ort und Stelle, statt seine Position mit dem Kontakt-Button zu tauschen.
|
|
2467
|
+
Nav-Links klappen darunter auf. */
|
|
2468
|
+
.ep-logo{order:1}
|
|
2469
|
+
.ep-nav-actions{order:2;margin-left:auto}
|
|
2470
|
+
.ep-topnav > .btn{order:3;margin-left:var(--s3)}
|
|
2471
|
+
.ep-nav-burger{display:inline-flex;order:4;margin-left:var(--s2)}
|
|
2472
|
+
/* Popover am rechten Rand statt rechtsbündig, damit es auf schmalen Screens nicht abgeschnitten wird */
|
|
2473
|
+
.ep-nav-search-pop{right:auto;left:0;width:min(320px,calc(100vw - var(--s8)))}
|
|
2474
|
+
.ep-nav-links{display:none;order:5;flex-basis:100%;width:100%;flex-direction:column;align-items:stretch;gap:0;margin-top:var(--s3);padding-top:var(--s3);border-top:var(--bd)}
|
|
2475
|
+
.ep-topnav.nav-open .ep-nav-links{display:flex}
|
|
2476
|
+
/* Dropdown-Parent: Label-Link + Caret in EINER Zeile (Label nimmt Restbreite, Caret ≥44px Tap-Target
|
|
2477
|
+
rechts), Submenü klappt in eigener Zeile darunter auf. Einfache Top-Level-Links bleiben full-width. */
|
|
2478
|
+
.ep-nav-item{display:flex;flex-wrap:wrap;align-items:center;width:100%;gap:0}
|
|
2479
|
+
.ep-nav-btn{width:100%;padding:var(--s3) 0}
|
|
2480
|
+
.ep-nav-item .ep-nav-btn{flex:1 1 auto;width:auto}
|
|
2481
|
+
.ep-nav-item-toggle{flex:0 0 auto;width:44px;min-height:44px;padding:var(--s3) 0}
|
|
2482
|
+
.ep-nav-item .ep-nav-sub{flex-basis:100%}
|
|
2483
|
+
.ep-nav-btn::after{display:none}
|
|
2484
|
+
/* Untermenü inline aufklappen statt als schwebendes Overlay */
|
|
2485
|
+
.ep-nav-sub{position:static;display:none;box-shadow:none;border:none;background:none;padding:0 0 var(--s2) var(--s4);min-width:0}
|
|
2486
|
+
.ep-nav-has-sub.is-open .ep-nav-sub{display:flex}
|
|
2487
|
+
.ep-nav-sub-btn{padding:var(--s2) var(--s3);white-space:normal}
|
|
2488
|
+
}
|
|
2489
|
+
.ep-hero-eyebrow{font:var(--ty-label-xs);letter-spacing:.12em;text-transform:uppercase;opacity:.8;margin-bottom:var(--s3)}
|
|
2490
|
+
.ep-hero-ctas{display:flex;gap:var(--s3);flex-wrap:wrap}
|
|
2491
|
+
.ep-section{padding:var(--s12) var(--s8);text-align:left}
|
|
2492
|
+
/* Mobile (≤ 768px): horizontaler Section-Innenabstand 32 → 24 px (--s6), im Rhythmus
|
|
2493
|
+
mit dem Card-Padding; vertikaler Abstand bleibt. Greift nicht auf Sektionen mit
|
|
2494
|
+
inline gesetztem padding-inline / padding-Shorthand (bewusste Einzelfälle). */
|
|
2495
|
+
@media(max-width:768px){
|
|
2496
|
+
.ep-section{padding-inline:var(--s6)}
|
|
2497
|
+
}
|
|
2498
|
+
/* Phone (≤ 520px): Hero-CTAs stapeln full-width für große Tap-Flächen. Erst hier, nicht
|
|
2499
|
+
schon ab 768px: Auf Phablet/kleinem Tablet (521–768px) liefen die Buttons sonst viel
|
|
2500
|
+
breiter als der (auf 520px gekappte) Intro-Text und wirkten überdehnt. Dort behalten sie
|
|
2501
|
+
ihre natürliche Breite + Wrap und folgen der Hero-Ausrichtung (justify-content). */
|
|
2502
|
+
@media(max-width:520px){
|
|
2503
|
+
.ep-hero-ctas{flex-direction:column;align-items:stretch}
|
|
2504
|
+
.ep-hero-ctas .btn{width:100%;justify-content:center}
|
|
2505
|
+
}
|
|
2506
|
+
/* Auszeichnungs-/Badge-Liste (z. B. „Ausgezeichnet als Arbeitgeber“): Desktop als zentrierte
|
|
2507
|
+
Reihe. Auf Mobile (≤ 768px) als 2×2-Grid statt flex-wrap: zentriertes Wrappen richtet jede
|
|
2508
|
+
Zeile einzeln aus, sodass die unterschiedlich breiten Einträge versetzt erscheinen; das Grid
|
|
2509
|
+
fluchtet sie in zwei saubere Spalten (minmax(0,1fr) lässt lange Labels umbrechen). */
|
|
2510
|
+
.ep-award-list{list-style:none;margin:var(--s5) 0 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s4) var(--s8)}
|
|
2511
|
+
@media(max-width:768px){
|
|
2512
|
+
.ep-award-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));justify-content:stretch;gap:var(--s5)}
|
|
2513
|
+
.ep-award-list>li{justify-self:start}
|
|
2514
|
+
}
|
|
2515
|
+
.ep-section-label{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;margin-bottom:var(--s2)}
|
|
2516
|
+
.ep-section-h2{font:var(--ty-headline-md);color:var(--tx-primary);margin-bottom:var(--s2)}
|
|
2517
|
+
/* margin-bottom --s8 (32 px): Sub-Cards-Gap (32) ist bewusst kleiner als section-padding-bottom (48),
|
|
2518
|
+
damit das Auge die Card-Reihe als „optisch mittig“ wahrnimmt (psychologische Mitte liegt über der
|
|
2519
|
+
geometrischen). Verhältnis card-padding (24) : sub-cards-gap (32) : section-edge (48) = 1 : 1.33 : 2.
|
|
2520
|
+
Color tx-secondary als Lead-Default; macht Inline-Overrides im Markup überflüssig. */
|
|
2521
|
+
.ep-section-sub{font:var(--ty-body-md);color:var(--tx-secondary);margin-bottom:var(--s8)}
|
|
2522
|
+
/* Fakten-Liste: die Rahmendaten eines Angebots (Dauer, Format, Gruppe, Preis …) als Label/Wert-Paare
|
|
2523
|
+
untereinander. Bewusst OHNE eigenen Rahmen und ohne Fläche: die Liste zieht in einen vorhandenen
|
|
2524
|
+
Container ein (Angebots-Box, Sticky-Sidebar), ein eigener Rahmen ergäbe dort Kasten-im-Kasten.
|
|
2525
|
+
Einspaltig auf allen Breiten, deshalb keine Media-Query nötig — und lange Werte wie „Schriftliche
|
|
2526
|
+
Handlungsempfehlungen“ brechen innerhalb ihres Paares um, statt wie im früheren mehrspaltigen
|
|
2527
|
+
Streifen die Nachbarspalten zu verziehen. Bereichston der Labels über .t-XX im Markup (dark-safe),
|
|
2528
|
+
nie als Inline-Farbe. */
|
|
2529
|
+
.ep-facts{margin:0}
|
|
2530
|
+
.ep-facts > div + div{margin-top:var(--s4);padding-top:var(--s4);border-top:var(--bd)}
|
|
2531
|
+
.ep-facts dt{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;margin:0 0 var(--s1)}
|
|
2532
|
+
.ep-facts dd{font:var(--ty-body-md);color:var(--tx-primary);margin:0}
|
|
2533
|
+
/* Zwei-Spalten-Variante für Kästen, die neben Inhalt stehen: Einspaltig macht der Kasten dort mehr
|
|
2534
|
+
Höhe als der Inhalt daneben (gemessen 470 gegen 256 px, also 214 px Leerraum). Zweispaltig halbiert
|
|
2535
|
+
die Liste. auto-fit statt fixer Spaltenzahl, damit sie in schmalen Kästen und mobil von selbst
|
|
2536
|
+
einspaltig wird. Die Haarlinien entfallen dabei: Bei zwei Spalten trennen sie keine Zeilen mehr
|
|
2537
|
+
eindeutig, und der Abstand gliedert bereits. Nur für kurze Werte gedacht — lange wie „Schriftliche
|
|
2538
|
+
Handlungsempfehlungen“ brauchen die einspaltige Grundform. */
|
|
2539
|
+
.ep-facts.is-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--s4) var(--s5)}
|
|
2540
|
+
.ep-facts.is-grid > div + div{margin-top:0;padding-top:0;border-top:0}
|
|
2541
|
+
/* Funktions-Vergleich: aufklappbar via native <details>/<summary>, default zugeklappt.
|
|
2542
|
+
Mirror des .article-toc-Musters; Marker entfernt, Caret rotiert im [open]-Zustand. */
|
|
2543
|
+
.ep-compare{margin-top:var(--s8);border-top:var(--bd);padding-top:var(--s5)}
|
|
2544
|
+
.ep-compare-summary{display:inline-flex;align-items:center;gap:var(--s2);padding:var(--s2) 0;font:var(--ty-label-md);letter-spacing:.05em;text-transform:uppercase;color:var(--ki-800);cursor:pointer;list-style:none}
|
|
2545
|
+
.ep-compare-summary::-webkit-details-marker{display:none}
|
|
2546
|
+
.ep-compare-summary:hover{color:var(--ki-900)}
|
|
2547
|
+
.ep-compare-summary:focus-visible{outline:none;box-shadow:var(--focus-aa);border-radius:2px}
|
|
2548
|
+
.ep-compare-caret{width:16px;height:16px;flex-shrink:0;transition:transform var(--m-fast)}
|
|
2549
|
+
.ep-compare[open] .ep-compare-caret{transform:rotate(180deg)}
|
|
2550
|
+
.ep-compare-table-wrap{overflow-x:auto;margin-top:var(--s5)}
|
|
2551
|
+
.ep-compare-table{width:100%;border-collapse:collapse;font:var(--ty-body-sm)}
|
|
2552
|
+
.ep-compare-table th,.ep-compare-table td{padding:var(--s3);border-bottom:var(--bd)}
|
|
2553
|
+
.ep-compare-table thead th{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;color:var(--tx-secondary);text-align:center}
|
|
2554
|
+
.ep-compare-table thead th:first-child{text-align:left}
|
|
2555
|
+
.ep-compare-table thead th:not(:first-child){width:8rem}
|
|
2556
|
+
.ep-compare-table tbody th{text-align:left;font:var(--ty-body-sm);font-weight:400;color:var(--tx-secondary)}
|
|
2557
|
+
.ep-compare-table tbody td{text-align:center;color:var(--tx-secondary)}
|
|
2558
|
+
.ep-compare-table tbody tr:last-child th,.ep-compare-table tbody tr:last-child td{border-bottom:none}
|
|
2559
|
+
.ep-compare-table .ep-compare-pro{background:var(--ki-50)}
|
|
2560
|
+
.ep-compare-table thead .ep-compare-pro{color:var(--ki-800);border-bottom:2px solid var(--ki-500)}
|
|
2561
|
+
.ep-compare-yes{color:var(--ki-800);font-weight:700}
|
|
2562
|
+
.ep-compare-no{color:var(--tx-muted)}
|
|
2563
|
+
/* Gap --s6 (24 px) statt --s4 (16 px), damit der Card-Rhythmus konsistent zu .layout-grid bleibt
|
|
2564
|
+
(Wissensbeiträge, Veranstaltungen, Team nutzen ebenfalls --s6). Border-Radius und Box-Shadow
|
|
2565
|
+
der Cards tragen das Container-Gefühl, auch wenn padding ≈ gap ist. */
|
|
2566
|
+
.ep-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--s6)}
|
|
2567
|
+
/* Padding 24 (--s6) statt 20 (--s5), damit Innen-Atem ≥ 1,5× Außen-Gap (--s4 = 16 px).
|
|
2568
|
+
Sonst lösen sich die Cards visuell auf — Innen- und Außenabstand wären zu nah beieinander. */
|
|
2569
|
+
/* Konvention „Elevation = Interaktivität“: statische Cards ruhen flach mit Rahmen (--bd-strong),
|
|
2570
|
+
kein Schatten. Schatten ist interaktiven Cards (.ep-card-link) vorbehalten → eindeutiges Affordanz-Signal. */
|
|
2571
|
+
.ep-card{display:flex;flex-direction:column;border-radius:var(--r-lg);padding:var(--s6);background:var(--bg-surface);border:var(--bd-strong)}
|
|
2572
|
+
/* Icon-Container 48×48 (war 40), SVG 32×32 (war 24). Substantiellere Präsenz im Verhältnis zum
|
|
2573
|
+
Card-Padding (24 px). Sizes folgen Icon-Sizing-System (siehe sec-icons/Größen). */
|
|
2574
|
+
/* Kachel-Fläche über --XX-50, den ruhigen Bereichston, und ohne Rand. Sie muss nicht als Fläche
|
|
2575
|
+
lesen: WCAG verlangt für eine dekorative Fläche nichts, das Glyph ist aria-hidden und wiederholt
|
|
2576
|
+
nur das Eyebrow daneben. Darüber entscheidet das Markenrad, und 48 px gesättigte Farbe sind das
|
|
2577
|
+
Gegenteil von „Ruhig“. Das Glyph trägt die Erkennbarkeit: -700/-800 auf dem Tint 7,5 bis 11,4:1,
|
|
2578
|
+
im Dark hebt dark-mode.css es auf -100 (6,9 bis 8,6:1). Die Farbe kommt aus der Komponente, nicht
|
|
2579
|
+
aus 76 inline gesetzten style-Attributen. */
|
|
2580
|
+
.ep-card-icon{width:48px;height:48px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;margin-bottom:var(--s4);background:var(--co-50)}
|
|
2581
|
+
.ep-card-icon[data-area="co"]{background:var(--co-50)}
|
|
2582
|
+
.ep-card-icon[data-area="ki"]{background:var(--ki-50)}
|
|
2583
|
+
.ep-card-icon[data-area="es"]{background:var(--es-50)}
|
|
2584
|
+
.ep-card-icon[data-area="wo"]{background:var(--wo-50)}
|
|
2585
|
+
/* stroke-sm (1.25) = wie die Outline-Icons inline gezeichnet sind; md (1.5) ueberschrieb das und
|
|
2586
|
+
wirkte auf dem 32px-Render (24er-viewBox, hochskaliert) zu fett. Gefuellte Brand-Icons ohne stroke
|
|
2587
|
+
sind unberuehrt. */
|
|
2588
|
+
.ep-card-icon svg{width:32px;height:32px;stroke-width:var(--icon-stroke-sm)}
|
|
2589
|
+
/* Area-aware Eyebrow, spiegelbildlich zu .card-eyebrow (700er-Token) */
|
|
2590
|
+
.ep-card-eyebrow{font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;color:var(--co-700);margin-bottom:var(--s2)}
|
|
2591
|
+
.ep-card-eyebrow[data-area="co"]{color:var(--co-700)}
|
|
2592
|
+
.ep-card-eyebrow[data-area="ki"]{color:var(--ki-800)}
|
|
2593
|
+
.ep-card-eyebrow[data-area="es"]{color:var(--es-700)}
|
|
2594
|
+
.ep-card-eyebrow[data-area="wo"]{color:var(--wo-700)}
|
|
2595
|
+
.ep-card-title{font:var(--ty-title-sm);color:var(--tx-primary);margin-bottom:var(--s2)}
|
|
2596
|
+
.ep-card-text{font:var(--ty-body-md);color:var(--tx-secondary)}
|
|
2597
|
+
/* Klickbare Karten-Variante: gesamte Karte ist Link, mit Hover-Elevation */
|
|
2598
|
+
/* Interaktive Karte: ruht auf --e1 (statt Rahmen), hebt auf Hover/Focus auf --e3 + translateY.
|
|
2599
|
+
border-color:transparent neutralisiert den statischen --bd-strong-Rahmen; ein inline border-top-Akzent bleibt erhalten. */
|
|
2600
|
+
.ep-card-link{text-decoration:none;color:inherit;cursor:pointer;border-color:transparent;box-shadow:var(--e1);transition:box-shadow var(--m-fast),transform var(--m-fast),background var(--m-fast)}
|
|
2601
|
+
.ep-card-link:hover{box-shadow:var(--e3);transform:translateY(-2px)}
|
|
2602
|
+
.ep-card-link:focus-visible{outline:none;box-shadow:var(--focus-ring),var(--e3)}
|
|
2603
|
+
/* CTA-Zeile: per margin-top:auto an Karten-Unterkante gepinnt, area-aware Farbe via [data-area] auf .ep-card */
|
|
2604
|
+
.ep-card-cta{font:var(--ty-label-md);color:var(--co-700);margin-top:auto;padding-top:var(--s4);display:inline-flex;align-items:center;gap:var(--s1)}
|
|
2605
|
+
.ep-card[data-area="co"] .ep-card-cta{color:var(--co-700)}
|
|
2606
|
+
.ep-card[data-area="ki"] .ep-card-cta{color:var(--ki-800)}
|
|
2607
|
+
.ep-card[data-area="es"] .ep-card-cta{color:var(--es-700)}
|
|
2608
|
+
.ep-card[data-area="wo"] .ep-card-cta{color:var(--wo-700)}
|
|
2609
|
+
/* Card-CTA-Link (z.B. „Beitrag lesen →“ am Karten-Fuß).
|
|
2610
|
+
Light: --co-700 #007575 auf #fff = 5.53:1 ✓ AA. Dark-Override in dark-mode.css.
|
|
2611
|
+
--pinned-Modifier für Flex-Karten, in denen der CTA an die Unterkante gepinnt werden soll. */
|
|
2612
|
+
/* Kein margin-top: den Abstand zur Zeile darüber trägt der gap des .card-body. Die --pinned-
|
|
2613
|
+
Variante setzt margin-top:auto und schiebt den CTA an die Unterkante, dort ersetzt das auto
|
|
2614
|
+
jeden festen Wert ohnehin. */
|
|
2615
|
+
.card-cta-link{font:var(--ty-label-md);color:var(--co-700)}
|
|
2616
|
+
/* Bereichsvariante (optional): trägt die Akzentfarbe statt Corporate-Teal, wenn der CTA in einer
|
|
2617
|
+
Bereichs-Sektion sitzt. Shades wie .ep-card-cta; Dark-Overrides (→ -200/-100) in dark-mode.css. */
|
|
2618
|
+
.card-cta-link[data-area="co"]{color:var(--co-700)}
|
|
2619
|
+
.card-cta-link[data-area="ki"]{color:var(--ki-800)}
|
|
2620
|
+
.card-cta-link[data-area="es"]{color:var(--es-700)}
|
|
2621
|
+
.card-cta-link[data-area="wo"]{color:var(--wo-700)}
|
|
2622
|
+
/* Pinned-Variante: margin-top:auto schiebt den Link an die Karten-Unterkante.
|
|
2623
|
+
padding-top:var(--s4) trennt die Action-Zone (CTA) sichtbar vom Info-Block (Meta + Anreißer) darüber. */
|
|
2624
|
+
.card-cta-link--pinned{margin-top:auto;padding-top:var(--s4)}
|
|
2625
|
+
/* Als echter Link (a.card-cta-link) verwendbar: kein Default-Underline, Underline erst bei Hover, sichtbarer
|
|
2626
|
+
Fokus-Ring. Gescoped auf a[…], damit die <span>-Nutzung in klickbaren .ep-card-link-Karten (kein Fremd-Hover) unberührt bleibt. */
|
|
2627
|
+
a.card-cta-link{display:inline-block;text-decoration:none}
|
|
2628
|
+
a.card-cta-link:hover{text-decoration:underline;text-underline-offset:2px}
|
|
2629
|
+
a.card-cta-link:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:2px}
|
|
2630
|
+
/* ── Offene Feature-Liste (flaches Icon-Layout, gruppiert nach Tier; Alternative zu Bild-Cards) ── */
|
|
2631
|
+
.ep-feature{display:flex;gap:var(--s4)}
|
|
2632
|
+
/* Icon-Kachel: Glyph hat AA-Kontrast zur Kachel — Core tx-secondary/n-100 5.3:1, Pro ki-800/ki-50 7.5:1.
|
|
2633
|
+
tx-secondary + n-100 sind theme-aware, Core flippt also automatisch (Dark 6.0:1).
|
|
2634
|
+
Pro braucht einen Dark-Override, weil --ki-800 dunkel bleibt, --ki-50 aber dunkel wird → dark-mode.css. */
|
|
2635
|
+
.ep-feature-icon{flex:0 0 48px;width:48px;height:48px;border-radius:var(--r-sm);display:inline-flex;align-items:center;justify-content:center;background:var(--n-100);color:var(--tx-secondary)}
|
|
2636
|
+
.ep-feature-icon svg{width:26px;height:26px;stroke-width:var(--icon-stroke-md)}
|
|
2637
|
+
.ep-feature-icon[data-area="ki"]{background:var(--ki-50);color:var(--ki-800)}
|
|
2638
|
+
.ep-feature-icon[data-area="co"]{background:var(--co-50);color:var(--co-800)}
|
|
2639
|
+
.ep-feature-icon[data-area="es"]{background:var(--es-50);color:var(--es-800)}
|
|
2640
|
+
.ep-feature-icon[data-area="wo"]{background:var(--wo-50);color:var(--wo-800)}
|
|
2641
|
+
.ep-feature-body{display:flex;flex-direction:column;gap:var(--s1)}
|
|
2642
|
+
/* Ausnahme, und sie gehört dem Container: der Gap ist hier absichtlich winzig (--s1), damit Titel
|
|
2643
|
+
und Text als eine Einheit gelesen werden. Für den CTA ist das zu eng, er soll sich vom Text
|
|
2644
|
+
lösen. Der Card-Body braucht das nicht, sein gap:var(--s3) trägt den Abstand schon. */
|
|
2645
|
+
.ep-feature-body>.card-cta-link{margin-top:var(--s2)}
|
|
2646
|
+
.ep-feature-title{font:var(--ty-title-sm);color:var(--tx-primary);margin:0}
|
|
2647
|
+
.ep-feature-text{font:var(--ty-body-md);color:var(--tx-secondary);margin:0}
|
|
2648
|
+
/* Tier-Trenner: Label + Hairline. Label area-aware (Pro = ki-800, Dark-Override → ki-100). Linie = --bd-strong-Ton (n-200). */
|
|
2649
|
+
.ep-tier{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s6)}
|
|
2650
|
+
.ep-tier-label{font:var(--ty-label-md);letter-spacing:.06em;text-transform:uppercase;color:var(--tx-secondary);white-space:nowrap}
|
|
2651
|
+
.ep-tier-label[data-area="ki"]{color:var(--ki-800)}
|
|
2652
|
+
.ep-tier-rule{flex:1;height:1px;background:var(--n-200)}
|
|
2653
|
+
/* Timeline-Marker (Conciso-Story): heller Bereichston + dunkles Icon (ruhiger als gefüllter Punkt), auf der Schiene sitzend. Dark-Override (helles Icon auf dunklem Tile) in dark-mode.css. */
|
|
2654
|
+
/* Dekorative Fläche wie .ep-card-icon: ruhiger Tint, das Glyph trägt. */
|
|
2655
|
+
.ep-tl-icon{position:absolute;right:-20px;top:0;width:38px;height:38px;border-radius:var(--r-full);background:var(--co-50);color:var(--co-800);display:inline-flex;align-items:center;justify-content:center;box-shadow:0 0 0 4px var(--bg-surface)}
|
|
2656
|
+
.ep-tl-icon svg{width:24px;height:24px;stroke-width:var(--icon-stroke-sm)}
|
|
2657
|
+
/* ── FAQ-Accordion (native details/summary) ── */
|
|
2658
|
+
.ep-faq{max-width:none}
|
|
2659
|
+
.ep-faq details{border-top:var(--bd)}
|
|
2660
|
+
.ep-faq details:last-of-type{border-bottom:var(--bd)}
|
|
2661
|
+
.ep-faq summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:var(--s4);padding:var(--s4) 0;font:var(--ty-title-sm);color:var(--tx-primary)}
|
|
2662
|
+
.ep-faq summary::-webkit-details-marker{display:none}
|
|
2663
|
+
.ep-faq summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
2664
|
+
.ep-faq-caret{flex:0 0 auto;color:var(--tx-secondary);transition:transform var(--m-fast)}
|
|
2665
|
+
.ep-faq details[open] .ep-faq-caret{transform:rotate(180deg)}
|
|
2666
|
+
.ep-faq-a{font:var(--ty-body-md);color:var(--tx-secondary);margin:0 0 var(--s4);max-width:680px}
|
|
2667
|
+
/* ── Download CTA ── */
|
|
2668
|
+
/* Kein Schatten: der Block ist statisch, die Interaktion liegt in den Buttons darin
|
|
2669
|
+
(Elevation = Interaktivität). Rahmen plus 4-px-Akzent oben tragen die Kartenform. */
|
|
2670
|
+
.cta-dl{display:flex;align-items:center;gap:var(--s6);background:var(--bg-surface);border:var(--bd-strong);border-top:4px solid var(--cta-accent,var(--co-500));border-radius:var(--r-lg);padding:var(--s6) var(--s8)}
|
|
2671
|
+
.cta-dl[data-area="co"]{--cta-accent:var(--co-500)}
|
|
2672
|
+
.cta-dl[data-area="ki"]{--cta-accent:var(--ki-500)}
|
|
2673
|
+
.cta-dl[data-area="es"]{--cta-accent:var(--es-500)}
|
|
2674
|
+
.cta-dl[data-area="wo"]{--cta-accent:var(--wo-500)}
|
|
2675
|
+
.cta-dl-icon{width:64px;height:64px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
|
2676
|
+
.cta-dl[data-area="co"] .cta-dl-icon{background:var(--co-50);color:var(--co-700)}
|
|
2677
|
+
.cta-dl[data-area="ki"] .cta-dl-icon{background:var(--ki-50);color:var(--ki-700)}
|
|
2678
|
+
.cta-dl[data-area="es"] .cta-dl-icon{background:var(--es-50);color:var(--es-700)}
|
|
2679
|
+
.cta-dl[data-area="wo"] .cta-dl-icon{background:var(--wo-50);color:var(--wo-700)}
|
|
2680
|
+
.cta-dl-body{flex:1}
|
|
2681
|
+
.cta-dl-eyebrow{font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.08em;margin:0 0 var(--s1)}
|
|
2682
|
+
.cta-dl[data-area="co"] .cta-dl-eyebrow{color:var(--co-700)} /* co-600 war nur 3,28:1 (Uppercase-Label < AA) → co-700 = 5,5:1; jetzt konsistent mit ki-800/es-700/wo-700 */
|
|
2683
|
+
.cta-dl[data-area="ki"] .cta-dl-eyebrow{color:var(--ki-800)}
|
|
2684
|
+
.cta-dl[data-area="es"] .cta-dl-eyebrow{color:var(--es-700)}
|
|
2685
|
+
.cta-dl[data-area="wo"] .cta-dl-eyebrow{color:var(--wo-700)}
|
|
2686
|
+
.cta-dl-title{font:var(--ty-headline-sm);color:var(--tx-primary);margin:0 0 var(--s2)}
|
|
2687
|
+
.cta-dl-desc{font:var(--ty-body-md);color:var(--tx-secondary);margin:0 0 var(--s3)}
|
|
2688
|
+
.cta-dl-meta{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center}
|
|
2689
|
+
.cta-dl-actions{display:flex;flex-direction:column;gap:var(--s2);align-items:stretch;flex-shrink:0;min-width:152px}
|
|
2690
|
+
/* Compact strip */
|
|
2691
|
+
.cta-strip{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s4);background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-md);padding:var(--s4) var(--s5)}
|
|
2692
|
+
.cta-strip-icon{width:40px;height:40px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
|
2693
|
+
.cta-strip[data-area="co"] .cta-strip-icon{background:var(--co-50);color:var(--co-700)}
|
|
2694
|
+
.cta-strip[data-area="ki"] .cta-strip-icon{background:var(--ki-50);color:var(--ki-700)}
|
|
2695
|
+
.cta-strip[data-area="es"] .cta-strip-icon{background:var(--es-50);color:var(--es-700)}
|
|
2696
|
+
.cta-strip[data-area="wo"] .cta-strip-icon{background:var(--wo-50);color:var(--wo-700)}
|
|
2697
|
+
.cta-strip-body{flex:1;display:flex;flex-direction:column;gap:2px}
|
|
2698
|
+
.cta-strip-title{font:var(--ty-label-md);color:var(--tx-primary)}
|
|
2699
|
+
.cta-strip-meta{font:var(--ty-body-xs);color:var(--tx-muted)}
|
|
2700
|
+
/* Minimal link */
|
|
2701
|
+
.cta-link{display:inline-flex;align-items:center;gap:var(--s2);font:var(--ty-label-md);text-decoration:none;padding:var(--s2) 0;border-bottom:1px solid transparent;transition:border-color var(--m-fast)}
|
|
2702
|
+
.cta-link[data-area="co"]{color:var(--co-700)}
|
|
2703
|
+
.cta-link[data-area="ki"]{color:var(--ki-800)}
|
|
2704
|
+
.cta-link[data-area="es"]{color:var(--es-700)}
|
|
2705
|
+
.cta-link[data-area="wo"]{color:var(--wo-700)}
|
|
2706
|
+
.cta-link:hover{border-bottom-color:currentColor}
|
|
2707
|
+
.cta-link-meta{font:var(--ty-body-xs);color:var(--tx-muted);margin-left:var(--s1)}
|
|
2708
|
+
/* Mit Vorschaubild */
|
|
2709
|
+
/* Kein Schatten, gleiche Begründung wie .cta-dl: statischer Block mit Button darin. */
|
|
2710
|
+
.cta-visual{display:flex;align-items:stretch;background:var(--bg-surface);border:var(--bd-strong);border-radius:var(--r-lg);overflow:hidden}
|
|
2711
|
+
.cta-visual-cover{width:180px;flex-shrink:0;overflow:hidden;background:var(--n-100);position:relative}
|
|
2712
|
+
.cta-visual-cover img{width:100%;height:100%;object-fit:cover;display:block}
|
|
2713
|
+
.cta-visual-content{flex:1;padding:var(--s6);display:flex;flex-direction:column;border-left:var(--bd)}
|
|
2714
|
+
.cta-visual-eyebrow{font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.08em;margin:0 0 var(--s1)}
|
|
2715
|
+
/* Alle vier auf --XX-ink: co lag auf co-600 und trug damit nur 3,29:1 auf Weiß. Das Ink-Token
|
|
2716
|
+
flippt im Dark auf den hellen Ton, ein festes -700/-800 wäre dort dunkel-auf-dunkel. */
|
|
2717
|
+
.cta-visual[data-area="co"] .cta-visual-eyebrow{color:var(--co-ink)}
|
|
2718
|
+
.cta-visual[data-area="ki"] .cta-visual-eyebrow{color:var(--ki-ink)}
|
|
2719
|
+
.cta-visual[data-area="es"] .cta-visual-eyebrow{color:var(--es-700)}
|
|
2720
|
+
.cta-visual[data-area="wo"] .cta-visual-eyebrow{color:var(--wo-700)}
|
|
2721
|
+
.cta-visual-title{font:var(--ty-headline-xs);color:var(--tx-primary);margin:0 0 var(--s2)}
|
|
2722
|
+
.cta-visual-desc{font:var(--ty-body-md);color:var(--tx-secondary);margin:0;flex:1}
|
|
2723
|
+
.cta-visual-footer{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;margin-top:auto;padding-top:var(--s4);border-top:var(--bd)}
|
|
2724
|
+
.ep-cta-band{padding:var(--s12) var(--s8);text-align:center}
|
|
2725
|
+
.ep-cta-h2{font:var(--ty-headline-md);margin-bottom:var(--s2)}
|
|
2726
|
+
.ep-cta-sub{font:var(--ty-body-md);opacity:.85;margin-bottom:var(--s6)}
|
|
2727
|
+
/* Beispielseiten: iframes der Prototypen (volle Breite, kein Border) */
|
|
2728
|
+
|
|
2729
|
+
/* ── Tabelle ── */
|
|
2730
|
+
.tbl-wrap{overflow-x:auto}
|
|
2731
|
+
.tbl-wrap:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-xs)}
|
|
2732
|
+
.tbl{width:100%;border-collapse:collapse;font:var(--ty-body-md);color:var(--tx-primary)}
|
|
2733
|
+
.tbl caption{font:var(--ty-title-sm);color:var(--tx-primary);padding:0 0 var(--s5);text-align:left}
|
|
2734
|
+
.tbl thead th{font:var(--ty-label-xs);text-transform:uppercase;letter-spacing:.06em;color:var(--tx-secondary);padding:var(--s3) var(--s5);background:var(--n-50);border-bottom:2px solid var(--n-200);border-top:var(--bd);text-align:left;white-space:nowrap}
|
|
2735
|
+
.tbl tbody td,.tbl tbody th{padding:var(--s4) var(--s5);border-bottom:var(--bd);vertical-align:top}
|
|
2736
|
+
.tbl tbody tr:last-child td,.tbl tbody tr:last-child th{border-bottom:none}
|
|
2737
|
+
.tbl tbody tr:hover td,.tbl tbody tr:hover th{background:var(--bg-overlay)}
|
|
2738
|
+
.tbl tbody th{font:var(--ty-label-md);color:var(--tx-primary);text-align:left}
|
|
2739
|
+
.tbl tfoot td,.tbl tfoot th{padding:var(--s4) var(--s5) 0;font:var(--ty-label-sm);color:var(--tx-primary);border-top:2px solid var(--n-200);text-align:left}
|
|
2740
|
+
.tbl td[data-num],.tbl th[data-num]{text-align:right;font-variant-numeric:tabular-nums}
|
|
2741
|
+
/* Striped variant */
|
|
2742
|
+
.tbl--striped tbody tr:nth-child(even) td,.tbl--striped tbody tr:nth-child(even) th{background:var(--n-50)}
|
|
2743
|
+
.tbl--striped tbody tr:hover td,.tbl--striped tbody tr:hover th{background:var(--bg-overlay)}
|
|
2744
|
+
/* Sortierbare Spalten */
|
|
2745
|
+
.tbl-sort{display:inline-flex;align-items:center;gap:var(--s1);background:none;border:none;cursor:pointer;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit;padding:0}
|
|
2746
|
+
.tbl-sort:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-xs)}
|
|
2747
|
+
.tbl-sort svg{opacity:.3;transition:opacity var(--m-fast)}
|
|
2748
|
+
.tbl-sort:hover svg{opacity:.7}
|
|
2749
|
+
thead th[aria-sort="ascending"] .tbl-sort svg,
|
|
2750
|
+
thead th[aria-sort="descending"] .tbl-sort svg{opacity:1;color:var(--co-600)}
|
|
2751
|
+
|
|
2752
|
+
/* ── Wissensbeitrag (Article) ── */
|
|
2753
|
+
/* Header: zentrierter Block mit Breadcrumb · Pill · Titel · Lead · Meta */
|
|
2754
|
+
.article-header{max-width:880px;margin:0 auto;text-align:center}
|
|
2755
|
+
.article-breadcrumb{font:var(--ty-body-sm);color:var(--tx-muted);margin-bottom:var(--s5)}
|
|
2756
|
+
.article-breadcrumb a{color:inherit;text-decoration:none}
|
|
2757
|
+
.article-breadcrumb [aria-current="page"]{color:var(--tx-primary);font-weight:500}
|
|
2758
|
+
.article-breadcrumb-sep{margin:0 var(--s2)}
|
|
2759
|
+
/* Pill: Kategorie · Format · Lesezeit, area-aware */
|
|
2760
|
+
/* Füllung über --XX-fill, gleiche Begründung wie beim Badge (siehe tokens.css). ES-Text auf -800
|
|
2761
|
+
statt -700: auf der kräftigeren Füllung trägt -700 nur noch 4,74:1, -800 gibt Reserve und ist
|
|
2762
|
+
derselbe Ton, den das ES-Badge längst nutzt. */
|
|
2763
|
+
/* width:fit-content hält die Pille eine Pille, auch als Flex- oder Grid-Item. Ein inline-block
|
|
2764
|
+
wird als Flex-Item zu block blockifiziert, und ein Kind mit auto-Cross-Size wird von
|
|
2765
|
+
align-items:stretch auf die volle Spaltenbreite gezogen: aus der Pille wird ein Balken
|
|
2766
|
+
(gemessen im Featured-Body bei 1280 px Kartenbreite: 448 px statt 146 px). Im normalen Fluss
|
|
2767
|
+
ist die Zeile ein No-Op, ein inline-block schrumpft dort ohnehin auf seinen Inhalt. Darum hier
|
|
2768
|
+
an der Komponente und nicht als align-self je Container: die Pille bringt ihre Form selbst mit,
|
|
2769
|
+
statt sie von jedem Layout einzeln zugewiesen zu bekommen. Deckt Flex und Grid in einem ab,
|
|
2770
|
+
denn eine definierte Cross-Size schlägt stretch in beiden. */
|
|
2771
|
+
.pill{display:inline-block;width:fit-content;font:var(--ty-label-xs);letter-spacing:.09em;text-transform:uppercase;padding:var(--s1) var(--s3);border-radius:var(--r-full);margin-bottom:var(--s5);background:var(--co-fill);color:var(--co-800)}
|
|
2772
|
+
.pill[data-area="co"]{background:var(--co-fill);color:var(--co-800)}
|
|
2773
|
+
.pill[data-area="ki"]{background:var(--ki-fill);color:var(--ki-800)}
|
|
2774
|
+
.pill[data-area="es"]{background:var(--es-fill);color:var(--es-800)}
|
|
2775
|
+
.pill[data-area="wo"]{background:var(--wo-fill);color:var(--wo-800)}
|
|
2776
|
+
.article-title{font:var(--ty-display-md);color:var(--tx-primary);margin:0 0 var(--s4);text-wrap:balance}
|
|
2777
|
+
/* Lead-Paragraph für Artikel-Header: 18 px, eine Stufe über Body-Md (16) und unter Title-Sm (20).
|
|
2778
|
+
Bewusst hardcoded statt eigenes Token, weil Lead nur in einer Komponente vorkommt. */
|
|
2779
|
+
.article-lead{font:400 1.125rem/1.75rem var(--font);color:var(--tx-secondary);margin:0 auto;max-width:680px;text-wrap:pretty}
|
|
2780
|
+
/* Meta-Strip: Avatar · Name/Rolle · Trenner · Datum */
|
|
2781
|
+
.article-meta{display:flex;align-items:center;justify-content:center;gap:var(--s4);margin-top:var(--s8);flex-wrap:wrap}
|
|
2782
|
+
.article-meta-author{display:flex;align-items:center;gap:var(--s3)}
|
|
2783
|
+
.article-meta-text{text-align:left}
|
|
2784
|
+
.article-meta-name{font:var(--ty-label-md);color:var(--tx-primary);margin:0}
|
|
2785
|
+
.article-meta-role{font:var(--ty-body-xs);color:var(--tx-muted);margin:0}
|
|
2786
|
+
.article-meta-sep{display:inline-block;width:1px;height:24px;background:var(--n-200)}
|
|
2787
|
+
.article-meta-date{font:var(--ty-body-sm);color:var(--tx-secondary);margin:0}
|
|
2788
|
+
/* Avatar (Initialen-Kreis), area-aware; .article-avatar-lg für Author-Card-Größe; <img> als Kind ersetzt die Initialen */
|
|
2789
|
+
.article-avatar{width:40px;height:40px;border-radius:var(--r-full);display:flex;align-items:center;justify-content:center;font:600 0.875rem/1 var(--font);letter-spacing:.04em;flex-shrink:0;background:var(--co-100);color:var(--co-800);position:relative;overflow:hidden}
|
|
2790
|
+
.article-avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
|
|
2791
|
+
.article-avatar[data-area="co"]{background:var(--co-100);color:var(--co-800)}
|
|
2792
|
+
.article-avatar[data-area="ki"]{background:var(--ki-100);color:var(--ki-800)}
|
|
2793
|
+
.article-avatar[data-area="es"]{background:var(--es-100);color:var(--es-700)}
|
|
2794
|
+
.article-avatar[data-area="wo"]{background:var(--wo-100);color:var(--wo-800)}
|
|
2795
|
+
.article-avatar-lg{width:64px;height:64px;font-size:1.25rem}
|
|
2796
|
+
/* XL für Team-Tile-Grid auf Landing/Über-uns: 160 px (war 112 px). Mit 4 Tiles pro Reihe (col-3)
|
|
2797
|
+
füllt das Foto die Tile-Breite sinnvoll aus, statt verloren in der Whitespace zu wirken.
|
|
2798
|
+
Author-Card-Bios bleiben bei -lg (64 px), weil sie horizontal neben Bio-Text sitzen. */
|
|
2799
|
+
.article-avatar-xl{width:160px;height:160px;font-size:3rem}
|
|
2800
|
+
/* Mobile: spaltenrelativ, damit der Avatar (160px fix, flex-shrink:0) in den schmalen Spalten der
|
|
2801
|
+
2-/3-spaltigen Team- und Roster-Grids nicht überläuft. 72 % der Tile-Breite, gedeckelt bei 112px;
|
|
2802
|
+
aspect-ratio:1 hält ihn quadratisch (height:auto statt der fixen 160px). Bei 3-Spalten/375px
|
|
2803
|
+
(~93px Spalte) → ~67px, bei breiteren Spalten bis max. 112px. Desktop bleibt bei 160px. */
|
|
2804
|
+
@media(max-width:768px){.article-avatar-xl{width:min(112px,72%);height:auto;aspect-ratio:1;font-size:1.875rem}}
|
|
2805
|
+
/* Multi-Author: Avatare gestapelt mit weißem Border-Halo zur visuellen Überlappung */
|
|
2806
|
+
.article-avatar-stack{display:inline-flex;align-items:center;flex-shrink:0}
|
|
2807
|
+
.article-avatar-stack .article-avatar{border:2px solid var(--bg-surface)}
|
|
2808
|
+
.article-avatar-stack .article-avatar + .article-avatar,
|
|
2809
|
+
.article-avatar-stack .article-avatar + .article-avatar-more{margin-left:-12px}
|
|
2810
|
+
.article-avatar-stack .article-avatar-lg + .article-avatar-lg,
|
|
2811
|
+
.article-avatar-stack .article-avatar-lg + .article-avatar-more{margin-left:-16px}
|
|
2812
|
+
/* "+N"-Indikator für 4+ Autor:innen */
|
|
2813
|
+
.article-avatar-more{width:40px;height:40px;border-radius:var(--r-full);background:var(--n-100);color:var(--tx-secondary);display:flex;align-items:center;justify-content:center;font:600 0.75rem/1 var(--font);letter-spacing:.02em;flex-shrink:0;border:2px solid var(--bg-surface)}
|
|
2814
|
+
/* Author-Card-Group: mehrere Author-Cards untereinander am Artikelende */
|
|
2815
|
+
.author-card-group{max-width:720px;margin:0 auto;display:flex;flex-direction:column;gap:var(--s6)}
|
|
2816
|
+
.author-card-group .author-card{margin:0;max-width:none}
|
|
2817
|
+
/* Zwei-Spalten-Variante der Gruppe: für Personen mit Kurz-Bio, wo die gestapelte Liste zu lang
|
|
2818
|
+
würde, typisch Trainer:innen auf einer Seminar-/Training-Landing (2 bis 4 Personen). Die Bio
|
|
2819
|
+
ist dort das Vertrauenselement und darf nicht wegfallen, deshalb Raster statt Tile-Grid
|
|
2820
|
+
(.article-avatar-xl ohne Bio, siehe #gt-article-team-tiles). 960 statt 720 px Container, weil
|
|
2821
|
+
zwei Karten nebeneinander sonst je ~340 px hätten und der 64-px-Avatar den Text auf ~260 px
|
|
2822
|
+
drückt. minmax(0,1fr) verhindert Grid-Blowout durch lange Namen. */
|
|
2823
|
+
.author-card-group.is-grid{max-width:960px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s8)}
|
|
2824
|
+
/* Mobil einspaltig, konsistent mit dem Kollaps der .layout-grid bei 768px. Engerer Abstand,
|
|
2825
|
+
weil untereinander kein Spaltenabstand mehr trennt und --s8 dort als Loch wirken würde. */
|
|
2826
|
+
@media(max-width:768px){.author-card-group.is-grid{grid-template-columns:1fr;gap:var(--s6)}}
|
|
2827
|
+
/* Eine gemeinsame Gruppen-Überschrift („Über die Autor:innen“), ersetzt die Eyebrows der einzelnen Cards */
|
|
2828
|
+
.author-card-group-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--tx-muted);margin:0 0 var(--s2);max-width:720px;margin-left:auto;margin-right:auto}
|
|
2829
|
+
/* Die Überschrift steht als Geschwister VOR der Gruppe und muss deren Container-Breite mitgehen,
|
|
2830
|
+
sonst sitzt sie bei der Raster-Variante 120 px links neben der ersten Karte. */
|
|
2831
|
+
.author-card-group-eyebrow:has(+ .author-card-group.is-grid){max-width:960px}
|
|
2832
|
+
/* Body: 720px-Spalte mit Article-Typo, H2/Listen automatisch gestylt */
|
|
2833
|
+
.article-body{max-width:720px;margin:0 auto;font:var(--ty-body-md);color:var(--tx-primary);line-height:1.7}
|
|
2834
|
+
.article-body > p{margin:0 0 var(--s5)}
|
|
2835
|
+
.article-body > p:last-child{margin-bottom:0}
|
|
2836
|
+
.article-body h2{font:var(--ty-headline-sm);color:var(--tx-primary);margin:var(--s10) 0 var(--s4);text-wrap:balance}
|
|
2837
|
+
.article-body ul,.article-body ol{padding-left:var(--s5);margin:0 0 var(--s5)}
|
|
2838
|
+
.article-body ul li{margin-bottom:var(--s4)}
|
|
2839
|
+
.article-body ol li{margin-bottom:var(--s3)}
|
|
2840
|
+
/* In-Article Figure: redaktionelles Inline-Bild mit Bildunterschrift; alt beschreibt, figcaption ordnet ein */
|
|
2841
|
+
.article-figure{margin:var(--s8) 0}
|
|
2842
|
+
.article-figure img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:var(--r-lg);display:block;background:var(--n-100)}
|
|
2843
|
+
.article-figcaption{font:var(--ty-body-md);color:var(--tx-secondary);text-align:center;margin:var(--s3) 0 0;text-wrap:balance}
|
|
2844
|
+
/* Inhaltsverzeichnis: aufklappbar via native <details>/<summary>, default zugeklappt; minimaler Stil — kein Container, nur dünne Trennlinien oben/unten */
|
|
2845
|
+
.article-toc{max-width:720px;margin:var(--s6) auto var(--s8);border-block:var(--bd)}
|
|
2846
|
+
.article-toc-summary{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);padding:var(--s3) 0;font:var(--ty-label-md);color:var(--tx-primary);cursor:pointer;list-style:none}
|
|
2847
|
+
.article-toc-summary::-webkit-details-marker{display:none}
|
|
2848
|
+
.article-toc-summary:hover{color:var(--co-700)}
|
|
2849
|
+
.article-toc-summary:focus-visible{outline:none;box-shadow:var(--focus-aa);border-radius:2px}
|
|
2850
|
+
.article-toc-caret{width:16px;height:16px;flex-shrink:0;color:var(--tx-secondary);transition:transform var(--m-fast)}
|
|
2851
|
+
.article-toc[open] .article-toc-caret{transform:rotate(180deg)}
|
|
2852
|
+
.article-toc-list{list-style:none;counter-reset:toc;padding:var(--s2) 0 var(--s4);margin:0}
|
|
2853
|
+
.article-toc-list li{display:flex;gap:var(--s3);align-items:baseline;padding:3px 0}
|
|
2854
|
+
.article-toc-list li::before{content:counter(toc);counter-increment:toc;color:var(--tx-secondary);font:var(--ty-label-sm);font-variant-numeric:tabular-nums;flex-shrink:0;min-width:1.25em}
|
|
2855
|
+
.article-toc-list a{color:var(--tx-primary);text-decoration:none;font:var(--ty-body-md);line-height:1.5}
|
|
2856
|
+
.article-toc-list a:hover{text-decoration:underline;text-underline-offset:3px;color:var(--co-700)}
|
|
2857
|
+
.article-toc-list a:focus-visible{outline:none;box-shadow:var(--focus-aa);border-radius:2px}
|
|
2858
|
+
/* Callout: Aside im Body, area-aware. Border-Akzent in 500 (wie .bq), Eyebrow in 700 (wie .cta-dl-eyebrow) */
|
|
2859
|
+
.article-callout{background:var(--co-50);border-left:4px solid var(--co-500);border-radius:var(--r-md);padding:var(--s5) var(--s6);margin:var(--s8) 0}
|
|
2860
|
+
.article-callout[data-area="co"]{background:var(--co-50);border-left-color:var(--co-500)}
|
|
2861
|
+
.article-callout[data-area="ki"]{background:var(--ki-50);border-left-color:var(--ki-500)}
|
|
2862
|
+
.article-callout[data-area="es"]{background:var(--es-50);border-left-color:var(--es-500)}
|
|
2863
|
+
.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)}
|
|
2865
|
+
.article-callout[data-area="ki"] .article-callout-eyebrow{color:var(--ki-800)}
|
|
2866
|
+
.article-callout[data-area="es"] .article-callout-eyebrow{color:var(--es-700)}
|
|
2867
|
+
.article-callout[data-area="wo"] .article-callout-eyebrow{color:var(--wo-700)}
|
|
2868
|
+
.article-callout > p{font:var(--ty-body-md);color:var(--tx-primary);margin:0}
|
|
2869
|
+
/* Author-Card: Avatar + Bio am Ende des Artikels, area-aware */
|
|
2870
|
+
.author-card{max-width:720px;margin:0 auto;display:flex;gap:var(--s5);align-items:flex-start}
|
|
2871
|
+
.author-card-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--tx-muted);margin:0 0 var(--s1)}
|
|
2872
|
+
.author-card-name{font:var(--ty-title-sm);color:var(--tx-primary);margin:0}
|
|
2873
|
+
.author-card-role{font:var(--ty-body-sm);color:var(--tx-secondary);margin:0 0 var(--s3)}
|
|
2874
|
+
.author-card-bio{font:var(--ty-body-md);color:var(--tx-primary);margin:0}
|
|
2875
|
+
/* Pull-Quote: typografische Hervorhebung autoreigener Sätze im Body — area-aware Linksakzent in 500 (analog .bq), aber ohne Background und ohne Quote-Icon */
|
|
2876
|
+
.article-pullquote{margin:var(--s10) 0;padding:var(--s4) var(--s6);border-left:4px solid var(--co-500);font-family:var(--font-display);font-style:italic;font-size:clamp(1.375rem, 1.222rem + 0.68vw, 1.75rem);line-height:1.4;color:var(--tx-primary);quotes:none}
|
|
2877
|
+
.article-pullquote[data-area="co"]{border-left-color:var(--co-500)}
|
|
2878
|
+
.article-pullquote[data-area="ki"]{border-left-color:var(--ki-500)}
|
|
2879
|
+
.article-pullquote[data-area="es"]{border-left-color:var(--es-500)}
|
|
2880
|
+
.article-pullquote[data-area="wo"]{border-left-color:var(--wo-500)}
|
|
2881
|
+
|
|
2882
|
+
/* ── Documentation tables (Verwendung, Barrierefreiheit, etc.) ── */
|
|
2883
|
+
.doc-table{width:100%;border-collapse:collapse;font:var(--ty-body-md)}
|
|
2884
|
+
.doc-table thead tr{border-bottom:var(--bd-strong)}
|
|
2885
|
+
.doc-table th{text-align:left;padding:var(--s2) var(--s3) var(--s2) 0;font:500 0.75rem/1rem var(--font);letter-spacing:.06em;text-transform:uppercase;color:var(--tx-secondary)}
|
|
2886
|
+
.doc-table th:last-child{padding-left:var(--s3)}
|
|
2887
|
+
.doc-table tbody tr{border-bottom:var(--bd)}
|
|
2888
|
+
.doc-table tbody tr:last-child{border-bottom:none}
|
|
2889
|
+
.doc-table td{padding:var(--s3) var(--s3) var(--s3) 0;color:var(--tx-secondary);vertical-align:top}
|
|
2890
|
+
.doc-table td:first-child{color:var(--tx-primary);font-weight:500}
|
|
2891
|
+
.doc-table td:last-child{padding-left:var(--s3)}
|