Der wichtigste Fund: env(safe-area-inset-*) stand bereits im CSS, lieferte aber immer null -- viewport-fit=cover fehlte auf allen dreizehn Seiten. Der Code sah richtig aus und tat nichts. Zusammen mit apple-mobile-web-app-status-bar-style=black-translucent (schon gesetzt) hiess das: installiert lag die Kopfzeile auf einem iPhone hinter Uhr und Akkuanzeige. Behoben: - viewport-fit=cover auf allen 13 Seiten. - Vier Sicherheitsabstaende zentral benannt statt an jeder Stelle einzeln geschrieben. Kopfzeile weicht der Statusleiste, Container dem seitlichen Notch im Querformat, Fusszeile der Gestenleiste. - Der 'Ueberspringen'-Knopf des Vorspanns lag mit bottom:2rem praktisch AUF dem Entsperr-Strich (34px). Man haette die App verlassen statt uebersprungen. - Eigener Zweig fuer den installierten Betrieb: kein Gummiband- Nachfedern (sieht in einer App nach einem Fehler aus), kein Installations-Hinweis. - Die vier Sprungmarken auf der Rechtsseite waren 39px hoch -- fuenf unter dem Daumenmass. Ausgerechnet dort muss man zum Widerrufsrecht springen koennen. - 'Waehle links einen Verlauf aus': Auf dem Handy gibt es kein links, die Liste steht darueber. Richtungswort entfernt. - Sechs Reiter brauchten auf dem Handy drei Zeilen. Jetzt ein Wischstreifen mit Einrasten und Auslauf am Rand; der aktive Reiter wird herangeholt, wenn man ueber eine Kachel springt. - Uebersicht zweispaltig statt zwoelf Zeilen untereinander: 2635px -> 1924px. Eine Uebersicht, an der man vorbeiwischen muss, ist keine. Geprueft mit 55 neuen Handy-Pruefungen auf iPhone 14 Pro, Pixel 7 und 320px Breite, jeweils im Browser und im installierten Zweig. Drei Fehlalarme der eigenen Pruefung wurden begruendet ausgenommen (Honigtopf bei left:-9999px, Eingabefeld in einer Beschriftung, Inline-Link im Fliesstext -- WCAG 2.5.8 nimmt letztere ausdruecklich aus). Zwei Selbstkorrekturen an der Pruefung dokumentiert: Die Emulation von display-mode wirkt nicht (Chromium nimmt den Befehl an und ignoriert ihn) -- ohne das waeren die zwoelf 'installiert'-Zeilen ein zweiter Browser-Durchgang gewesen. Und die Messung gegen die Systemleisten mass zuerst die Kastenkante statt der Inhaltskante und meldete elf korrekte Seiten als fehlerhaft. Eine Selbstpruefung mit einem absichtlich falsch gesetzten Knopf belegt jetzt, dass die Messung echte Fehler findet. Co-Authored-By: Claude Opus 5 <[email protected]>
2252 lines
102 KiB
CSS
2252 lines
102 KiB
CSS
/* =====================================================================
|
|
DOGFATHER WEBDESIGN — webdesign.css
|
|
Eigenes Designsystem für den Bereich /webdesign, umgesetzt nach dem
|
|
"Website Masterplan" (Seite 6, VISUELLE DNA).
|
|
|
|
Warum eine EIGENE Datei statt main.css zu erweitern:
|
|
- main.css trägt drei Welten (Dogfather/HasiDog/SpicyMedia) über
|
|
theme-*.css. Der Webdesign-Bereich ist eine vierte, eigenständige
|
|
Marke mit eigener Farblogik (Gold ist hier z.B. AUSSCHLIESSLICH für
|
|
Hinweise/Zahlung reserviert, im Universe ist es allgemeine Deko).
|
|
Eine Vermischung würde beide Systeme unscharf machen.
|
|
- Der Bereich ist bis zur Freigabe nicht öffentlich. Solange darf er
|
|
am laufenden Universe nichts kaputt machen können — getrennte Datei
|
|
heißt: null Risiko für die Live-Seite.
|
|
Die Grundtokens (--radius, Schriftfamilien) kommen weiterhin aus
|
|
main.css, das hier zusätzlich geladen wird. Alles Eigene trägt bewusst
|
|
das Präfix --wd- / .wd-, damit es sich nie mit main.css beißt.
|
|
|
|
AUGENSCHONEND ist Dauervorgabe (nicht projektspezifisch):
|
|
gedeckte Flächen statt greller Neon-Optik, Leuchten nur als weicher
|
|
Schimmer, keine Flacker-/Strobe-Effekte, jede Animation respektiert
|
|
prefers-reduced-motion, Textkontraste durchgehend über WCAG-AA.
|
|
===================================================================== */
|
|
|
|
/* ---------------------------------------------------------------------
|
|
1. FARBWELT & TOKENS
|
|
Kontraste gegen die dunkelste Fläche (#05070b) nachgerechnet:
|
|
--wd-text #eef4fb -> 17.4:1 (AAA)
|
|
--wd-text-mid #b3c2d4 -> 10.2:1 (AAA)
|
|
--wd-text-soft #8f9fb4 -> 6.6:1 (AA, auch für kleine Schrift)
|
|
--wd-blau #7fd0e8 -> 10.6:1 (AAA)
|
|
--wd-lila #b79dff -> 8.1:1 (AAA)
|
|
--wd-gold #e8c877 -> 11.0:1 (AAA)
|
|
Bewusst KEIN reines #00e5ff / #ff00ff — solche vollgesättigten Neons
|
|
blenden auf dunklem Grund und sind genau das, was vermieden werden soll.
|
|
--------------------------------------------------------------------- */
|
|
:root {
|
|
--wd-schwarz: #05070b; /* Tiefschwarz — Grundfläche */
|
|
--wd-dunkelblau: #0a1220; /* Dunkelblau — zweite Grundfläche */
|
|
--wd-dunkelblau-2: #0e1826; /* leicht angehoben, für Abschnittswechsel */
|
|
--wd-flaeche: #101a29; /* Kartengrund (deckend, für Formularfelder) */
|
|
|
|
/* ---------- Markenfarben als KANÄLE ----------
|
|
Zusätzlich zu den fertigen Farben stehen die Rot-, Grün- und
|
|
Blauanteile einzeln bereit. Das ist kein Selbstzweck.
|
|
|
|
Halbdurchsichtige Töne — Ränder, Leuchten, sanfte Flächen — brauchen
|
|
einen Alphawert. Mit einer fertigen Farbvariablen geht das nicht,
|
|
also stand die Farbe in solchen Regeln ausgeschrieben da:
|
|
"rgb(var(--wd-blau-rgb) / .16)". Eine Zählung am 23.08.2026 ergab
|
|
155 solcher Stellen, allein 74 für Blau.
|
|
|
|
Die Folge: Wer den Markenton ändern will, muss 155 Stellen finden.
|
|
Man übersieht welche, und die Seite hat danach zwei Blautöne, die
|
|
sich um eine Nuance unterscheiden — der Unterschied zwischen
|
|
gewachsener und gestalteter Oberfläche.
|
|
|
|
Mit den Kanälen schreibt man rgb(var(--wd-blau-rgb) / .16). Eine
|
|
Änderung hier wirkt überall. Die fertigen Farben bleiben daneben
|
|
erhalten, weil sie kürzer zu lesen sind, wo kein Alpha gebraucht
|
|
wird — sie werden aus denselben Kanälen gebildet, können also nicht
|
|
auseinanderlaufen. */
|
|
--wd-blau-rgb: 127 208 232;
|
|
--wd-lila-rgb: 183 157 255;
|
|
--wd-gold-rgb: 232 200 119;
|
|
--wd-ok-rgb: 111 214 163;
|
|
--wd-fehler-rgb: 255 157 157;
|
|
--wd-glas-rgb: 16 26 41;
|
|
|
|
--wd-blau: rgb(var(--wd-blau-rgb)); /* Babyblau — Hauptaktionen, Linien, Leuchten */
|
|
--wd-blau-hell: #a9e2f2; /* Eisblau — Lesbarkeit auf dunklem Grund */
|
|
--wd-blau-tief: #3d9dbd; /* für Ränder/Verläufe, nicht für Text */
|
|
--wd-lila: rgb(var(--wd-lila-rgb)); /* sekundäre Bereiche, Kontrast */
|
|
--wd-lila-tief: #7c5cd6;
|
|
--wd-gold: rgb(var(--wd-gold-rgb)); /* NUR Hinweise & Zahlungsinformationen */
|
|
--wd-gold-tief: #a8873a;
|
|
|
|
--wd-text: #eef4fb;
|
|
--wd-text-mid: #b3c2d4;
|
|
--wd-text-soft: #8f9fb4;
|
|
|
|
--wd-rand: rgb(var(--wd-blau-rgb) / .16);
|
|
--wd-rand-stark: rgb(var(--wd-blau-rgb) / .34);
|
|
--wd-glas: rgb(var(--wd-glas-rgb) / .62);
|
|
--wd-glas-tief: rgba(10, 18, 32, .82);
|
|
|
|
--wd-ok: rgb(var(--wd-ok-rgb));
|
|
--wd-fehler: rgb(var(--wd-fehler-rgb));
|
|
--wd-warnung: var(--wd-gold);
|
|
|
|
/* Eine Skala mit vier Stufen: 6 / 10 / 14 / 20 -- plus 999px fuer die
|
|
Pillenform, die keine Stufe ist, sondern eine eigene Form.
|
|
Vorher waren 12 verschiedene Werte im Umlauf, darunter 5, 7, 9 und
|
|
11px. Solche Zwischenwerte entstehen nicht aus Absicht, sondern
|
|
weil man beim Bauen einer neuen Kachel nicht nachschaut, was
|
|
nebenan schon gilt. Auffallen tut es niemandem einzeln -- in Summe
|
|
ist es der Unterschied zwischen gewachsener und gestalteter
|
|
Oberflaeche. */
|
|
--wd-r: 14px; /* Standardradius */
|
|
--wd-r-gross: 20px;
|
|
--wd-schatten: 0 24px 60px -28px rgba(0, 0, 0, .9);
|
|
--wd-schatten-tief: 0 40px 90px -34px rgba(0, 0, 0, .95);
|
|
|
|
/* Bewegung an EINER Stelle steuerbar — die Reduktions-Regel ganz unten
|
|
setzt diese Variablen auf 0s, damit auch neu hinzukommende Animationen
|
|
automatisch mit abgeschaltet sind und nicht einzeln nachgepflegt
|
|
werden müssen. */
|
|
--wd-zeit-schnell: .16s;
|
|
--wd-zeit: .28s;
|
|
--wd-zeit-lang: .6s;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
1b. BILDLAUFLEISTE
|
|
|
|
Rückmeldung 22.08.2026: "die leiste rechts zum hoch und runter, kannst
|
|
du die mal geil aussehen lassen anstatt einfach so kake weiß."
|
|
|
|
Zu Recht. Auf einer durchgehend dunklen Seite ist eine helle
|
|
Bildlaufleiste der einzige grelle Streifen im Bild — sie zieht den
|
|
Blick genau dorthin, wo nichts Wichtiges steht, und ist bei einer
|
|
dunklen Umgebung schlicht blendend. Das widerspricht der Dauervorgabe
|
|
"augenschonend".
|
|
|
|
Zwei Wege sind nötig, weil kein Browser beide versteht:
|
|
|
|
* color-scheme: dark -- Firefox und Safari. Ein einziges Wort, das
|
|
dem Browser sagt: das hier ist eine dunkle Oberfläche, nimm deine
|
|
dunklen Bedienelemente. Wirkt auch auf Auswahlfelder und
|
|
Datumsauswahl, die sonst weiß aufblitzen.
|
|
|
|
* ::-webkit-scrollbar -- Chrome, Edge, Opera. Feiner steuerbar,
|
|
aber ausschließlich dort verfügbar.
|
|
|
|
scrollbar-width/-color (die neue Norm) NICHT verwendet: Sobald es
|
|
gesetzt ist, ignoriert Chrome die ::-webkit-Regeln und man bekommt
|
|
überall die grobe Fassung. Zwei getrennte Wege ergeben in beiden
|
|
Browserfamilien das bessere Ergebnis.
|
|
|
|
Die Leiste ist bewusst zurückhaltend: gedeckt, erst beim Zeigen etwas
|
|
heller. Sie soll auffindbar sein, nicht leuchten.
|
|
--------------------------------------------------------------------- */
|
|
body.wd,
|
|
.wd input, .wd select, .wd textarea {
|
|
/* Wirkt zusätzlich auf Formularfelder — sonst bleibt die Datumsauswahl
|
|
in Firefox ein weißes Rechteck mitten in der dunklen Seite. */
|
|
color-scheme: dark;
|
|
}
|
|
|
|
/* ACHTUNG bei den Selektoren: "body.wd::-webkit-scrollbar" (ohne
|
|
Leerzeichen) und ".wd ::-webkit-scrollbar" (mit Leerzeichen) sind
|
|
zwei VERSCHIEDENE Dinge, und man braucht beide.
|
|
|
|
ohne Leerzeichen -> die Leiste des body selbst, also die grosse
|
|
rechts am Fensterrand. GENAU die war gemeint.
|
|
mit Leerzeichen -> die Leisten von Elementen INNERHALB der Seite,
|
|
z.B. im Detailfenster der Verwaltung.
|
|
|
|
Beim ersten Versuch stand hier nur die zweite Fassung. Alle Messungen
|
|
sahen gut aus — an der einzigen Leiste, ueber die sich jemand
|
|
beschwert hatte, aenderte sich dadurch nichts. */
|
|
body.wd::-webkit-scrollbar,
|
|
.wd ::-webkit-scrollbar { width: 12px; height: 12px; }
|
|
|
|
body.wd::-webkit-scrollbar-track,
|
|
.wd ::-webkit-scrollbar-track {
|
|
background: rgba(8, 14, 24, .6);
|
|
border-radius: 999px;
|
|
}
|
|
|
|
body.wd::-webkit-scrollbar-thumb,
|
|
.wd ::-webkit-scrollbar-thumb {
|
|
background: linear-gradient(180deg, rgb(var(--wd-blau-rgb) / .44), rgb(var(--wd-lila-rgb) / .36));
|
|
border-radius: 999px;
|
|
/* Der durchsichtige Rand lässt die Spur seitlich durchscheinen — der
|
|
Griff wirkt dadurch schmaler als die Trefferfläche. Bedienbar bleibt
|
|
die volle Breite, sichtbar ist nur ein feiner Strich. */
|
|
border: 3px solid transparent;
|
|
background-clip: content-box;
|
|
}
|
|
body.wd::-webkit-scrollbar-thumb:hover,
|
|
.wd ::-webkit-scrollbar-thumb:hover {
|
|
background: linear-gradient(180deg, rgb(var(--wd-blau-rgb) / .6), rgb(var(--wd-lila-rgb) / .5));
|
|
background-clip: content-box;
|
|
}
|
|
body.wd::-webkit-scrollbar-thumb:active,
|
|
.wd ::-webkit-scrollbar-thumb:active {
|
|
background: linear-gradient(180deg, rgb(var(--wd-blau-rgb) / .8), rgb(var(--wd-lila-rgb) / .7));
|
|
background-clip: content-box;
|
|
}
|
|
/* Die Ecke zwischen waagerechter und senkrechter Leiste — ohne diese
|
|
Zeile bleibt genau dort ein weißes Quadrat stehen. */
|
|
body.wd::-webkit-scrollbar-corner,
|
|
.wd ::-webkit-scrollbar-corner { background: transparent; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
2. GRUNDLAGEN
|
|
--------------------------------------------------------------------- */
|
|
body.wd {
|
|
background: var(--wd-schwarz);
|
|
color: var(--wd-text);
|
|
font-family: var(--font-body);
|
|
line-height: 1.7;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Cinematische Tiefe: zwei sehr weiche, weit auseinanderliegende
|
|
Lichtquellen statt eines flächigen Verlaufs. Fest positioniert, damit
|
|
beim Scrollen echte Tiefe entsteht, ohne eine einzige Animation zu
|
|
kosten (Masterplan S.6 "Cinematische Tiefe, Licht, Nebel" — S.15 aber
|
|
auch "Animationen leistungsbewusst"). */
|
|
body.wd::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -2;
|
|
pointer-events: none;
|
|
background:
|
|
radial-gradient(1100px 720px at 18% -8%, rgba(61, 157, 189, .20), transparent 68%),
|
|
radial-gradient(900px 640px at 92% 8%, rgba(124, 92, 214, .16), transparent 66%),
|
|
linear-gradient(180deg, #070b12 0%, var(--wd-schwarz) 46%, #04060a 100%);
|
|
}
|
|
|
|
/* Feine Rasterlinien — gibt der Fläche Struktur (Premium statt Baukasten),
|
|
bleibt mit 3 % Deckkraft klar unter der Wahrnehmungsschwelle für
|
|
"unruhig". mask blendet das Raster nach unten aus, damit es nicht
|
|
teppichartig über die ganze Seite liegt. */
|
|
body.wd::after {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -1;
|
|
pointer-events: none;
|
|
opacity: .5;
|
|
background-image:
|
|
linear-gradient(rgb(var(--wd-blau-rgb) / .03) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgb(var(--wd-blau-rgb) / .03) 1px, transparent 1px);
|
|
background-size: 64px 64px;
|
|
-webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 62%);
|
|
mask-image: linear-gradient(180deg, #000 0%, transparent 62%);
|
|
}
|
|
|
|
.wd-container { width: min(1180px, 92vw); margin: 0 auto; }
|
|
.wd-container--schmal { width: min(860px, 92vw); }
|
|
|
|
/* Abstand zwischen den Abschnitten.
|
|
Vorher clamp(3.4rem, 7vw, 6.5rem) = 100,8px oben UND unten, also gut
|
|
200px Leerraum zwischen zwei Abschnitten. Rueckmeldung 22.08.2026:
|
|
"ich will nicht soooo viel abstand". Jetzt rund die Haelfte -- immer
|
|
noch klar getrennt, aber ohne dass man an leeren Flaechen
|
|
vorbeiscrollt. */
|
|
.wd-abschnitt { padding: clamp(2.2rem, 4vw, 3.6rem) 0; position: relative; }
|
|
.wd-abschnitt--eng { padding: clamp(1.4rem, 2.6vw, 2.2rem) 0; }
|
|
/* Abwechselnde Grundfläche statt Trennlinien — ruhiger und trotzdem klar. */
|
|
.wd-abschnitt--gehoben { background: linear-gradient(180deg, transparent, var(--wd-dunkelblau) 14%, var(--wd-dunkelblau) 86%, transparent); }
|
|
|
|
/* ---------- Typografie (Masterplan S.6) ----------
|
|
Dynamische Größen mit clamp(); Fließtext bewusst ruhiger und kleiner als
|
|
im Universe (dort 1.32rem), weil hier deutlich mehr Sachtext steht —
|
|
Preise, Bedingungen und Abläufe müssen lesbar sein, nicht laut. */
|
|
.wd h1, .wd h2, .wd h3, .wd h4 {
|
|
font-family: var(--font-head);
|
|
line-height: 1.15;
|
|
letter-spacing: -.015em;
|
|
margin: 0 0 .5em;
|
|
color: var(--wd-text);
|
|
/* Lange deutsche Komposita ("Buchhaltungsverwaltungsseiten") duerfen auf
|
|
dem Handy nicht aus dem Kasten laufen — dafuer reicht
|
|
overflow-wrap: break-word. Es greift NUR im Notfall, wenn ein Wort
|
|
sonst wirklich ueberlaufen wuerde.
|
|
|
|
"hyphens: auto" stand hier zusaetzlich und ist wieder raus: der
|
|
Browser trennt damit nach Silben, auch wenn gar kein Platzproblem
|
|
besteht. Auf dem Handy stand dadurch "Alles, was vorher ge-klaert
|
|
sein sollte" in der Ueberschrift. In Fliesstext ist Silbentrennung
|
|
ein Gewinn, in grossen Ueberschriften sieht sie schlicht billig aus —
|
|
und genau die sind das Erste, was jemand von der Seite sieht. */
|
|
overflow-wrap: break-word;
|
|
hyphens: manual;
|
|
}
|
|
.wd h1 { font-size: clamp(2.15rem, 5.6vw, 3.9rem); font-weight: 800; }
|
|
.wd h2 { font-size: clamp(1.75rem, 4.2vw, 2.75rem); font-weight: 800; }
|
|
.wd h3 { font-size: clamp(1.2rem, 2.4vw, 1.5rem); font-weight: 700; }
|
|
.wd h4 { font-size: 1.05rem; font-weight: 700; }
|
|
.wd p { margin: 0 0 1em; color: var(--wd-text-mid); font-size: clamp(1rem, 1.5vw, 1.12rem); }
|
|
.wd .wd-lead { font-size: clamp(1.08rem, 2vw, 1.32rem); color: var(--wd-text); line-height: 1.65; }
|
|
.wd .wd-klein { font-size: .92rem; }
|
|
.wd .wd-leise { color: var(--wd-text-soft); }
|
|
/* :not(.wd-btn) ist hier PFLICHT, kein Feinschliff.
|
|
Ohne das gewinnt ".wd a" (Klasse + Element = spezifischer als die reine
|
|
Knopf-Klasse ".wd-btn--haupt") und faerbt die Schrift auf dem hellblauen
|
|
Hauptknopf ebenfalls hellblau -- blau auf blau, praktisch unlesbar.
|
|
Genau so live gemeldet am 22.08.2026 per Bildschirmfoto. */
|
|
.wd a:not(.wd-btn) { color: var(--wd-blau); text-decoration: none; }
|
|
.wd a:not(.wd-btn):hover { color: var(--wd-blau-hell); }
|
|
.wd a.wd-btn { text-decoration: none; }
|
|
.wd strong { color: var(--wd-text); font-weight: 700; }
|
|
|
|
.wd-eyebrow {
|
|
display: inline-block;
|
|
font-size: 0.8rem;
|
|
letter-spacing: .18em;
|
|
text-transform: uppercase;
|
|
font-weight: 800;
|
|
color: var(--wd-blau);
|
|
margin-bottom: .9em;
|
|
}
|
|
.wd-eyebrow--lila { color: var(--wd-lila); }
|
|
|
|
/* Sichtbarer Fokus ÜBERALL (Masterplan S.15 Barrierearmut). :focus-visible
|
|
statt :focus, damit Mausklicks keinen Rahmen hinterlassen, Tastatur aber
|
|
immer einen — und zwar auch auf Elementen, die erst später dazukommen. */
|
|
.wd :focus-visible {
|
|
outline: 3px solid var(--wd-blau);
|
|
outline-offset: 3px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* Sprungmarke für Tastatur-/Screenreader-Nutzung. */
|
|
.wd-skip {
|
|
position: absolute; left: -9999px; top: 0; z-index: 200;
|
|
background: var(--wd-blau); color: #04060a; font-weight: 800;
|
|
padding: .8rem 1.2rem; border-radius: 0 0 10px 0;
|
|
}
|
|
.wd-skip:focus { left: 0; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
[hidden] MUSS gewinnen.
|
|
|
|
Das hidden-Attribut wird vom Browser nur mit "display: none" aus dem
|
|
Standard-Stylesheet umgesetzt — jede eigene display-Angabe schlaegt es.
|
|
Und genau die haben hier viele Elemente: Knoepfe sind inline-flex,
|
|
Karten sind flex, Raster sind grid.
|
|
|
|
Folge ohne diese Regel: el.hidden = true im JavaScript hat schlicht
|
|
keine Wirkung, und das Element bleibt sichtbar. Genau so aufgefallen im
|
|
Anfrageformular (22.08.2026) -- der "Zurueck"-Knopf stand auch auf dem
|
|
ersten Schritt da, obwohl es dorthin nichts zurueckzugehen gibt.
|
|
|
|
Das !important ist hier ausnahmsweise richtig: "versteckt" ist eine
|
|
Aussage ueber den Zustand, nicht ueber die Gestaltung, und darf von
|
|
keiner Gestaltungsregel ueberstimmt werden.
|
|
--------------------------------------------------------------------- */
|
|
.wd [hidden] { display: none !important; }
|
|
|
|
.wd-visuell-versteckt {
|
|
position: absolute; width: 1px; height: 1px; overflow: hidden;
|
|
clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
|
|
}
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
BILDVERHAELTNIS — diese Regel verhindert einen Fehler, der schon
|
|
passiert ist und sonst wieder passiert.
|
|
|
|
Bilder tragen im HTML bewusst width/height als Attribute: der Browser
|
|
reserviert damit vor dem Laden den richtigen Platz und die Seite
|
|
springt beim Nachladen nicht. Diese Attribute wirken aber wie eine
|
|
CSS-Hoehe -- und schlagen damit jedes spaetere "aspect-ratio".
|
|
|
|
Live gemeldet am 22.08.2026 ("die sollen alle gleich aussehen"): die
|
|
beiden Projektbilder standen mit 750px bzw. 696px Hoehe bei nur 576px
|
|
Breite da, also hochkant gestreckt und ungleich hoch, obwohl im CSY
|
|
sauber 16:10 stand.
|
|
|
|
"height: auto" gibt die Hoehe an aspect-ratio zurueck. Es steht hier
|
|
einmal zentral fuer alle Bilder mit Seitenverhaeltnis, statt in jeder
|
|
einzelnen Regel -- so kann es bei einem neuen Bild nicht vergessen
|
|
werden.
|
|
--------------------------------------------------------------------- */
|
|
.wd img[width][height] { height: auto; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
3. KARTEN — "glasartig mit feinen Neonrändern" (Masterplan S.6)
|
|
Der Rand ist bewusst ein Verlauf über border-box statt einer flachen
|
|
Farbe: dadurch wirkt er wie eine Lichtkante, nicht wie ein Strich.
|
|
--------------------------------------------------------------------- */
|
|
.wd-karte {
|
|
position: relative;
|
|
border-radius: var(--wd-r-gross);
|
|
padding: clamp(1.3rem, 2.6vw, 1.9rem);
|
|
background:
|
|
linear-gradient(180deg, rgba(20, 32, 50, .72), rgba(9, 15, 26, .86)) padding-box,
|
|
linear-gradient(140deg, rgb(var(--wd-blau-rgb) / .40), rgb(var(--wd-blau-rgb) / .07) 45%, rgb(var(--wd-lila-rgb) / .30)) border-box;
|
|
border: 1px solid transparent;
|
|
box-shadow: var(--wd-schatten);
|
|
backdrop-filter: blur(10px);
|
|
transition: transform var(--wd-zeit) ease, box-shadow var(--wd-zeit) ease;
|
|
}
|
|
/* Sekundäre Bereiche tragen Lila (Masterplan S.6). */
|
|
.wd-karte--lila {
|
|
background:
|
|
linear-gradient(180deg, rgba(26, 22, 48, .72), rgba(12, 10, 24, .88)) padding-box,
|
|
linear-gradient(140deg, rgb(var(--wd-lila-rgb) / .42), rgb(var(--wd-lila-rgb) / .07) 45%, rgb(var(--wd-blau-rgb) / .26)) border-box;
|
|
}
|
|
/* Nur für Karten, die wirklich klickbar sind — eine Karte, die sich hebt,
|
|
ohne dass man sie anklicken kann, verspricht eine Aktion, die es nicht
|
|
gibt. */
|
|
a.wd-karte:hover, .wd-karte--klickbar:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: var(--wd-schatten-tief), 0 0 44px -20px rgb(var(--wd-blau-rgb) / .55);
|
|
}
|
|
|
|
/* Farbige Kappe oben — übernimmt die Optik der Masterplan-PDF, in der jede
|
|
Karte einen blauen bzw. lila Balken trägt. */
|
|
.wd-karte--kappe { padding-top: clamp(1.6rem, 3vw, 2.2rem); overflow: hidden; }
|
|
.wd-karte--kappe::before {
|
|
content: "";
|
|
position: absolute; top: 0; left: 0; right: 0; height: 5px;
|
|
background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau));
|
|
}
|
|
.wd-karte--lila.wd-karte--kappe::before { background: linear-gradient(90deg, var(--wd-lila-tief), var(--wd-lila)); }
|
|
|
|
.wd-karte h3 { margin-bottom: .55em; }
|
|
.wd-karte > :last-child { margin-bottom: 0; }
|
|
|
|
/* Aufzählung in Karten — Punkt als eigenes Element statt list-style, damit
|
|
die Farbe steuerbar ist und mehrzeilige Punkte sauber einrücken. */
|
|
.wd-liste { margin: 0; padding: 0; list-style: none; }
|
|
.wd-liste li {
|
|
position: relative;
|
|
padding-left: 1.35rem;
|
|
margin-bottom: .55rem;
|
|
color: var(--wd-text-mid);
|
|
font-size: clamp(.98rem, 1.4vw, 1.05rem);
|
|
}
|
|
.wd-liste li::before {
|
|
content: "";
|
|
position: absolute; left: 0; top: .62em;
|
|
width: 7px; height: 7px; border-radius: 50%;
|
|
background: var(--wd-blau);
|
|
box-shadow: 0 0 10px rgb(var(--wd-blau-rgb) / .7);
|
|
}
|
|
.wd-karte--lila .wd-liste li::before { background: var(--wd-lila); box-shadow: 0 0 10px rgb(var(--wd-lila-rgb) / .7); }
|
|
.wd-liste li:last-child { margin-bottom: 0; }
|
|
|
|
/* ---------- Raster ---------- */
|
|
.wd-grid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
|
|
.wd-grid--2 { grid-template-columns: repeat(2, 1fr); }
|
|
.wd-grid--3 { grid-template-columns: repeat(3, 1fr); }
|
|
.wd-grid--4 { grid-template-columns: repeat(4, 1fr); }
|
|
@media (max-width: 900px) { .wd-grid--3, .wd-grid--4 { grid-template-columns: repeat(2, 1fr); } }
|
|
@media (max-width: 640px) { .wd-grid--2, .wd-grid--3, .wd-grid--4 { grid-template-columns: 1fr; } }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
4. KNÖPFE
|
|
Genau EIN Haupt-CTA pro Seite (Masterplan S.3) — deshalb gibt es
|
|
bewusst nur eine einzige auffällige Knopfvariante. Alles andere ist
|
|
sichtbar, konkurriert aber nicht.
|
|
--------------------------------------------------------------------- */
|
|
.wd-btn {
|
|
display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
|
|
/* min-height 48px = Touch-Ziel-Mindestmaß (Masterplan S.15). */
|
|
min-height: 48px;
|
|
padding: .85rem 1.7rem;
|
|
/* Abgerundetes Rechteck statt Pillenform (999px).
|
|
Rueckmeldung 22.08.2026: "das sieht lang gezogen aus". Stimmt — bei
|
|
einer Pille waechst der Radius optisch mit der Breite mit, ein breiter
|
|
Knopf wirkt dadurch auseinandergezogen wie eine Tablette. Ein fester
|
|
Radius haelt die Form bei jeder Breite gleich und wirkt ruhiger und
|
|
hochwertiger. */
|
|
border-radius: 14px;
|
|
border: 1px solid transparent;
|
|
font-family: var(--font-head);
|
|
font-weight: 700;
|
|
font-size: 1rem;
|
|
line-height: 1.2;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
transition: transform var(--wd-zeit-schnell) ease, box-shadow var(--wd-zeit) ease,
|
|
background var(--wd-zeit) ease, border-color var(--wd-zeit) ease, color var(--wd-zeit) ease;
|
|
}
|
|
/* Sofortige, sichtbare Reaktion (Masterplan S.6 "Buttons reagieren sofort
|
|
und sichtbar") — active feuert ohne Verzögerung, auch auf dem Handy. */
|
|
.wd-btn:active { transform: translateY(1px) scale(.985); }
|
|
.wd-btn[disabled], .wd-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
|
|
|
|
.wd .wd-btn--haupt, .wd-btn--haupt {
|
|
/* Dunkler Text auf hellem Babyblau: 11.7:1 — der einzige Weg, einen
|
|
leuchtenden Knopf zu bauen, ohne die Lesbarkeit zu opfern. */
|
|
background: linear-gradient(135deg, var(--wd-blau-hell), var(--wd-blau) 55%, #63bcd8);
|
|
color: #04070c;
|
|
box-shadow: 0 12px 34px -14px rgb(var(--wd-blau-rgb) / .8);
|
|
}
|
|
.wd-btn--haupt:hover { box-shadow: 0 16px 44px -14px rgb(var(--wd-blau-rgb) / .95); transform: translateY(-2px); }
|
|
|
|
.wd .wd-btn--zweit, .wd-btn--zweit {
|
|
background: rgb(var(--wd-blau-rgb) / .07);
|
|
border-color: var(--wd-rand-stark);
|
|
color: var(--wd-blau-hell);
|
|
}
|
|
.wd-btn--zweit:hover { background: rgb(var(--wd-blau-rgb) / .14); border-color: var(--wd-blau); }
|
|
|
|
.wd .wd-btn--still, .wd-btn--still { background: transparent; border-color: var(--wd-rand); color: var(--wd-text-mid); }
|
|
.wd-btn--still:hover { border-color: var(--wd-rand-stark); color: var(--wd-text); }
|
|
|
|
.wd-btn--breit { width: 100%; }
|
|
/* "klein" heißt schmaler und leiser, NICHT niedriger als das Touch-Ziel.
|
|
Die Höhe stand hier ursprünglich auf 40px — die Handy-Abnahme
|
|
(server/pruefe-webdesign-handy.mjs) hat das quer über alle Seiten
|
|
angemerkt: „Dieses Paket anfragen“, „Live ansehen“ und „Was genau
|
|
enthalten ist“ waren durchgehend 4px zu flach. 44px ist die Untergrenze,
|
|
ab der ein Ziel mit dem Daumen zuverlässig getroffen wird. */
|
|
.wd-btn--klein { min-height: 44px; padding: .6rem 1.05rem; font-size: .9rem; }
|
|
|
|
.wd-btn-reihe { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
5. HINWEISFLÄCHEN — Gold ist AUSSCHLIESSLICH hierfür reserviert
|
|
(Masterplan S.6: "Gold ausschließlich für wichtige Hinweise und
|
|
Zahlungsinformationen"). Wer Gold sieht, soll wissen: das ist wichtig.
|
|
--------------------------------------------------------------------- */
|
|
.wd-hinweis {
|
|
position: relative;
|
|
border-radius: var(--wd-r);
|
|
padding: 1.15rem 1.35rem 1.15rem 1.6rem;
|
|
background: linear-gradient(180deg, rgb(var(--wd-gold-rgb) / .09), rgb(var(--wd-gold-rgb) / .04));
|
|
border: 1px solid rgb(var(--wd-gold-rgb) / .32);
|
|
border-left: 4px solid var(--wd-gold);
|
|
}
|
|
.wd-hinweis-titel {
|
|
margin: 0 0 .35rem;
|
|
font-family: var(--font-head);
|
|
font-weight: 800;
|
|
font-size: .82rem;
|
|
letter-spacing: .12em;
|
|
text-transform: uppercase;
|
|
color: var(--wd-gold);
|
|
}
|
|
.wd-hinweis p { margin: 0; color: var(--wd-text-mid); font-size: .98rem; }
|
|
.wd-hinweis p + p { margin-top: .6rem; }
|
|
|
|
/* Neutrale Variante für Erklärungen, die NICHT wichtig-wichtig sind —
|
|
damit Gold seine Signalwirkung behält. */
|
|
.wd-notiz {
|
|
border-radius: var(--wd-r);
|
|
padding: 1rem 1.25rem;
|
|
background: rgb(var(--wd-blau-rgb) / .05);
|
|
border: 1px solid var(--wd-rand);
|
|
}
|
|
.wd-notiz p { margin: 0; font-size: .96rem; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
6. TAGS / KENNZEICHEN
|
|
--------------------------------------------------------------------- */
|
|
.wd-tag {
|
|
display: inline-flex; align-items: center; gap: .35rem;
|
|
padding: .3rem .7rem;
|
|
border-radius: 999px;
|
|
font-size: .78rem; font-weight: 700; letter-spacing: .04em;
|
|
background: rgb(var(--wd-blau-rgb) / .12);
|
|
border: 1px solid var(--wd-rand-stark);
|
|
color: var(--wd-blau-hell);
|
|
}
|
|
.wd-tag--lila { background: rgb(var(--wd-lila-rgb) / .12); border-color: rgb(var(--wd-lila-rgb) / .34); color: var(--wd-lila); }
|
|
.wd-tag--gold { background: rgb(var(--wd-gold-rgb) / .12); border-color: rgb(var(--wd-gold-rgb) / .34); color: var(--wd-gold); }
|
|
.wd-tag--ok { background: rgb(var(--wd-ok-rgb) / .12); border-color: rgb(var(--wd-ok-rgb) / .34); color: var(--wd-ok); }
|
|
.wd-tags { display: flex; flex-wrap: wrap; gap: .45rem; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
7. PREISKARTEN (Masterplan S.8)
|
|
Preis, Dauer und Personalisierungshinweis gehören sichtbar zusammen —
|
|
der Hinweis steht deshalb direkt unter dem Preis, nicht im Kleingedruckten.
|
|
--------------------------------------------------------------------- */
|
|
.wd-preis-karte { display: flex; flex-direction: column; }
|
|
.wd-preis {
|
|
font-family: var(--font-head);
|
|
font-weight: 800;
|
|
font-size: clamp(1.9rem, 4.4vw, 2.5rem);
|
|
line-height: 1.1;
|
|
margin: .2rem 0 .5rem;
|
|
color: var(--wd-blau);
|
|
}
|
|
.wd-karte--lila .wd-preis { color: var(--wd-lila); }
|
|
.wd-preis-zeile { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; margin-bottom: .5rem; }
|
|
.wd-preis-label { font-size: .78rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--wd-blau); }
|
|
.wd-karte--lila .wd-preis-label { color: var(--wd-lila); }
|
|
.wd-preis-wert { color: var(--wd-text-mid); font-size: .98rem; }
|
|
/* mt:auto schiebt den Knopf immer an den Kartenboden — sonst stehen die
|
|
Knöpfe in einer Reihe unterschiedlich hoher Karten treppenförmig. */
|
|
.wd-preis-karte .wd-btn { margin-top: auto; }
|
|
.wd-personalisierung {
|
|
margin-top: .2rem;
|
|
font-size: .88rem;
|
|
color: var(--wd-text-soft);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
8. NUMMERIERTE SCHRITTE (Ablauf / Customer Journey)
|
|
--------------------------------------------------------------------- */
|
|
.wd-schritte { display: grid; gap: 1rem; }
|
|
.wd-schritt {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: 1.1rem;
|
|
align-items: start;
|
|
border-radius: var(--wd-r-gross);
|
|
padding: 1.25rem 1.4rem;
|
|
background: linear-gradient(180deg, rgba(20, 32, 50, .55), rgba(9, 15, 26, .75));
|
|
border: 1px solid var(--wd-rand);
|
|
}
|
|
.wd-schritt-nr {
|
|
font-family: var(--font-head);
|
|
font-weight: 800;
|
|
font-size: clamp(1.4rem, 3vw, 1.9rem);
|
|
line-height: 1;
|
|
min-width: 2.2ch;
|
|
color: var(--wd-blau);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
.wd-schritt:nth-child(even) { border-color: rgb(var(--wd-lila-rgb) / .18); }
|
|
.wd-schritt:nth-child(even) .wd-schritt-nr { color: var(--wd-lila); }
|
|
.wd-schritt h3 { margin: 0 0 .3em; font-size: 1.12rem; }
|
|
.wd-schritt p { margin: 0; font-size: 1rem; }
|
|
@media (max-width: 520px) {
|
|
.wd-schritt { grid-template-columns: 1fr; gap: .4rem; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
9. FAQ — natives <details>, damit es ohne JavaScript funktioniert
|
|
und die Tastaturbedienung vom Browser kommt statt nachgebaut zu werden.
|
|
--------------------------------------------------------------------- */
|
|
.wd-faq { border-radius: var(--wd-r); border: 1px solid var(--wd-rand); background: rgb(var(--wd-glas-rgb) / .5); margin-bottom: .7rem; overflow: hidden; }
|
|
.wd-faq > summary {
|
|
cursor: pointer;
|
|
list-style: none;
|
|
padding: 1.05rem 3rem 1.05rem 1.25rem;
|
|
position: relative;
|
|
font-family: var(--font-head);
|
|
font-weight: 700;
|
|
font-size: 1.04rem;
|
|
color: var(--wd-text);
|
|
transition: background var(--wd-zeit-schnell) ease;
|
|
}
|
|
.wd-faq > summary::-webkit-details-marker { display: none; }
|
|
.wd-faq > summary:hover { background: rgb(var(--wd-blau-rgb) / .05); }
|
|
.wd-faq > summary::after {
|
|
content: "+";
|
|
position: absolute; right: 1.2rem; top: 50%; transform: translateY(-50%);
|
|
font-size: 1.5rem; line-height: 1; color: var(--wd-blau);
|
|
transition: transform var(--wd-zeit) ease;
|
|
}
|
|
.wd-faq[open] > summary::after { transform: translateY(-50%) rotate(45deg); }
|
|
.wd-faq-inhalt { padding: 0 1.25rem 1.15rem; }
|
|
.wd-faq-inhalt p { margin: 0; font-size: 1rem; }
|
|
.wd-faq-inhalt p + p { margin-top: .7rem; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
10. FORMULARE (Masterplan S.10 + S.15)
|
|
Zustände für Fehler und Erfolg sind Pflicht — und der Fehler steht
|
|
IMMER unter dem Feld, nie nur als Farbe: Farbe allein ist für
|
|
farbfehlsichtige Menschen keine Information.
|
|
--------------------------------------------------------------------- */
|
|
.wd-feld { margin-bottom: 1.15rem; }
|
|
.wd-feld > label,
|
|
.wd-feld-legende {
|
|
display: block;
|
|
margin-bottom: .45rem;
|
|
font-weight: 700;
|
|
font-size: .95rem;
|
|
color: var(--wd-text);
|
|
}
|
|
.wd-pflicht { color: var(--wd-blau); margin-left: .15rem; }
|
|
.wd-feld-hilfe { display: block; margin: -.2rem 0 .5rem; font-size: .88rem; color: var(--wd-text-soft); }
|
|
|
|
.wd-eingabe,
|
|
.wd-feld input[type="text"], .wd-feld input[type="email"], .wd-feld input[type="tel"],
|
|
.wd-feld input[type="url"], .wd-feld input[type="number"], .wd-feld input[type="date"],
|
|
.wd-feld input[type="password"], .wd-feld input[type="search"],
|
|
.wd-feld select, .wd-feld textarea {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
padding: .82rem 1rem;
|
|
min-height: 48px;
|
|
border-radius: 10px;
|
|
background: var(--wd-flaeche);
|
|
border: 1.5px solid var(--wd-rand);
|
|
color: var(--wd-text);
|
|
font-family: var(--font-body);
|
|
/* 16px verhindert, dass iOS beim Fokus in ein Feld hineinzoomt. */
|
|
font-size: 16px;
|
|
line-height: 1.5;
|
|
transition: border-color var(--wd-zeit-schnell) ease, box-shadow var(--wd-zeit-schnell) ease, background var(--wd-zeit-schnell) ease;
|
|
}
|
|
.wd-feld textarea { min-height: 130px; resize: vertical; }
|
|
.wd-feld select {
|
|
/* Eigener Pfeil: das Standard-Dreieck von Windows ist auf dunklem Grund
|
|
fast unsichtbar. */
|
|
appearance: none;
|
|
background-image: linear-gradient(45deg, transparent 50%, var(--wd-blau) 50%), linear-gradient(135deg, var(--wd-blau) 50%, transparent 50%);
|
|
background-position: calc(100% - 20px) center, calc(100% - 14px) center;
|
|
background-size: 6px 6px, 6px 6px;
|
|
background-repeat: no-repeat;
|
|
padding-right: 2.6rem;
|
|
}
|
|
.wd-feld ::placeholder { color: rgba(143, 159, 180, .7); }
|
|
.wd-eingabe:focus, .wd-feld input:focus, .wd-feld select:focus, .wd-feld textarea:focus {
|
|
outline: none;
|
|
border-color: var(--wd-blau);
|
|
background: #12203180;
|
|
box-shadow: 0 0 0 4px rgb(var(--wd-blau-rgb) / .16);
|
|
}
|
|
|
|
/* Fehlerzustand */
|
|
.wd-feld--fehler .wd-eingabe,
|
|
.wd-feld--fehler input, .wd-feld--fehler select, .wd-feld--fehler textarea {
|
|
border-color: var(--wd-fehler);
|
|
box-shadow: 0 0 0 4px rgb(var(--wd-fehler-rgb) / .12);
|
|
}
|
|
.wd-feld-fehler {
|
|
display: none;
|
|
margin: .45rem 0 0;
|
|
font-size: .9rem;
|
|
color: var(--wd-fehler);
|
|
font-weight: 600;
|
|
}
|
|
.wd-feld-fehler::before { content: "⚠ "; }
|
|
.wd-feld--fehler .wd-feld-fehler { display: block; }
|
|
|
|
/* Auswahlkacheln (Radio/Checkbox als anklickbare Fläche) — deutlich
|
|
fingerfreundlicher als native Punkte und zeigt den gewählten Zustand
|
|
nicht nur farblich, sondern über Rand + Häkchen. */
|
|
.wd-wahl { display: grid; gap: .7rem; }
|
|
.wd-wahl--2 { grid-template-columns: repeat(2, 1fr); }
|
|
@media (max-width: 640px) { .wd-wahl--2 { grid-template-columns: 1fr; } }
|
|
.wd-wahl-kachel { position: relative; display: block; cursor: pointer; }
|
|
.wd-wahl-kachel input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
|
.wd-wahl-inhalt {
|
|
display: block;
|
|
padding: 1rem 1.15rem 1rem 2.9rem;
|
|
border-radius: 14px;
|
|
background: rgb(var(--wd-glas-rgb) / .6);
|
|
border: 1.5px solid var(--wd-rand);
|
|
transition: border-color var(--wd-zeit-schnell) ease, background var(--wd-zeit-schnell) ease;
|
|
}
|
|
.wd-wahl-inhalt::before {
|
|
content: "";
|
|
position: absolute; left: 1rem; top: 1.15rem;
|
|
width: 20px; height: 20px; border-radius: 6px;
|
|
border: 2px solid var(--wd-rand-stark);
|
|
background: rgba(5, 7, 11, .6);
|
|
transition: border-color var(--wd-zeit-schnell) ease, background var(--wd-zeit-schnell) ease;
|
|
}
|
|
.wd-wahl-kachel input[type="radio"] + .wd-wahl-inhalt::before { border-radius: 50%; }
|
|
.wd-wahl-kachel:hover .wd-wahl-inhalt { border-color: var(--wd-rand-stark); }
|
|
.wd-wahl-kachel input:checked + .wd-wahl-inhalt {
|
|
border-color: var(--wd-blau);
|
|
background: rgb(var(--wd-blau-rgb) / .09);
|
|
}
|
|
.wd-wahl-kachel input:checked + .wd-wahl-inhalt::before {
|
|
border-color: var(--wd-blau);
|
|
background: var(--wd-blau);
|
|
/* Häkchen als CSS-Maske — kein Bild, keine Schriftart nötig. */
|
|
box-shadow: inset 0 0 0 3px #05070b, inset 0 0 0 20px var(--wd-blau);
|
|
}
|
|
.wd-wahl-kachel input:focus-visible + .wd-wahl-inhalt { outline: 3px solid var(--wd-blau); outline-offset: 3px; }
|
|
.wd-wahl-titel { display: block; font-weight: 700; color: var(--wd-text); }
|
|
.wd-wahl-text { display: block; font-size: .9rem; color: var(--wd-text-soft); margin-top: .15rem; }
|
|
|
|
/* Erfolgs-/Fehlermeldung eines ganzen Formulars */
|
|
.wd-meldung { border-radius: var(--wd-r); padding: 1rem 1.2rem; margin-bottom: 1.2rem; font-weight: 600; }
|
|
.wd-meldung--ok { background: rgb(var(--wd-ok-rgb) / .1); border: 1px solid rgb(var(--wd-ok-rgb) / .38); color: var(--wd-ok); }
|
|
.wd-meldung--fehler { background: rgb(var(--wd-fehler-rgb) / .1); border: 1px solid rgb(var(--wd-fehler-rgb) / .38); color: var(--wd-fehler); }
|
|
.wd-meldung[hidden] { display: none; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
11. FORTSCHRITT (mehrstufiges Formular)
|
|
--------------------------------------------------------------------- */
|
|
.wd-fortschritt { margin-bottom: 1.8rem; }
|
|
.wd-fortschritt-schiene { height: 6px; border-radius: 999px; background: rgb(var(--wd-blau-rgb) / .12); overflow: hidden; }
|
|
.wd-fortschritt-balken {
|
|
height: 100%; width: 0%;
|
|
border-radius: 999px;
|
|
background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau));
|
|
transition: width var(--wd-zeit-lang) cubic-bezier(.4, 0, .2, 1);
|
|
}
|
|
.wd-fortschritt-text { margin: .6rem 0 0; font-size: .88rem; color: var(--wd-text-soft); }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
12. TABELLEN (Verwaltung / Portal)
|
|
Auf schmalen Bildschirmen scrollt die Tabelle waagerecht in ihrem
|
|
eigenen Kasten, statt die ganze Seite zu verbreitern.
|
|
--------------------------------------------------------------------- */
|
|
.wd-tabelle-rahmen { overflow-x: auto; border-radius: var(--wd-r); border: 1px solid var(--wd-rand); }
|
|
.wd-tabelle { width: 100%; border-collapse: collapse; font-size: .95rem; min-width: 560px; }
|
|
.wd-tabelle th, .wd-tabelle td { padding: .8rem 1rem; text-align: left; border-bottom: 1px solid var(--wd-rand); }
|
|
.wd-tabelle th {
|
|
font-family: var(--font-head); font-size: .78rem; font-weight: 800;
|
|
letter-spacing: .1em; text-transform: uppercase; color: var(--wd-blau);
|
|
background: rgb(var(--wd-blau-rgb) / .05);
|
|
position: sticky; top: 0;
|
|
}
|
|
.wd-tabelle tbody tr:last-child td { border-bottom: none; }
|
|
.wd-tabelle tbody tr:hover { background: rgb(var(--wd-blau-rgb) / .04); }
|
|
.wd-tabelle td { color: var(--wd-text-mid); }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
13. BEWEGUNG — "kontrolliert beim Scrollen" (Masterplan S.6)
|
|
Die Elemente starten sichtbar und werden erst per JS auf unsichtbar
|
|
gesetzt (Klasse .wd-bereit am <html>). Ohne JavaScript oder bei einem
|
|
Skriptfehler bleibt dadurch ALLES lesbar — der häufigste schwere Fehler
|
|
bei Scroll-Animationen ist eine dauerhaft unsichtbare Seite.
|
|
--------------------------------------------------------------------- */
|
|
.wd-bereit .wd-auf {
|
|
opacity: 0;
|
|
transform: translateY(18px);
|
|
transition: opacity var(--wd-zeit-lang) ease, transform var(--wd-zeit-lang) cubic-bezier(.22, 1, .36, 1);
|
|
}
|
|
.wd-bereit .wd-auf.wd-sichtbar { opacity: 1; transform: none; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
14. KOPF- UND FUSSZEILE des Webdesign-Bereichs
|
|
Eigene Leiste statt der Universe-Navigation: der Bereich hat eigene
|
|
Ziele (Anfrage statt Bewerbung) und ist bis zur Freigabe nicht
|
|
öffentlich. Der Rückweg ins Universe steht trotzdem immer sichtbar
|
|
drin (Masterplan S.14 "Direkte Navigation zwischen Universe und
|
|
Webdesign").
|
|
--------------------------------------------------------------------- */
|
|
.wd-kopf {
|
|
position: sticky; top: 0; z-index: 60;
|
|
background: rgba(5, 7, 11, .92);
|
|
backdrop-filter: blur(14px);
|
|
border-bottom: 1px solid var(--wd-rand);
|
|
}
|
|
.wd-kopf-bar {
|
|
width: min(1320px, 94vw); margin: 0 auto;
|
|
display: flex; align-items: center; gap: 1rem;
|
|
padding: .7rem 0;
|
|
}
|
|
/* min-height 44px: die Marke ist ein Link auf die Startseite und damit
|
|
ein echtes Touch-Ziel — sie war vorher exakt so hoch wie das Logo (42px). */
|
|
.wd-marke { display: flex; align-items: center; gap: .65rem; flex-shrink: 0; min-height: 44px; }
|
|
.wd-marke img { width: 42px; height: 42px; object-fit: contain; }
|
|
.wd-marke-text { display: flex; flex-direction: column; line-height: 1.1; }
|
|
.wd-marke-oben { font-family: var(--font-head); font-weight: 800; font-size: 1rem; color: var(--wd-text); letter-spacing: .02em; }
|
|
.wd-marke-unten { font-size: 0.75rem; letter-spacing: .18em; text-transform: uppercase; color: var(--wd-blau); font-weight: 700; }
|
|
|
|
.wd-nav { display: flex; align-items: center; gap: .15rem; margin-left: auto; }
|
|
.wd-nav a {
|
|
/* inline-flex + min-height statt nur Innenabstand: mit reinem padding
|
|
kam der Menüpunkt auf 43px — einen Pixel unter dem Touch-Ziel, was
|
|
die Handy-Abnahme zu Recht angemerkt hat. */
|
|
display: inline-flex; align-items: center; min-height: 44px;
|
|
padding: .5rem .8rem; border-radius: 10px;
|
|
font-size: .95rem; font-weight: 600; color: var(--wd-text-mid);
|
|
transition: color var(--wd-zeit-schnell) ease, background var(--wd-zeit-schnell) ease;
|
|
}
|
|
.wd-nav a:hover { color: var(--wd-text); background: rgb(var(--wd-blau-rgb) / .07); }
|
|
.wd-nav a.wd-aktiv { color: var(--wd-blau); background: rgb(var(--wd-blau-rgb) / .11); }
|
|
.wd-nav .wd-btn { margin-left: .5rem; }
|
|
|
|
.wd-menue-knopf {
|
|
display: none; margin-left: auto;
|
|
align-items: center; gap: .45rem;
|
|
min-height: 44px; padding: .5rem .9rem;
|
|
border-radius: 10px; border: 1px solid var(--wd-rand);
|
|
background: transparent; color: var(--wd-text); cursor: pointer; font-weight: 700;
|
|
}
|
|
|
|
/* Sprachschalter — teilt sich die gespeicherte Sprache mit dem Universe
|
|
(localStorage "dogi-sprache"), damit ein Wechsel hier auch dort gilt. */
|
|
.wd-sprache { position: relative; }
|
|
.wd-sprache-knopf {
|
|
display: inline-flex; align-items: center; gap: .35rem;
|
|
/* 44px statt 40px — auch auf dem Computer ist das der bessere Wert:
|
|
Touchscreen-Laptops und Tablets im Querformat landen ebenfalls hier. */
|
|
min-height: 44px; padding: .5rem .75rem;
|
|
border-radius: 10px; border: 1px solid var(--wd-rand);
|
|
background: transparent; color: var(--wd-text-mid); cursor: pointer;
|
|
font-weight: 700; font-size: .88rem;
|
|
}
|
|
.wd-sprache-knopf:hover { color: var(--wd-text); border-color: var(--wd-rand-stark); }
|
|
.wd-sprache-liste {
|
|
position: absolute; right: 0; top: calc(100% + .4rem);
|
|
min-width: 190px; padding: .35rem;
|
|
border-radius: 10px;
|
|
background: #0b1320;
|
|
border: 1px solid var(--wd-rand-stark);
|
|
box-shadow: var(--wd-schatten);
|
|
display: none;
|
|
z-index: 70;
|
|
}
|
|
.wd-sprache.wd-offen .wd-sprache-liste { display: block; }
|
|
.wd-sprache-liste button {
|
|
display: flex; align-items: center; gap: .6rem;
|
|
width: 100%; min-height: 42px; padding: .5rem .7rem;
|
|
border: none; border-radius: 10px; background: transparent;
|
|
color: var(--wd-text-mid); cursor: pointer; text-align: left; font-size: .95rem;
|
|
}
|
|
.wd-sprache-liste button:hover { background: rgb(var(--wd-blau-rgb) / .09); color: var(--wd-text); }
|
|
.wd-sprache-liste button[aria-current="true"] { color: var(--wd-blau); font-weight: 700; }
|
|
.wd-sprache-punkt { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
|
|
|
|
@media (max-width: 1080px) {
|
|
.wd-menue-knopf { display: inline-flex; }
|
|
.wd-nav {
|
|
display: none;
|
|
position: absolute; left: 0; right: 0; top: 100%;
|
|
flex-direction: column; align-items: stretch; gap: .2rem;
|
|
padding: .8rem 4vw 1.2rem;
|
|
background: #070b12;
|
|
border-bottom: 1px solid var(--wd-rand);
|
|
box-shadow: var(--wd-schatten);
|
|
/* Vollbildnavigation auf dem Handy (Masterplan S.5), aber scrollbar —
|
|
bei 8 Punkten + Sprachschalter passt sonst nicht alles auf ein
|
|
kleines Display. */
|
|
max-height: calc(100dvh - 70px);
|
|
overflow-y: auto;
|
|
}
|
|
.wd-nav.wd-offen { display: flex; }
|
|
/* Die minimale Kopfzeile (Zugangswand) enthält nur den Sprachschalter und
|
|
hat deshalb bewusst keinen Menü-Knopf. Ohne diese Ausnahme wäre sie auf
|
|
dem Handy durch die Regel oben komplett unsichtbar — man könnte die
|
|
Sprache dort dann gar nicht mehr umstellen. */
|
|
.wd-nav--minimal {
|
|
display: flex; position: static; flex-direction: row;
|
|
padding: 0; background: none; border: none; box-shadow: none;
|
|
max-height: none; overflow: visible; width: auto;
|
|
}
|
|
.wd-nav--minimal .wd-sprache { margin-top: 0; }
|
|
.wd-nav--minimal .wd-sprache-knopf { width: auto; }
|
|
.wd-nav--minimal .wd-sprache-liste { position: absolute; width: auto; }
|
|
.wd-nav a { padding: .8rem .9rem; font-size: 1.02rem; }
|
|
.wd-nav .wd-btn { margin: .6rem 0 0; }
|
|
.wd-sprache { margin-top: .6rem; }
|
|
.wd-sprache-knopf { width: 100%; justify-content: center; }
|
|
.wd-sprache-liste { position: static; width: 100%; margin-top: .4rem; }
|
|
}
|
|
|
|
/* Fußzeile */
|
|
.wd-fuss { border-top: 1px solid var(--wd-rand); background: rgba(5, 7, 11, .8); padding: 2.6rem 0 2rem; margin-top: 3rem; }
|
|
.wd-fuss-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2rem; }
|
|
@media (max-width: 780px) { .wd-fuss-grid { grid-template-columns: 1fr; gap: 1.5rem; } }
|
|
/* Die Spaltenueberschriften der Fusszeile sind jetzt h2 statt h4.
|
|
|
|
Grund: Sie folgten im Dokument auf die h2 der Seite -- ein Sprung von
|
|
h2 direkt auf h4. Wer sich mit einem Screenreader durch die
|
|
Ueberschriften bewegt, hoert dabei eine Gliederung, die es nicht gibt,
|
|
und vermutet uebersprungene Abschnitte (WCAG 1.3.1). Auf allen 13
|
|
Seiten in allen 5 Sprachen -- also 42 Stellen.
|
|
|
|
Die Klasse haelt die Optik unveraendert: Die Ebene sagt etwas ueber
|
|
die STRUKTUR, die Groesse ueber die GEWICHTUNG. Das sind zwei
|
|
verschiedene Dinge, und man soll das eine nicht ueber das andere
|
|
erzwingen muessen. */
|
|
.wd-fuss .wd-fuss-h, .wd-fuss h4 {
|
|
font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
|
|
color: var(--wd-blau); margin: 0 0 .8rem; font-weight: 700;
|
|
font-family: var(--font-head);
|
|
}
|
|
.wd-fuss ul li { margin-bottom: .1rem; }
|
|
/* Fußzeilenlinks waren nur so hoch wie ihre Zeile (20px) und damit auf dem
|
|
Handy praktisch nicht sicher zu treffen — sie liegen zudem dicht
|
|
untereinander, was Fehlgriffe zusätzlich begünstigt. Als inline-flex mit
|
|
Mindesthöhe sind sie ein ordentliches Touch-Ziel; die Fußzeile wird
|
|
dadurch etwas höher, was hier die richtige Abwägung ist. */
|
|
.wd-fuss a {
|
|
display: inline-flex; align-items: center; min-height: 44px;
|
|
color: var(--wd-text-mid); font-size: .95rem;
|
|
}
|
|
/* Die Marke in der Fußzeile bringt ihre eigene Höhe mit. */
|
|
.wd-fuss a.wd-marke { min-height: 48px; }
|
|
.wd-fuss a:hover { color: var(--wd-blau); }
|
|
.wd-fuss-unten {
|
|
margin-top: 2rem; padding-top: 1.2rem;
|
|
border-top: 1px solid var(--wd-rand);
|
|
display: flex; flex-wrap: wrap; gap: .8rem; justify-content: space-between;
|
|
font-size: .86rem; color: var(--wd-text-soft);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
15. HERO
|
|
"Der erste Bildschirm enthält niemals zu viel Text" (Masterplan S.7).
|
|
min-height bewusst mit svh: 100vh ist auf dem Handy die Höhe OHNE
|
|
Adressleiste — der Knopf rutscht damit beim ersten Laden unter die
|
|
sichtbare Kante, genau das, was die Hero-Regel verbietet.
|
|
--------------------------------------------------------------------- */
|
|
.wd-hero { position: relative; padding: clamp(2.6rem, 6vw, 4.6rem) 0 clamp(2.2rem, 4vw, 3.4rem); min-height: 68svh; display: flex; align-items: center; }
|
|
.wd-hero-inhalt { max-width: 780px; }
|
|
.wd-hero h1 { margin-bottom: .45em; }
|
|
.wd-hero .wd-lead { margin-bottom: 1.8rem; max-width: 62ch; }
|
|
.wd-hero-glanz {
|
|
/* Kein Farbverlauf über den ganzen Titel — nur die Kernaussage trägt ihn,
|
|
sonst leidet die Lesbarkeit langer Überschriften. */
|
|
background: linear-gradient(120deg, var(--wd-blau-hell), var(--wd-blau) 45%, var(--wd-lila));
|
|
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
}
|
|
.wd-hero-belege { display: flex; flex-wrap: wrap; gap: .5rem 1.4rem; margin-top: 2rem; }
|
|
.wd-hero-beleg { display: flex; align-items: center; gap: .45rem; font-size: .92rem; color: var(--wd-text-soft); }
|
|
.wd-hero-beleg::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--wd-blau); box-shadow: 0 0 8px var(--wd-blau); }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
16. INSTALLATIONS-HINWEIS ("Als App installieren")
|
|
Sitzt unten statt oben: oben würde er die Kopfzeile verdecken, und auf
|
|
dem Handy ist der Daumen unten. env(safe-area-inset-bottom) hält ihn
|
|
über der Gestenleiste neuerer iPhones — ohne das liegt der Schließen-
|
|
Knopf genau unter dem Strich und ist praktisch nicht treffbar.
|
|
--------------------------------------------------------------------- */
|
|
.wd-install {
|
|
position: fixed; z-index: 80;
|
|
left: 50%; transform: translateX(-50%);
|
|
bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
|
|
width: min(560px, calc(100vw - 1.6rem));
|
|
display: flex; align-items: center; gap: 1rem;
|
|
padding: .85rem 1rem;
|
|
border-radius: var(--wd-r);
|
|
background: rgba(11, 19, 32, .97);
|
|
border: 1px solid var(--wd-rand-stark);
|
|
box-shadow: var(--wd-schatten-tief);
|
|
backdrop-filter: blur(12px);
|
|
animation: wd-install-auf .45s cubic-bezier(.22, 1, .36, 1) both;
|
|
}
|
|
@keyframes wd-install-auf { from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translate(-50%, 0); } }
|
|
.wd-install-text { display: flex; align-items: center; gap: .8rem; flex: 1; min-width: 0; }
|
|
.wd-install-text img { border-radius: 10px; flex-shrink: 0; }
|
|
.wd-install-text strong { display: block; font-size: .95rem; color: var(--wd-text); }
|
|
.wd-install-text span { display: block; font-size: .84rem; color: var(--wd-text-soft); line-height: 1.45; }
|
|
.wd-install-knoepfe { display: flex; align-items: center; gap: .4rem; flex-shrink: 0; }
|
|
.wd-install-knoepfe .wd-btn--still { min-width: 44px; padding: .5rem .7rem; }
|
|
@media (max-width: 560px) {
|
|
/* Auf schmalen Bildschirmen untereinander — nebeneinander wird der Text
|
|
auf zwei Wörter pro Zeile gequetscht. */
|
|
.wd-install { flex-direction: column; align-items: stretch; gap: .7rem; }
|
|
.wd-install-knoepfe { justify-content: flex-end; }
|
|
.wd-install-knoepfe .wd-btn--haupt { flex: 1; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
17. BEWEGUNGSREDUKTION — eine Regel für alles
|
|
--------------------------------------------------------------------- */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
:root { --wd-zeit-schnell: 0s; --wd-zeit: 0s; --wd-zeit-lang: 0s; }
|
|
.wd *, .wd *::before, .wd *::after {
|
|
animation-duration: .001ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: .001ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
/* Wichtig: die Einblend-Elemente müssen dann SOFORT sichtbar sein,
|
|
nicht "unsichtbar mit 0s Übergang". */
|
|
.wd-bereit .wd-auf { opacity: 1; transform: none; }
|
|
.wd-btn:hover, a.wd-karte:hover, .wd-karte--klickbar:hover { transform: none; }
|
|
}
|
|
|
|
/* Druckansicht: Angebote/Zusammenfassungen werden erfahrungsgemäß
|
|
ausgedruckt oder als PDF gesichert. */
|
|
@media print {
|
|
body.wd { background: #fff; color: #000; }
|
|
body.wd::before, body.wd::after, .wd-kopf, .wd-fuss, .wd-btn { display: none !important; }
|
|
.wd-karte { border: 1px solid #bbb; background: #fff; box-shadow: none; }
|
|
.wd h1, .wd h2, .wd h3, .wd p, .wd li { color: #000 !important; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
18. LEERER ZUSTAND IM KUNDENPORTAL
|
|
|
|
Ein leerer Bereich mit einem einzigen Satz ist eine verpasste
|
|
Gelegenheit. Wer hier zum ersten Mal landet, hat gerade sein Passwort
|
|
gesetzt und weiß noch nicht, was ihn erwartet — genau dann entscheidet
|
|
sich, ob die Seite souverän wirkt oder unfertig.
|
|
|
|
Deshalb zeigt der leere Zustand, WAS gleich hier stehen wird, statt
|
|
nur festzustellen, dass gerade nichts da ist.
|
|
--------------------------------------------------------------------- */
|
|
.po-leer { text-align: center; padding: clamp(1.6rem, 4vw, 2.6rem) clamp(1rem, 3vw, 2rem); }
|
|
.po-leer-symbol { width: clamp(64px, 12vw, 92px); margin: 0 auto .9rem; position: relative; }
|
|
.po-leer-symbol img { width: 100%; height: auto; opacity: .9; }
|
|
.po-leer-symbol::before {
|
|
content: ""; position: absolute; inset: -24%; z-index: -1; border-radius: 50%;
|
|
background: radial-gradient(circle, rgb(var(--wd-blau-rgb) / .26), transparent 70%);
|
|
filter: blur(20px);
|
|
}
|
|
.po-leer h3 { margin-bottom: .3em; }
|
|
.po-leer > p { max-width: 48ch; margin-left: auto; margin-right: auto; }
|
|
|
|
.po-leer-liste {
|
|
display: grid; grid-template-columns: repeat(2, 1fr); gap: .9rem;
|
|
margin: 1.6rem 0 1.2rem; text-align: left;
|
|
}
|
|
@media (max-width: 640px) { .po-leer-liste { grid-template-columns: 1fr; } }
|
|
.po-leer-punkt {
|
|
display: grid; grid-template-columns: auto 1fr; gap: .8rem; align-items: start;
|
|
padding: .9rem 1rem; border-radius: 14px;
|
|
background: rgb(var(--wd-blau-rgb) / .05); border: 1px solid var(--wd-rand);
|
|
}
|
|
.po-leer-nr {
|
|
width: 28px; height: 28px; border-radius: 50%;
|
|
display: flex; align-items: center; justify-content: center;
|
|
font-family: var(--font-head); font-weight: 800; font-size: .85rem;
|
|
color: var(--wd-blau); background: rgb(var(--wd-blau-rgb) / .12);
|
|
border: 1px solid var(--wd-rand-stark);
|
|
}
|
|
.po-leer-punkt strong { display: block; color: var(--wd-text); font-size: .98rem; margin-bottom: .15rem; }
|
|
/* :not(.po-leer-nr) ist hier PFLICHT, kein Feinschliff.
|
|
Der Zahlenkreis ist ebenfalls ein <span> in dieser Kachel. Ohne den
|
|
Ausschluss trifft ihn diese Regel mit -- und sie ist spezifischer
|
|
(Klasse + Element) als ".po-leer-nr" (nur Klasse). Sie erzwang dadurch
|
|
display:block, Schriftgroesse 14,4px und Zeilenhoehe 23px; die Ziffer
|
|
sass 15px neben der Kreismitte, statt darin.
|
|
Gemeldet am 22.08.2026 ("wieso sehen die zahlen immer noch so
|
|
scheisse aus?") und per Messung bestaetigt. Derselbe Spezifitaets-
|
|
Fehler wie zuvor beim Hauptknopf (blau auf blau) und bei den Namen auf
|
|
der Zugangswand -- deshalb steht die Begruendung hier so ausfuehrlich. */
|
|
.po-leer-punkt span:not(.po-leer-nr) { display: block; font-size: .88rem; color: var(--wd-text-soft); line-height: 1.5; }
|
|
.po-leer-fuss { margin: 0; }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
19. VORSCHAU IM LEEREN PORTAL
|
|
|
|
Die erste Fassung BESCHRIEB, was hier bald stehen wird ("Eine Leiste
|
|
zeigt dir, in welcher Phase dein Projekt ist"). Beschreibungen sind
|
|
schwach — man muss sie lesen und sich dann etwas vorstellen.
|
|
|
|
Diese Fassung ZEIGT es: eine echte, halbdurchsichtige Projektkarte,
|
|
deren Phasenleiste langsam durchläuft. Man sieht in zwei Sekunden, was
|
|
drei Sätze nicht erklären. Genau das ist der Unterschied zwischen
|
|
"erklärt" und "verstanden".
|
|
|
|
Die Karte ist bewusst als Vorschau erkennbar (gedämpft, mit Etikett) —
|
|
sie darf nie mit einem echten Projekt verwechselt werden.
|
|
--------------------------------------------------------------------- */
|
|
.po-vorschau {
|
|
position: relative;
|
|
border-radius: var(--wd-r-gross);
|
|
padding: clamp(1.1rem, 2.6vw, 1.5rem);
|
|
background: linear-gradient(180deg, rgba(20,32,50,.5), rgba(9,15,26,.66));
|
|
border: 1px dashed var(--wd-rand-stark);
|
|
text-align: left;
|
|
overflow: hidden;
|
|
}
|
|
.po-vorschau::after {
|
|
/* Sanfter Lichtstreifen, der einmal langsam durchwandert. Er sagt ohne
|
|
Worte "hier passiert gleich etwas", ohne zu blinken oder zu zappeln. */
|
|
content: "";
|
|
position: absolute; inset: 0;
|
|
background: linear-gradient(105deg, transparent 35%, rgb(var(--wd-blau-rgb) / .07) 50%, transparent 65%);
|
|
background-size: 260% 100%;
|
|
animation: po-schimmer 5.5s ease-in-out infinite;
|
|
pointer-events: none;
|
|
}
|
|
@keyframes po-schimmer { 0% { background-position: 130% 0; } 60%, 100% { background-position: -130% 0; } }
|
|
|
|
.po-vorschau-etikett {
|
|
position: absolute; top: .7rem; right: .8rem;
|
|
font-size: 0.75rem; letter-spacing: .14em; text-transform: uppercase;
|
|
font-weight: 800; color: var(--wd-text-soft);
|
|
padding: .2rem .55rem; border-radius: 999px;
|
|
background: rgba(5,7,11,.7); border: 1px solid var(--wd-rand);
|
|
}
|
|
.po-vorschau-nr { font-family: var(--font-head); font-weight: 800; font-size: .78rem; color: var(--wd-blau); opacity: .75; }
|
|
.po-vorschau h4 { margin: .15rem 0 .6rem; font-size: clamp(1.05rem, 2.4vw, 1.25rem); color: var(--wd-text); opacity: .85; }
|
|
|
|
/* Die laufende Phasenleiste — der eigentliche Kern der Vorschau. */
|
|
.po-vorschau-phasen { display: flex; gap: 3px; margin-bottom: .5rem; }
|
|
.po-vorschau-phasen span {
|
|
flex: 1; height: 6px; border-radius: 999px;
|
|
background: rgb(var(--wd-blau-rgb) / .13);
|
|
animation: po-phase-lauf 7s ease-in-out infinite;
|
|
}
|
|
.po-vorschau-phasen span:nth-child(1) { animation-delay: 0s; }
|
|
.po-vorschau-phasen span:nth-child(2) { animation-delay: .55s; }
|
|
.po-vorschau-phasen span:nth-child(3) { animation-delay: 1.1s; }
|
|
.po-vorschau-phasen span:nth-child(4) { animation-delay: 1.65s; }
|
|
.po-vorschau-phasen span:nth-child(5) { animation-delay: 2.2s; }
|
|
.po-vorschau-phasen span:nth-child(6) { animation-delay: 2.75s; }
|
|
.po-vorschau-phasen span:nth-child(7) { animation-delay: 3.3s; }
|
|
@keyframes po-phase-lauf {
|
|
0%, 8% { background: rgb(var(--wd-blau-rgb) / .13); }
|
|
14%, 55% { background: var(--wd-blau-tief); }
|
|
100% { background: rgb(var(--wd-blau-rgb) / .13); }
|
|
}
|
|
|
|
.po-vorschau-zeile { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-size: .82rem; color: var(--wd-text-soft); }
|
|
.po-vorschau-marke {
|
|
display: inline-flex; align-items: center; gap: .3rem;
|
|
padding: .18rem .55rem; border-radius: 999px; font-size: 0.8rem; font-weight: 700;
|
|
background: rgb(var(--wd-blau-rgb) / .12); color: var(--wd-blau);
|
|
}
|
|
.po-vorschau-schritt { margin: .7rem 0 0; font-size: .88rem; color: var(--wd-text-mid); opacity: .8; }
|
|
|
|
/* Bewegungsreduktion: keine Animation, aber die Leiste soll trotzdem
|
|
etwas zeigen — sonst steht dort eine leere graue Reihe. */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.po-vorschau::after { animation: none; }
|
|
.po-vorschau-phasen span { animation: none; }
|
|
.po-vorschau-phasen span:nth-child(-n+3) { background: var(--wd-blau-tief); }
|
|
}
|
|
|
|
/* Die vier Merkmale kompakter und mit farbigem Akzent statt nur Nummer. */
|
|
.po-leer-punkt { transition: border-color var(--wd-zeit-schnell) ease, background var(--wd-zeit-schnell) ease; }
|
|
.po-leer-punkt:hover { border-color: var(--wd-rand-stark); background: rgb(var(--wd-blau-rgb) / .08); }
|
|
.po-leer-nr {
|
|
background: linear-gradient(135deg, rgb(var(--wd-blau-rgb) / .22), rgb(var(--wd-lila-rgb) / .18));
|
|
color: var(--wd-blau-hell); border-color: var(--wd-rand-stark);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
20. LEERER ZUSTAND — GEHOBENE FASSUNG
|
|
|
|
Drei Rückmeldungen vom 22.08.2026, alle drei berechtigt:
|
|
"Schrift und Kacheln sollen viel spezieller sein", "die Zahlen sollen
|
|
besser im Kreis sein", "die Kisten sollen eine spezielle Farbe
|
|
bekommen wenn sie fertig sind".
|
|
|
|
Der letzte Punkt war der wichtigste und inhaltlich der schwerste:
|
|
Vorher waren erledigte und laufende Phase fast gleich blau. Damit ging
|
|
die einzige Information verloren, die die Leiste überhaupt trägt —
|
|
nämlich WO man gerade steht. Jetzt sind es drei klar verschiedene
|
|
Zustände: erledigt (grün), gerade dran (leuchtendes Blau mit Puls),
|
|
kommt noch (gedämpft).
|
|
--------------------------------------------------------------------- */
|
|
|
|
/* ---------- Zahlenkreise ----------
|
|
Vorher ein flacher Kreis mit Zahl. Jetzt ein doppelter Ring: außen ein
|
|
Farbverlauf als Rand, innen die dunkle Fläche. Das ist derselbe Kniff
|
|
wie bei den Karten (Verlauf über border-box) und lässt den Kreis
|
|
plastisch wirken, statt aufgemalt. */
|
|
.po-leer-nr {
|
|
width: 40px; height: 40px; border-radius: 50%;
|
|
font-size: 1.02rem; font-weight: 800;
|
|
color: var(--wd-blau-hell);
|
|
border: 2px solid transparent;
|
|
background:
|
|
linear-gradient(#0c1523, #0c1523) padding-box,
|
|
linear-gradient(140deg, var(--wd-blau), var(--wd-lila)) border-box;
|
|
box-shadow: 0 0 18px -6px rgb(var(--wd-blau-rgb) / .55);
|
|
flex-shrink: 0;
|
|
font-variant-numeric: tabular-nums;
|
|
letter-spacing: -.02em;
|
|
}
|
|
|
|
/* ---------- Merkmalskacheln ----------
|
|
Jede bekommt oben eine eigene Farbkante. Vier gleiche Kacheln wirken
|
|
wie eine Aufzählung; vier unterscheidbare wirken wie ein System. */
|
|
.po-leer-punkt {
|
|
position: relative;
|
|
overflow: hidden;
|
|
padding: 1.1rem 1.15rem 1.15rem;
|
|
border-radius: 14px;
|
|
gap: 1rem;
|
|
background: linear-gradient(180deg, rgba(20, 32, 50, .58), rgba(9, 15, 26, .74));
|
|
}
|
|
.po-leer-punkt::before {
|
|
content: "";
|
|
position: absolute; top: 0; left: 0; right: 0; height: 3px;
|
|
background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau));
|
|
opacity: .8;
|
|
}
|
|
.po-leer-punkt:nth-child(2)::before { background: linear-gradient(90deg, var(--wd-lila-tief), var(--wd-lila)); }
|
|
.po-leer-punkt:nth-child(3)::before { background: linear-gradient(90deg, #2e8f6b, var(--wd-ok)); }
|
|
.po-leer-punkt:nth-child(4)::before { background: linear-gradient(90deg, var(--wd-gold-tief), var(--wd-gold)); }
|
|
.po-leer-punkt:nth-child(2) .po-leer-nr {
|
|
color: var(--wd-lila);
|
|
background: linear-gradient(#0c1523, #0c1523) padding-box,
|
|
linear-gradient(140deg, var(--wd-lila), var(--wd-blau)) border-box;
|
|
box-shadow: 0 0 18px -6px rgb(var(--wd-lila-rgb) / .55);
|
|
}
|
|
.po-leer-punkt:nth-child(3) .po-leer-nr {
|
|
color: var(--wd-ok);
|
|
background: linear-gradient(#0c1523, #0c1523) padding-box,
|
|
linear-gradient(140deg, var(--wd-ok), var(--wd-blau)) border-box;
|
|
box-shadow: 0 0 18px -6px rgb(var(--wd-ok-rgb) / .5);
|
|
}
|
|
.po-leer-punkt:nth-child(4) .po-leer-nr {
|
|
color: var(--wd-gold);
|
|
background: linear-gradient(#0c1523, #0c1523) padding-box,
|
|
linear-gradient(140deg, var(--wd-gold), var(--wd-lila)) border-box;
|
|
box-shadow: 0 0 18px -6px rgb(var(--wd-gold-rgb) / .5);
|
|
}
|
|
|
|
/* ---------- Typografie ----------
|
|
Die Überschrift der Kachel war so groß wie der Fließtext darunter und
|
|
ging dadurch unter. Jetzt größer, enger gesetzt und mit einem Hauch
|
|
negativer Laufweite — das ist der Unterschied, den man als "wertig"
|
|
empfindet, ohne ihn benennen zu können. */
|
|
.po-leer-punkt strong {
|
|
font-family: var(--font-head);
|
|
font-size: 1.06rem; font-weight: 800;
|
|
letter-spacing: -.015em; line-height: 1.25;
|
|
margin-bottom: .3rem;
|
|
}
|
|
.po-leer-punkt span:not(.po-leer-nr) { font-size: .9rem; line-height: 1.6; }
|
|
|
|
.po-leer h3 {
|
|
font-size: clamp(1.5rem, 3.6vw, 2rem);
|
|
letter-spacing: -.02em;
|
|
background: linear-gradient(120deg, var(--wd-text), var(--wd-blau-hell) 70%);
|
|
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
}
|
|
.po-leer > p { font-size: 1.02rem; }
|
|
|
|
/* ---------- Phasen: drei klar verschiedene Zustände ----------
|
|
Das war der eigentliche Mangel. Erledigt und laufend sahen fast gleich
|
|
aus — damit ging die einzige Aussage der Leiste verloren. */
|
|
.po-phase, .po-vorschau-phasen span { height: 7px; }
|
|
.po-phase.po-erledigt {
|
|
background: linear-gradient(90deg, #2e8f6b, var(--wd-ok));
|
|
box-shadow: 0 0 8px -2px rgb(var(--wd-ok-rgb) / .5);
|
|
}
|
|
.po-phase.po-jetzt {
|
|
background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau));
|
|
box-shadow: 0 0 14px -2px rgb(var(--wd-blau-rgb) / .85);
|
|
animation: po-jetzt-puls 2.4s ease-in-out infinite;
|
|
}
|
|
@keyframes po-jetzt-puls { 0%, 100% { opacity: .82; } 50% { opacity: 1; } }
|
|
@media (prefers-reduced-motion: reduce) { .po-phase.po-jetzt { animation: none; opacity: 1; } }
|
|
|
|
/* Dieselbe Logik in der Vorschau: die durchlaufende Leiste wechselt von
|
|
"gerade dran" (blau) nach "erledigt" (grün), statt einfach nur an- und
|
|
auszugehen. Damit erklärt die Vorschau die Farblogik gleich mit. */
|
|
@keyframes po-phase-lauf {
|
|
0%, 8% { background: rgb(var(--wd-blau-rgb) / .13); box-shadow: none; }
|
|
14%, 30% { background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau));
|
|
box-shadow: 0 0 12px -2px rgb(var(--wd-blau-rgb) / .8); }
|
|
38%, 62% { background: linear-gradient(90deg, #2e8f6b, var(--wd-ok));
|
|
box-shadow: 0 0 8px -2px rgb(var(--wd-ok-rgb) / .45); }
|
|
100% { background: rgb(var(--wd-blau-rgb) / .13); box-shadow: none; }
|
|
}
|
|
|
|
/* Kleine Legende unter der Vorschau, damit die Farben nicht geraten
|
|
werden müssen. Farbe allein ist nie Information. */
|
|
.po-legende {
|
|
display: flex; flex-wrap: wrap; gap: .5rem 1.1rem;
|
|
margin-top: .9rem; font-size: .78rem; color: var(--wd-text-soft);
|
|
}
|
|
.po-legende span { display: inline-flex; align-items: center; gap: .4rem; }
|
|
.po-legende i {
|
|
width: 16px; height: 6px; border-radius: 999px; display: inline-block;
|
|
}
|
|
.po-legende .po-l-fertig { background: linear-gradient(90deg, #2e8f6b, var(--wd-ok)); }
|
|
.po-legende .po-l-jetzt { background: linear-gradient(90deg, var(--wd-blau-tief), var(--wd-blau)); }
|
|
.po-legende .po-l-offen { background: rgb(var(--wd-blau-rgb) / .18); }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
21. ZAHLENKREISE REPARIERT + VIER PROZESSFARBEN
|
|
|
|
a) "wieso sehen die zahlen immer noch so scheisse aus?"
|
|
Zu Recht. Die Ziffer sass nicht mittig im Kreis. Ursache war die
|
|
geerbte Zeilenhoehe: body.wd setzt line-height 1.7, und in einem
|
|
40px hohen Kreis erzeugt das einen Textkasten von rund 28px, der
|
|
die Ziffer nach unten drueckt. Zusaetzlich hing die Zentrierung an
|
|
einer weiter oben stehenden Regel — verlaesst man sich darauf, ist
|
|
man beim naechsten Umbau wieder verlassen.
|
|
Deshalb hier ALLES explizit: eigenes Raster, place-items, und vor
|
|
allem line-height: 1. Eine Ziffer in einem Kreis braucht genau die
|
|
Hoehe ihrer selbst, nichts sonst.
|
|
|
|
b) "es soll 4 farben geben wie 4 kategorien zum prozess"
|
|
Sehr gute Idee — und sie macht das System erst schluessig. Die
|
|
sieben Phasen sind in Wahrheit vier Abschnitte, und die vier
|
|
Merkmalskacheln tragen ohnehin schon vier Farben. Jetzt bedeuten
|
|
diese Farben ueberall dasselbe:
|
|
|
|
1 Blau Start Briefing, Angebot
|
|
2 Lila Gestaltung Design
|
|
3 Gruen Umsetzung Entwicklung, Tests
|
|
4 Gold Abschluss Abnahme, Uebergabe
|
|
|
|
Damit ist die Farbe nicht mehr Dekoration, sondern Sprache: Wer
|
|
Gold sieht, weiss, dass es auf die Zielgerade geht.
|
|
--------------------------------------------------------------------- */
|
|
|
|
/* ---------- a) Der Kreis ---------- */
|
|
.po-leer-nr {
|
|
display: grid;
|
|
place-items: center;
|
|
width: 42px; height: 42px;
|
|
padding: 0;
|
|
border-radius: 50%;
|
|
/* Der entscheidende Wert: ohne ihn erbt die Ziffer 1.7 und rutscht. */
|
|
line-height: 1;
|
|
font-family: var(--font-head);
|
|
font-size: 1.15rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0;
|
|
font-variant-numeric: tabular-nums;
|
|
flex-shrink: 0;
|
|
border: 2px solid transparent;
|
|
background:
|
|
linear-gradient(#0d1624, #0d1624) padding-box,
|
|
linear-gradient(140deg, var(--wd-blau), var(--wd-lila)) border-box;
|
|
}
|
|
/* Die Ziffer selbst noch einmal optisch ausrichten: Zahlen haben oben
|
|
mehr Luft als unten, rein geometrisch zentriert wirken sie deshalb
|
|
leicht zu tief. Ein Hauch nach oben gleicht das aus. */
|
|
.po-leer-nr { padding-bottom: .06em; }
|
|
|
|
/* ---------- b) Die vier Prozessfarben ---------- */
|
|
:root {
|
|
/* Die vier Prozessfarben sind KEINE eigenen Farben, sondern Rollen.
|
|
Sie zeigen auf die Markenfarben, statt deren Werte zu wiederholen --
|
|
sonst haette man vier weitere Stellen, die beim naechsten
|
|
Farbwechsel stillschweigend zurueckbleiben und die Seite in zwei
|
|
Blautoene zerfallen lassen. */
|
|
--wd-p1: var(--wd-blau); /* Start — Briefing, Angebot */
|
|
--wd-p2: var(--wd-lila); /* Gestaltung — Design */
|
|
--wd-p3: var(--wd-ok); /* Umsetzung — Entwicklung, Tests */
|
|
--wd-p4: var(--wd-gold); /* Abschluss — Abnahme, Übergabe */
|
|
}
|
|
|
|
.po-leer-punkt:nth-child(1)::before { background: linear-gradient(90deg, #3d9dbd, var(--wd-p1)); }
|
|
.po-leer-punkt:nth-child(2)::before { background: linear-gradient(90deg, #7c5cd6, var(--wd-p2)); }
|
|
.po-leer-punkt:nth-child(3)::before { background: linear-gradient(90deg, #2e8f6b, var(--wd-p3)); }
|
|
.po-leer-punkt:nth-child(4)::before { background: linear-gradient(90deg, #a8873a, var(--wd-p4)); }
|
|
|
|
.po-leer-punkt:nth-child(1) .po-leer-nr { color: var(--wd-p1); background: linear-gradient(#0d1624,#0d1624) padding-box, linear-gradient(140deg, var(--wd-p1), #3d9dbd) border-box; box-shadow: 0 0 20px -7px var(--wd-p1); }
|
|
.po-leer-punkt:nth-child(2) .po-leer-nr { color: var(--wd-p2); background: linear-gradient(#0d1624,#0d1624) padding-box, linear-gradient(140deg, var(--wd-p2), #7c5cd6) border-box; box-shadow: 0 0 20px -7px var(--wd-p2); }
|
|
.po-leer-punkt:nth-child(3) .po-leer-nr { color: var(--wd-p3); background: linear-gradient(#0d1624,#0d1624) padding-box, linear-gradient(140deg, var(--wd-p3), #2e8f6b) border-box; box-shadow: 0 0 20px -7px var(--wd-p3); }
|
|
.po-leer-punkt:nth-child(4) .po-leer-nr { color: var(--wd-p4); background: linear-gradient(#0d1624,#0d1624) padding-box, linear-gradient(140deg, var(--wd-p4), #a8873a) border-box; box-shadow: 0 0 20px -7px var(--wd-p4); }
|
|
|
|
/* ---------- Die Phasenleiste spricht dieselbe Sprache ----------
|
|
Erledigte Phasen tragen die Farbe IHRES Abschnitts, nicht pauschal
|
|
Gruen. So sieht man auf einen Blick, wie weit man im Prozess ist —
|
|
und nicht nur, dass etwas erledigt wurde. */
|
|
.po-phase { background: rgb(var(--wd-blau-rgb) / .12); }
|
|
.po-phase:nth-child(1).po-erledigt, .po-phase:nth-child(2).po-erledigt { background: var(--wd-p1); box-shadow: 0 0 9px -3px var(--wd-p1); }
|
|
.po-phase:nth-child(3).po-erledigt { background: var(--wd-p2); box-shadow: 0 0 9px -3px var(--wd-p2); }
|
|
.po-phase:nth-child(4).po-erledigt, .po-phase:nth-child(5).po-erledigt { background: var(--wd-p3); box-shadow: 0 0 9px -3px var(--wd-p3); }
|
|
.po-phase:nth-child(6).po-erledigt, .po-phase:nth-child(7).po-erledigt { background: var(--wd-p4); box-shadow: 0 0 9px -3px var(--wd-p4); }
|
|
|
|
.po-phase:nth-child(1).po-jetzt, .po-phase:nth-child(2).po-jetzt { background: var(--wd-p1); box-shadow: 0 0 16px -2px var(--wd-p1); }
|
|
.po-phase:nth-child(3).po-jetzt { background: var(--wd-p2); box-shadow: 0 0 16px -2px var(--wd-p2); }
|
|
.po-phase:nth-child(4).po-jetzt, .po-phase:nth-child(5).po-jetzt { background: var(--wd-p3); box-shadow: 0 0 16px -2px var(--wd-p3); }
|
|
.po-phase:nth-child(6).po-jetzt, .po-phase:nth-child(7).po-jetzt { background: var(--wd-p4); box-shadow: 0 0 16px -2px var(--wd-p4); }
|
|
|
|
/* Die Vorschau zeigt denselben Verlauf: jede Phase leuchtet in der Farbe
|
|
ihres Abschnitts auf, wenn sie an der Reihe ist. */
|
|
.po-vorschau-phasen span:nth-child(1), .po-vorschau-phasen span:nth-child(2) { --po-f: var(--wd-p1); }
|
|
.po-vorschau-phasen span:nth-child(3) { --po-f: var(--wd-p2); }
|
|
.po-vorschau-phasen span:nth-child(4), .po-vorschau-phasen span:nth-child(5) { --po-f: var(--wd-p3); }
|
|
.po-vorschau-phasen span:nth-child(6), .po-vorschau-phasen span:nth-child(7) { --po-f: var(--wd-p4); }
|
|
@keyframes po-phase-lauf {
|
|
0%, 8% { background: rgb(var(--wd-blau-rgb) / .12); box-shadow: none; }
|
|
14%, 60% { background: var(--po-f); box-shadow: 0 0 12px -3px var(--po-f); }
|
|
100% { background: rgb(var(--wd-blau-rgb) / .12); box-shadow: none; }
|
|
}
|
|
|
|
/* ---------- Legende: vier Abschnitte statt drei Zustände ----------
|
|
Die alte Legende erklärte den Zustand (erledigt / läuft / offen). Der
|
|
ist aus der Position ohnehin ablesbar. Wertvoller ist, WAS gerade
|
|
passiert — deshalb erklärt sie jetzt die vier Abschnitte. */
|
|
.po-legende { gap: .45rem .9rem; font-size: .76rem; }
|
|
.po-legende i { width: 14px; height: 7px; }
|
|
.po-legende .po-l-1 { background: var(--wd-p1); }
|
|
.po-legende .po-l-2 { background: var(--wd-p2); }
|
|
.po-legende .po-l-3 { background: var(--wd-p3); }
|
|
.po-legende .po-l-4 { background: var(--wd-p4); }
|
|
|
|
/* =====================================================================
|
|
PORTAL — AUFGABENLISTE UND POSTFACH (22.08.2026)
|
|
|
|
"wenn sie drauf drücken sollen sie auch sehen was ich schon gemacht
|
|
habe von dem was im plan war."
|
|
|
|
Dieselben vier Prozessfarben wie auf der Ablaufseite, in der Vorschau
|
|
und in der Verwaltung. Das ist der eigentliche Wert: Eine Farbe
|
|
bedeutet im ganzen Bereich dasselbe — sonst wäre sie Dekoration.
|
|
===================================================================== */
|
|
|
|
/* Die grosse Zahl. "9 von 14 erledigt" ist greifbar, "64 %" ist eine
|
|
Rechnung, die niemand fühlt. */
|
|
.po-aufg-stand { margin: .9rem 0 .2rem; font-size: .92rem; color: var(--wd-text-soft); }
|
|
.po-aufg-stand b {
|
|
font-family: var(--font-head); font-weight: 800;
|
|
font-size: 1.7rem; color: var(--wd-text); margin-right: .3rem;
|
|
}
|
|
|
|
.po-fortschritt { display: flex; gap: 4px; height: 8px; margin-bottom: 1.2rem; }
|
|
.po-fs-teil { flex: 1; border-radius: 999px; background: rgba(255,255,255,.07); position: relative; overflow: hidden; }
|
|
.po-fs-teil > i { position: absolute; inset: 0 auto 0 0; border-radius: 999px; }
|
|
.po-fs-teil[data-k="start"] > i { background: var(--wd-p1); }
|
|
.po-fs-teil[data-k="gestaltung"] > i { background: var(--wd-p2); }
|
|
.po-fs-teil[data-k="umsetzung"] > i { background: var(--wd-p3); }
|
|
.po-fs-teil[data-k="abschluss"] > i { background: var(--wd-p4); }
|
|
|
|
/* ---------- "Das brauche ich noch von dir" ----------
|
|
Ein EIGENER Kasten ganz oben, nicht nur eine farbige Zeile irgendwo
|
|
in der Liste. Wer eine lange Liste sieht, liest sie als Bericht über
|
|
fremde Arbeit und überliest seinen eigenen Teil — und genau daraus
|
|
entstehen die meisten Verzögerungen.
|
|
|
|
Gold, weil es im ganzen Bereich für "das betrifft dich" steht. Nicht
|
|
Rot: Es ist eine Bitte, kein Fehler. */
|
|
.po-dubist {
|
|
margin: 0 0 1.3rem;
|
|
padding: .9rem 1rem 1rem;
|
|
border-radius: 14px;
|
|
background: rgb(var(--wd-gold-rgb) / .07);
|
|
border: 1px solid rgb(var(--wd-gold-rgb) / .32);
|
|
}
|
|
.po-dubist h4 {
|
|
margin: 0; font-size: 1rem; color: var(--wd-gold);
|
|
font-family: var(--font-head); font-weight: 700;
|
|
}
|
|
|
|
/* Der beruhigende Gegenpart. Wenn nichts offen ist, soll das auch
|
|
dastehen — Abwesenheit einer Aufforderung ist eine gute Nachricht und
|
|
darf ruhig ausgesprochen werden. */
|
|
.po-allesgut {
|
|
margin: 0 0 1.3rem; padding: .75rem .95rem;
|
|
border-radius: 10px; font-size: .9rem;
|
|
background: rgb(var(--wd-ok-rgb) / .08);
|
|
border: 1px solid rgb(var(--wd-ok-rgb) / .28);
|
|
color: var(--wd-ok);
|
|
}
|
|
|
|
/* ---------- Gruppen und Zeilen ---------- */
|
|
.po-aufg-gruppe { margin-bottom: 1.1rem; }
|
|
.po-aufg-kopf {
|
|
display: flex; align-items: baseline; gap: .5rem;
|
|
font-size: 0.8rem; letter-spacing: .13em; text-transform: uppercase;
|
|
margin-bottom: .45rem; padding-bottom: .35rem;
|
|
border-bottom: 1px solid var(--wd-rand);
|
|
}
|
|
.po-aufg-zahl { margin-left: auto; letter-spacing: 0; text-transform: none; font-size: .8rem; color: var(--wd-text-soft); }
|
|
.po-aufg-gruppe[data-k="start"] .po-aufg-kopf { color: var(--wd-p1); }
|
|
.po-aufg-gruppe[data-k="gestaltung"] .po-aufg-kopf { color: var(--wd-p2); }
|
|
.po-aufg-gruppe[data-k="umsetzung"] .po-aufg-kopf { color: var(--wd-p3); }
|
|
.po-aufg-gruppe[data-k="abschluss"] .po-aufg-kopf { color: var(--wd-p4); }
|
|
|
|
/* Zeile und Spalte ausdrücklich für JEDES Kind.
|
|
|
|
Ohne Spaltenangabe geht es schief, und zwar auf eine Art, die man
|
|
nicht errät: Das Raster platziert zuerst alle Elemente mit
|
|
FESTGELEGTER Zeile und erst danach die freien. Kästchen und Marke
|
|
haben beide eine feste Zeile — sie würden zusammen nach vorne rutschen
|
|
und der Titel landete ganz rechts. Genau das ist am 22.08.2026 in der
|
|
Verwaltung passiert und erst am Screenshot aufgefallen. */
|
|
.po-aufg {
|
|
display: grid;
|
|
grid-template-columns: auto minmax(0,1fr) auto;
|
|
gap: .12rem .7rem; align-items: start;
|
|
padding: .55rem .6rem; margin-bottom: .25rem;
|
|
border-radius: 10px; border: 1px solid transparent;
|
|
}
|
|
.po-aufg-haken { grid-row: 1 / span 2; grid-column: 1; }
|
|
.po-aufg-titel { grid-row: 1; grid-column: 2; font-size: .94rem; color: var(--wd-text); overflow-wrap: anywhere; }
|
|
.po-aufg-marken { grid-row: 1; grid-column: 3; }
|
|
.po-aufg-text { grid-row: 2; grid-column: 2 / span 2; font-size: .82rem; color: var(--wd-text-soft); line-height: 1.5; }
|
|
|
|
.po-aufg--fertig .po-aufg-titel { color: var(--wd-text-soft); text-decoration: line-through; text-decoration-thickness: 1px; }
|
|
.po-aufg--weg .po-aufg-titel { color: var(--wd-text-soft); text-decoration: line-through; opacity: .55; }
|
|
.po-aufg--du { background: rgb(var(--wd-gold-rgb) / .06); }
|
|
|
|
/* Im oberen Kasten stehen dieselben Punkte noch einmal. Dort brauchen
|
|
sie den eigenen Hintergrund nicht — der Kasten ist schon golden, ein
|
|
zweiter Goldton darin würde nur schmutzig wirken. */
|
|
.po-aufg--hervor { background: transparent; padding-left: 0; padding-right: 0; }
|
|
|
|
/* Das Kästchen. Bei eigenen Punkten ein echter Knopf (tastaturbedienbar,
|
|
44px Trefferfläche über das Innenabstands-Polster), sonst nur Anzeige.
|
|
Ein Knopf, der nichts tut, lässt die Seite kaputt wirken. */
|
|
.po-aufg-haken {
|
|
width: 26px; height: 26px; margin-top: .05rem; padding: 0;
|
|
border-radius: 10px; border: 2px solid var(--wd-rand-stark);
|
|
background: transparent; color: transparent;
|
|
display: grid; place-items: center;
|
|
font-size: .95rem; line-height: 1;
|
|
transition: all var(--wd-zeit-schnell) ease;
|
|
}
|
|
button.po-aufg-haken { cursor: pointer; }
|
|
button.po-aufg-haken:hover { border-color: var(--wd-gold); background: rgb(var(--wd-gold-rgb) / .1); }
|
|
.po-aufg-haken--fest { cursor: default; }
|
|
.po-aufg--fertig .po-aufg-haken { background: var(--wd-ok); border-color: var(--wd-ok); color: #06120c; }
|
|
.po-aufg--jetzt .po-aufg-haken { border-color: var(--wd-p2); color: var(--wd-p2); }
|
|
.po-aufg--weg .po-aufg-haken { border-style: dashed; color: var(--wd-text-soft); }
|
|
/* Offene EIGENE Punkte: der Rand ist golden, damit klar ist, dass hier
|
|
geklickt werden kann und soll. */
|
|
.po-aufg--du button.po-aufg-haken { border-color: rgb(var(--wd-gold-rgb) / .55); }
|
|
|
|
.po-aufg-marke {
|
|
display: inline-block; white-space: nowrap;
|
|
font-size: 0.75rem; letter-spacing: .05em; text-transform: uppercase;
|
|
padding: .14rem .45rem; border-radius: 999px;
|
|
}
|
|
.po-aufg-marke--ok { background: rgb(var(--wd-ok-rgb) / .13); color: var(--wd-ok); }
|
|
.po-aufg-marke--jetzt { background: rgb(var(--wd-lila-rgb) / .15); color: var(--wd-p2); }
|
|
.po-aufg-marke--du { background: rgb(var(--wd-gold-rgb) / .16); color: var(--wd-gold); }
|
|
.po-aufg-nicht {
|
|
display: inline-block; margin-left: .4rem;
|
|
font-size: 0.75rem; letter-spacing: .05em; text-transform: uppercase;
|
|
padding: .12rem .4rem; border-radius: 999px;
|
|
background: rgb(var(--wd-fehler-rgb) / .12); color: var(--wd-fehler);
|
|
}
|
|
|
|
/* Auf dem Handy rutscht die Marke unter den Titel — nebeneinander bliebe
|
|
für den Titel eine Spalte von zwei Wörtern Breite. */
|
|
@media (max-width: 520px) {
|
|
.po-aufg { grid-template-columns: auto minmax(0,1fr); }
|
|
.po-aufg-marken { grid-row: 2; grid-column: 2; margin-bottom: .15rem; }
|
|
.po-aufg-text { grid-row: 3; grid-column: 2; }
|
|
}
|
|
|
|
/* ---------- Postfach auf der Übersicht ---------- */
|
|
.po-pf-verlauf {
|
|
max-height: 46vh; overflow-y: auto;
|
|
margin: .8rem 0 .2rem; padding-right: .3rem;
|
|
display: flex; flex-direction: column; gap: .5rem;
|
|
}
|
|
|
|
/* =====================================================================
|
|
WIDERRUF (§ 356a BGB) — und die Druckansicht der Bestätigung
|
|
|
|
Gestalterisch bewusst ZURÜCKHALTEND. Alles andere im Bereich darf
|
|
Stimmung machen; diese Seite nicht. Wer hier landet, will eine Sache
|
|
erledigen und danach Gewissheit haben. Grosse Effekte würden hier wie
|
|
Ablenkung wirken — und der Vorwurf, man wolle den Widerruf erschweren,
|
|
ist genau der, den man am wenigsten gebrauchen kann.
|
|
===================================================================== */
|
|
.wr-h2 { font-size: 1.12rem; margin: 0 0 .5rem; }
|
|
|
|
.wr-info {
|
|
border-left: 3px solid var(--wd-blau);
|
|
margin-bottom: 1.4rem;
|
|
}
|
|
|
|
.wr-pruef {
|
|
display: grid; grid-template-columns: minmax(0,.42fr) minmax(0,1fr);
|
|
gap: .45rem .9rem; margin: .9rem 0 1.1rem;
|
|
padding: .9rem 1rem; border-radius: 10px;
|
|
background: rgb(var(--wd-blau-rgb) / .05); border: 1px solid var(--wd-rand);
|
|
}
|
|
@media (max-width: 520px) { .wr-pruef { grid-template-columns: 1fr; gap: .1rem; } }
|
|
.wr-pruef dt { color: var(--wd-text-soft); font-size: .88rem; }
|
|
.wr-pruef dd { margin: 0; color: var(--wd-text); overflow-wrap: anywhere; white-space: pre-wrap; }
|
|
@media (max-width: 520px) { .wr-pruef dd { margin-bottom: .55rem; } }
|
|
|
|
/* Der Bestätigungsschritt hebt sich ab — hier passiert das Verbindliche. */
|
|
.wr-bestaetigen { border-color: var(--wd-rand-stark); }
|
|
|
|
/* Grün statt Gold für den Abschluss: Der Widerruf ist erfolgreich
|
|
erklärt, das ist aus Sicht des Kunden eine gute Nachricht. Gold ist im
|
|
Bereich für "das betrifft dich, tu was" reserviert — hier ist nichts
|
|
mehr zu tun. */
|
|
.wr-fertig { border-color: rgb(var(--wd-ok-rgb) / .42); }
|
|
.wr-haken {
|
|
width: 46px; height: 46px; border-radius: 50%;
|
|
display: grid; place-items: center; line-height: 1;
|
|
font-size: 1.5rem; margin-bottom: .7rem;
|
|
background: rgb(var(--wd-ok-rgb) / .14); color: var(--wd-ok);
|
|
border: 1px solid rgb(var(--wd-ok-rgb) / .4);
|
|
}
|
|
|
|
.wr-beleg {
|
|
margin: 1rem 0; padding: 1.1rem 1.2rem;
|
|
border-radius: 14px;
|
|
background: rgba(8,14,24,.55);
|
|
border: 1px solid var(--wd-rand-stark);
|
|
}
|
|
.wr-beleg-kopf {
|
|
display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline;
|
|
justify-content: space-between;
|
|
padding-bottom: .6rem; margin-bottom: .7rem;
|
|
border-bottom: 1px solid var(--wd-rand);
|
|
}
|
|
.wr-beleg-nr { font-family: var(--font-head); font-weight: 800; color: var(--wd-blau); }
|
|
.wr-beleg dl {
|
|
display: grid; grid-template-columns: minmax(0,.42fr) minmax(0,1fr);
|
|
gap: .45rem .9rem; margin: 0;
|
|
}
|
|
@media (max-width: 520px) { .wr-beleg dl { grid-template-columns: 1fr; gap: .1rem; } }
|
|
.wr-beleg dt { color: var(--wd-text-soft); font-size: .86rem; }
|
|
.wr-beleg dd { margin: 0; overflow-wrap: anywhere; }
|
|
@media (max-width: 520px) { .wr-beleg dd { margin-bottom: .55rem; } }
|
|
|
|
/* ---------------------------------------------------------------------
|
|
DRUCKANSICHT
|
|
|
|
Die Eingangsbestätigung ist ein Rechtsnachweis. Ein Ausdruck mit
|
|
dunklem Hintergrund verbraucht eine halbe Patrone und ist auf Papier
|
|
schlecht lesbar — und ein Nachweis, den niemand ausdruckt, weil er
|
|
hässlich wird, erfüllt seinen Zweck nicht.
|
|
|
|
Deshalb: auf Papier schwarz auf weiss, ohne Navigation, ohne Knöpfe,
|
|
nur der Beleg. Adressen werden ausgeschrieben, weil ein Link auf
|
|
Papier nichts nützt.
|
|
--------------------------------------------------------------------- */
|
|
@media print {
|
|
body.wd { background: #fff !important; color: #000 !important; }
|
|
.wd-kopf, #wd-kopf, .wd-fuss, #wd-fuss,
|
|
.wr-nicht-drucken, .wr-info, #wr-form, #wr-schritt2,
|
|
.wd-meldung, .wd-eyebrow { display: none !important; }
|
|
|
|
.wd-abschnitt { padding: 0 !important; }
|
|
.wd-karte, .wr-beleg {
|
|
background: #fff !important; border: 1px solid #000 !important;
|
|
box-shadow: none !important; color: #000 !important;
|
|
}
|
|
.wr-fertig, .wr-beleg { page-break-inside: avoid; }
|
|
.wr-haken { border-color: #000 !important; color: #000 !important; background: #fff !important; }
|
|
.wr-beleg-nr, .wr-h2, h1, h2, dt, dd, p { color: #000 !important; }
|
|
.wr-beleg dt { color: #444 !important; }
|
|
|
|
/* Adressen ausschreiben — ein Link ist auf Papier wertlos. */
|
|
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
RECHTSSEITE
|
|
|
|
Lange Texte, die man liest statt überfliegt. Deshalb: schmalere
|
|
Zeilen, mehr Zeilenabstand, klare Absätze. Und KEIN Blocksatz --
|
|
der reisst im Deutschen wegen der langen Wörter Löcher in die Zeile
|
|
und macht genau die Texte schwerer lesbar, bei denen es auf jedes
|
|
Wort ankommt.
|
|
--------------------------------------------------------------------- */
|
|
.rl-nav {
|
|
display: flex; flex-wrap: wrap; gap: .45rem;
|
|
margin: 1.2rem 0 1.6rem;
|
|
}
|
|
.rl-nav a {
|
|
/* inline-flex + min-height 44px statt nur Innenabstand.
|
|
|
|
Mit reinem padding kamen die vier Sprungmarken auf 39px -- fuenf
|
|
Pixel unter dem Daumenmass. Genau derselbe Fall wie frueher bei
|
|
.wd-nav a (dort waren es 43px): Ein Innenabstand, der auf dem
|
|
Bildschirm gut aussieht, ergibt nicht automatisch ein treffbares
|
|
Ziel. Und ausgerechnet auf der Rechtsseite muss man verlaesslich
|
|
zum Widerrufsrecht springen koennen. */
|
|
display: inline-flex; align-items: center; min-height: 44px;
|
|
padding: .42rem .95rem; border-radius: 999px;
|
|
border: 1px solid var(--wd-rand); background: var(--wd-glas);
|
|
font-size: .88rem; color: var(--wd-text-mid) !important; text-decoration: none;
|
|
}
|
|
.rl-nav a:hover { border-color: var(--wd-rand-stark); color: var(--wd-text) !important; }
|
|
|
|
.rl-sprache { margin-bottom: 1.8rem; }
|
|
|
|
.rl-h2 {
|
|
margin-top: 2.4rem;
|
|
/* Ein Sprungziel darf nicht unter der klebenden Kopfzeile landen. */
|
|
scroll-margin-top: 5.5rem;
|
|
}
|
|
.rl-text { line-height: 1.75; }
|
|
.rl-text h3 {
|
|
font-size: 1rem; margin: 1.5rem 0 .5rem;
|
|
color: var(--wd-blau);
|
|
}
|
|
.rl-text h3:first-child { margin-top: 0; }
|
|
.rl-text p { margin: 0 0 .8rem; }
|
|
.rl-text ul { margin: 0 0 .9rem; padding-left: 1.2rem; }
|
|
.rl-text li { margin-bottom: .35rem; }
|
|
.rl-text code {
|
|
/* min() statt eines reinen em-Werts: In einem ohnehin kleineren Absatz
|
|
rutschte der Code sonst auf 11,2px -- unter die Lesbarkeitsgrenze. */
|
|
font-size: max(.78rem, .86em); padding: .1rem .35rem; border-radius: 6px;
|
|
background: rgb(var(--wd-blau-rgb) / .09); color: var(--wd-blau);
|
|
}
|
|
|
|
/* Die Belehrung hebt sich ab: Sie ist der Teil, auf den es rechtlich
|
|
ankommt, und muss auch optisch als geschlossener Block erkennbar sein. */
|
|
.rl-widerruf { border-left: 3px solid var(--wd-gold); }
|
|
.rl-adresse {
|
|
padding: .7rem .9rem; border-radius: 10px;
|
|
background: rgb(var(--wd-blau-rgb) / .05); border: 1px solid var(--wd-rand);
|
|
}
|
|
|
|
/* Das Muster-Formular sieht bewusst wie ein Formular aus — man soll
|
|
sehen, dass man es ausdrucken und ausfüllen kann. */
|
|
.rl-formular {
|
|
margin-top: .6rem; padding: 1rem 1.1rem;
|
|
border-radius: 10px; border: 1px dashed var(--wd-rand-stark);
|
|
background: rgba(8,14,24,.4);
|
|
font-size: .93rem;
|
|
}
|
|
.rl-formular p { margin: 0 0 .6rem; }
|
|
|
|
/* =====================================================================
|
|
FEINSCHLIFF — das Höhensystem (23.08.2026)
|
|
|
|
Bis hierher trug jede Karte EINEN Schatten: 0 24px 60px -28px. Das ist
|
|
solide, aber es ist auch der Grund, warum eine Oberfläche "ordentlich"
|
|
statt "teuer" wirkt.
|
|
|
|
Echtes Licht erzeugt zwei Dinge gleichzeitig:
|
|
|
|
1. einen engen, dunklen Kontaktschatten direkt an der Kante — er
|
|
sagt dem Auge, dass ein Gegenstand AUFLIEGT
|
|
2. einen weiten, weichen Umgebungsschatten — er sagt, wie HOCH er
|
|
darüber schwebt
|
|
|
|
Nur einen von beiden zu setzen, sieht aus wie ein Aufkleber. Beide
|
|
zusammen ergeben einen Gegenstand.
|
|
|
|
Dazu kommt die LICHTKANTE: eine 1 Pixel hohe, sehr schwache weisse
|
|
Linie an der Oberkante (inset 0 1px 0). Sie tut so, als käme das Licht
|
|
von oben und bräche sich an der Kante. Das ist das meistübersehene
|
|
Detail in dunklen Oberflächen — und dasjenige, das den grössten
|
|
Unterschied macht. Ohne sie wirkt eine Karte wie ein Loch im
|
|
Hintergrund; mit ihr wie ein Stück Material.
|
|
|
|
Drei Stufen, mehr braucht es nicht:
|
|
1 ruhende Flächen (Karten, Felder)
|
|
2 hervorgehobene Flächen (aktive Karte, Knopf)
|
|
3 Schwebendes (Fenster, Menü)
|
|
===================================================================== */
|
|
:root {
|
|
/* Kontaktschatten + Umgebungsschatten + Lichtkante, in dieser
|
|
Reihenfolge — die Lichtkante zuletzt, damit sie über allem liegt. */
|
|
--wd-hoehe-1:
|
|
0 1px 2px rgba(0, 0, 0, .40),
|
|
0 10px 28px -12px rgba(0, 0, 0, .70),
|
|
inset 0 1px 0 rgba(255, 255, 255, .055);
|
|
--wd-hoehe-2:
|
|
0 2px 4px rgba(0, 0, 0, .45),
|
|
0 18px 44px -16px rgba(0, 0, 0, .80),
|
|
inset 0 1px 0 rgba(255, 255, 255, .075);
|
|
--wd-hoehe-3:
|
|
0 4px 8px rgba(0, 0, 0, .50),
|
|
0 40px 90px -30px rgba(0, 0, 0, .92),
|
|
inset 0 1px 0 rgba(255, 255, 255, .09);
|
|
|
|
/* Vertiefte Flächen — Eingabefelder liegen NICHT auf der Oberfläche,
|
|
sie sind hineingeschnitten. Derselbe Lichteinfall, nur umgekehrt:
|
|
oben dunkel (Schattenkante), unten hell. */
|
|
--wd-tiefe:
|
|
inset 0 1px 2px rgba(0, 0, 0, .35),
|
|
inset 0 -1px 0 rgba(255, 255, 255, .03);
|
|
}
|
|
|
|
/* ---------- Karten ---------- */
|
|
.wd-karte {
|
|
box-shadow: var(--wd-hoehe-1);
|
|
/* Etwas schneller als der bisherige Standard: Bei Flächen, die man
|
|
überfährt, wirkt alles über 200 ms träge. */
|
|
transition:
|
|
transform .18s cubic-bezier(.2, .8, .3, 1),
|
|
box-shadow .18s cubic-bezier(.2, .8, .3, 1),
|
|
border-color .18s ease;
|
|
}
|
|
a.wd-karte:hover, .wd-karte--klickbar:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: var(--wd-hoehe-3), 0 0 40px -22px rgb(var(--wd-blau-rgb) / .5);
|
|
}
|
|
/* Beim Drücken zurück auf die Fläche — ohne das fehlt die Rückmeldung,
|
|
dass der Klick angekommen ist. */
|
|
a.wd-karte:active, .wd-karte--klickbar:active {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--wd-hoehe-1);
|
|
transition-duration: .06s;
|
|
}
|
|
|
|
/* ---------- Knöpfe ---------- */
|
|
.wd-btn {
|
|
transition:
|
|
transform .16s cubic-bezier(.2, .8, .3, 1),
|
|
box-shadow .16s cubic-bezier(.2, .8, .3, 1),
|
|
background .16s ease, border-color .16s ease, color .16s ease;
|
|
}
|
|
/* Der Hauptknopf ist hell auf dunklem Grund. Seine Lichtkante gehört
|
|
deshalb nach INNEN und heller — sie lässt die Fläche gewölbt wirken
|
|
statt flach aufgeklebt. */
|
|
/* ⚠️ Die Gewichtung muss zur Grundregel passen.
|
|
|
|
Weiter oben steht ".wd .wd-btn--haupt, .wd-btn--haupt { ... }" -- der
|
|
erste Teil zaehlt ZWEI Klassen. Ein blosses ".wd-btn--haupt" hier
|
|
unten zaehlt eine und verliert, obwohl es spaeter steht. Beim ersten
|
|
Versuch blieb der Hauptknopf deshalb ohne Lichtkante, waehrend die
|
|
Karten sie schon hatten -- gemessen, nicht vermutet.
|
|
|
|
Dieselbe Falle wie am 22.08.2026 bei ".wd a" gegen ".wd-btn--haupt".
|
|
Wer in dieser Datei etwas nachtraegt, muss die Gewichtung der
|
|
Grundregel uebernehmen, nicht nur die Reihenfolge. */
|
|
.wd .wd-btn--haupt, .wd-btn--haupt {
|
|
box-shadow:
|
|
0 1px 2px rgba(0, 0, 0, .35),
|
|
0 10px 26px -12px rgb(var(--wd-blau-rgb) / .55),
|
|
inset 0 1px 0 rgba(255, 255, 255, .45);
|
|
}
|
|
.wd .wd-btn--haupt:hover, .wd-btn--haupt:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow:
|
|
0 2px 4px rgba(0, 0, 0, .4),
|
|
0 18px 40px -14px rgb(var(--wd-blau-rgb) / .8),
|
|
inset 0 1px 0 rgba(255, 255, 255, .55);
|
|
}
|
|
.wd .wd-btn--haupt:active, .wd-btn--haupt:active { transform: translateY(0); transition-duration: .06s; }
|
|
|
|
.wd-btn--zweit, .wd-btn--still {
|
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
|
|
}
|
|
.wd-btn--zweit:hover, .wd-btn--still:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow:
|
|
0 6px 18px -10px rgba(0, 0, 0, .8),
|
|
inset 0 1px 0 rgba(255, 255, 255, .07);
|
|
}
|
|
|
|
/* ---------- Eingabefelder: vertieft statt aufliegend ---------- */
|
|
.wd-feld input[type="text"], .wd-feld input[type="email"], .wd-feld input[type="tel"],
|
|
.wd-feld input[type="url"], .wd-feld input[type="number"], .wd-feld input[type="date"],
|
|
.wd-feld input[type="password"], .wd-feld input[type="search"],
|
|
.wd-feld select, .wd-feld textarea, .wd-eingabe {
|
|
box-shadow: var(--wd-tiefe);
|
|
transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
|
|
}
|
|
/* Im Fokus bleibt die Vertiefung erhalten und der Ring kommt dazu —
|
|
sonst "springt" das Feld beim Anklicken aus der Fläche heraus. */
|
|
.wd-eingabe:focus, .wd-feld input:focus, .wd-feld select:focus, .wd-feld textarea:focus {
|
|
box-shadow: var(--wd-tiefe), 0 0 0 4px rgb(var(--wd-blau-rgb) / .16);
|
|
}
|
|
|
|
/* ---------- Marken und Abzeichen ---------- */
|
|
.wd-tag, .vw-status, .po-aufg-marke, .vw-aufg-wer, .vw-aufg-nicht {
|
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
|
|
}
|
|
|
|
/* ---------- Schwebende Flächen ---------- */
|
|
.vw-detail-blatt { box-shadow: var(--wd-hoehe-3), 0 0 0 1px rgb(var(--wd-blau-rgb) / .06) inset; }
|
|
.wd-nav-panel, .wd-menue-flaeche { box-shadow: var(--wd-hoehe-3); }
|
|
|
|
/* ---------- Schrift: optische Korrektur ----------
|
|
Grosse Schriftgrade wirken bei gleicher Laufweite zu locker gesetzt —
|
|
das Auge sieht bei 48px mehr Weissraum zwischen den Buchstaben als bei
|
|
16px. Professioneller Satz zieht deshalb mit wachsender Größe enger.
|
|
Bei kleinen Grössen genau umgekehrt: dort hilft etwas mehr Luft. */
|
|
.wd h1 { letter-spacing: -.028em; }
|
|
.wd h2 { letter-spacing: -.021em; }
|
|
.wd h3 { letter-spacing: -.012em; }
|
|
/* Verhindert Schusterjungen in Überschriften — ein einzelnes Wort in der
|
|
letzten Zeile sieht immer nach Versehen aus. */
|
|
.wd h1, .wd h2, .wd-fuehrung { text-wrap: balance; }
|
|
.wd p { text-wrap: pretty; }
|
|
|
|
/* ---------- Ruhe bei Bewegungsempfindlichkeit ---------- */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.wd-karte, .wd-btn { transition: none !important; }
|
|
a.wd-karte:hover, .wd-karte--klickbar:hover,
|
|
.wd-btn:hover, .wd-btn--haupt:hover, .wd-btn--zweit:hover, .wd-btn--still:hover {
|
|
transform: none !important;
|
|
}
|
|
}
|
|
|
|
/* =====================================================================
|
|
LESEBREITE (23.08.2026)
|
|
|
|
Gemessen über alle Seiten: 105 von 200 Textabsätzen waren zu breit,
|
|
der schlimmste mit 151 Zeichen pro Zeile.
|
|
|
|
Warum das zählt: Beim Zeilensprung muss das Auge zurück an den
|
|
Zeilenanfang finden. Je länger die Zeile, desto häufiger landet es in
|
|
der falschen — man liest eine Zeile doppelt oder überspringt eine und
|
|
merkt es erst zwei Sätze später. Der Text ist dann nicht "schwer", er
|
|
ist schlecht gesetzt.
|
|
|
|
Bewährt sind 45 bis 75 Zeichen. Bücher, Zeitungen und jedes ordentlich
|
|
gesetzte Buch halten sich daran; es ist der älteste und bestbelegte
|
|
Grundsatz der Typografie überhaupt.
|
|
|
|
Die Einheit ist ch (Breite der Ziffer Null). Damit hängt die Breite an
|
|
der SCHRIFTGRÖSSE, nicht an Pixeln: Kleingedrucktes bekommt
|
|
automatisch einen schmaleren Block, große Schrift einen breiteren --
|
|
in beiden Fällen landet man bei ähnlich vielen Zeichen.
|
|
|
|
max-width macht nie etwas breiter. In schmalen Karten und Spalten
|
|
ändert sich also gar nichts -- die Regel greift nur dort, wo eine
|
|
Zeile wirklich über das Lesbare hinauswächst.
|
|
===================================================================== */
|
|
:root {
|
|
--wd-lesebreite: 68ch;
|
|
--wd-lesebreite-eng: 60ch; /* für Kleingedrucktes und Hinweise */
|
|
}
|
|
|
|
.wd p,
|
|
.wd li,
|
|
.wd .wd-fuehrung {
|
|
max-width: var(--wd-lesebreite);
|
|
}
|
|
|
|
/* Kleingedrucktes darf enger stehen: Es wird überflogen, nicht gelesen,
|
|
und ein schmaler Block ist dabei schneller zu erfassen. */
|
|
.wd .wd-klein,
|
|
.wd .wd-feld-hilfe,
|
|
.wd .rl-text .wd-klein {
|
|
max-width: var(--wd-lesebreite-eng);
|
|
}
|
|
|
|
/* Wo mittig gesetzt wird, muss auch der BLOCK mittig bleiben.
|
|
Ohne das klebt zentrierter Text nach der Begrenzung am linken Rand --
|
|
die Schrift wäre zentriert, ihr Kasten aber nicht. */
|
|
/* Zwei Faelle, beide noetig:
|
|
|
|
ELTERNELEMENT zentriert -> die Kinder mittig halten
|
|
ABSATZ SELBST zentriert -> ihn selbst mittig halten
|
|
|
|
Beim ersten Versuch fehlte der zweite Fall. Ergebnis: zwei Absaetze,
|
|
deren Schrift zentriert war, deren Kasten aber links klebte -- auf
|
|
anfrage.html mit 384 Pixeln Luft rechts und null links. Gefunden, weil
|
|
die Pruefung den Abstand links mit dem rechts VERGLEICHT, statt nur zu
|
|
zaehlen, ob zentriert ist. */
|
|
.wd :is(p, li)[style*="text-align:center"],
|
|
.wd :is(p, li)[style*="text-align: center"],
|
|
.wd [style*="text-align:center"] :is(p, li),
|
|
.wd [style*="text-align: center"] :is(p, li),
|
|
/* Alle Behaelter, die ihren Inhalt mittig setzen -- aus der zentralen
|
|
Stilvorlage UND aus den seiteneigenen <style>-Bloecken zusammengesucht.
|
|
Ein einzelner uebersehener Behaelter faellt sofort auf: Der Text steht
|
|
dann mittig, sein Kasten aber links. */
|
|
.wd .po-leer :is(p, li),
|
|
.wd .af-danke :is(p, li),
|
|
.wd .wd-cta-flaeche :is(p, li),
|
|
.wd .wd-intro :is(p, li),
|
|
.wd .zg-mitte :is(p, li),
|
|
.wd .vw-leer-gross :is(p, li),
|
|
.wd .wd-abschnitt--mitte :is(p, li),
|
|
.wd .wr-fertig > p,
|
|
.wd .vw-leer-hinweis {
|
|
margin-inline: auto;
|
|
}
|
|
|
|
/* AUSNAHMEN — hier wäre eine Begrenzung falsch:
|
|
|
|
Nachrichtenblasen tragen ihre Breite schon selbst (82 % der Spalte);
|
|
eine zweite Begrenzung würde sie im Gespräch unruhig springen lassen.
|
|
|
|
Tabellenzellen und Beschreibungslisten richten sich nach ihrer Spalte.
|
|
Eine eigene Breite darin bricht die Ausrichtung zur Nachbarspalte.
|
|
|
|
Die Fusszeile ist bewusst mehrspaltig und schon schmal. */
|
|
.wd .vw-blase p, .wd .po-nachricht p,
|
|
.wd td p, .wd th p,
|
|
.wd dd, .wd dd p,
|
|
.wd .wd-fuss p, .wd .wd-fuss li,
|
|
.wd .vw-paar dd, .wd .wr-pruef dd, .wd .wr-beleg dd {
|
|
max-width: none;
|
|
}
|
|
|
|
/* =====================================================================
|
|
KACHELN: LICHT UNTER DEM ZEIGER (23.08.2026)
|
|
|
|
Die Kacheln hatten Verlaufsrand, Verlaufsfläche, Schatten und
|
|
Lichtkante — alles richtig, alles statisch. Was fehlte, war das
|
|
Gefühl von MATERIAL: eine Oberfläche, die auf Licht reagiert.
|
|
|
|
Der Effekt: Ein weicher Lichtfleck folgt dem Zeiger über die Kachel.
|
|
Das ist kein Zierrat, sondern die Fortsetzung derselben Erzählung wie
|
|
bei der Lichtkante oben — es gibt eine Lichtquelle, und die Fläche
|
|
verhält sich, als wäre sie aus etwas.
|
|
|
|
VIER ENTSCHEIDUNGEN, DAMIT ES HOCHWERTIG UND NICHT BILLIG WIRKT
|
|
|
|
1. Sehr schwach. 13 % Deckkraft. Man soll es SPÜREN, nicht ANSEHEN.
|
|
Ein greller Fleck sieht nach Spielerei aus; ein kaum sichtbarer
|
|
nach teurem Material. Passt zugleich zur Dauervorgabe
|
|
"augenschonend" — nichts blitzt, nichts blendet.
|
|
|
|
2. Nur bei echtem Zeiger (hover: hover). Auf einem Handy gibt es
|
|
keinen Zeiger; dort bliebe ein Lichtfleck an einer zufälligen
|
|
Stelle kleben.
|
|
|
|
3. Die Farbe folgt der Kachel. Blaue Kacheln leuchten blau, lila
|
|
lila — sonst bräche der Effekt die Farbordnung, die überall sonst
|
|
Bedeutung trägt.
|
|
|
|
4. Aus bei prefers-reduced-motion. Auch wenn sich nichts bewegt:
|
|
Etwas, das dem Zeiger folgt, ist Bewegung.
|
|
===================================================================== */
|
|
@media (hover: hover) and (pointer: fine) {
|
|
.wd-karte {
|
|
/* Startwert oben mittig — falls die Kachel vor der ersten
|
|
Zeigerbewegung schon überfahren wird. */
|
|
--wd-lichtx: 50%;
|
|
--wd-lichty: 0%;
|
|
isolation: isolate;
|
|
}
|
|
|
|
.wd-karte::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: inherit;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
opacity: 0;
|
|
transition: opacity .28s ease;
|
|
background: radial-gradient(
|
|
380px circle at var(--wd-lichtx) var(--wd-lichty),
|
|
rgb(var(--wd-blau-rgb) / .22),
|
|
rgb(var(--wd-blau-rgb) / .08) 38%,
|
|
transparent 70%
|
|
);
|
|
}
|
|
.wd-karte--lila::after {
|
|
background: radial-gradient(
|
|
380px circle at var(--wd-lichtx) var(--wd-lichty),
|
|
rgb(var(--wd-lila-rgb) / .24),
|
|
rgb(var(--wd-lila-rgb) / .08) 38%,
|
|
transparent 70%
|
|
);
|
|
}
|
|
.wd-karte:hover::after { opacity: 1; }
|
|
|
|
/* DER RAND LEUCHTET MIT — und das ist der Teil, der auffällt.
|
|
|
|
Die Kachel hat schon zwei Hintergrundebenen: die Fläche
|
|
(padding-box) und den Verlaufsrand (border-box). Der Rand ist nur
|
|
einen Pixel breit, aber genau dort lässt sich Licht am stärksten
|
|
zeigen, ohne dass es kitschig wird.
|
|
|
|
Beim Überfahren bekommt die Randebene einen Lichtpunkt an derselben
|
|
Stelle wie die Fläche. Ergebnis: Die Kante glüht dort auf, wo der
|
|
Zeiger steht, und verläuft nach beiden Seiten aus. Ein Lichtfleck
|
|
OHNE mitleuchtende Kante wirkt wie ein Fleck AUF der Kachel; mit ihr
|
|
wirkt die ganze Kachel beleuchtet.
|
|
|
|
Die Fläche bleibt unverändert — sonst würde der Text flackern. */
|
|
.wd-karte:hover {
|
|
background:
|
|
linear-gradient(180deg, rgba(20, 32, 50, .72), rgba(9, 15, 26, .86)) padding-box,
|
|
radial-gradient(240px circle at var(--wd-lichtx) var(--wd-lichty),
|
|
rgb(var(--wd-blau-rgb) / .95),
|
|
rgb(var(--wd-blau-rgb) / .30) 42%,
|
|
rgb(var(--wd-lila-rgb) / .28) 100%) border-box;
|
|
}
|
|
.wd-karte--lila:hover {
|
|
background:
|
|
linear-gradient(180deg, rgba(26, 22, 48, .72), rgba(12, 10, 24, .88)) padding-box,
|
|
radial-gradient(240px circle at var(--wd-lichtx) var(--wd-lichty),
|
|
rgb(var(--wd-lila-rgb) / .95),
|
|
rgb(var(--wd-lila-rgb) / .30) 42%,
|
|
rgb(var(--wd-blau-rgb) / .26) 100%) border-box;
|
|
}
|
|
|
|
/* Der Inhalt muss ÜBER dem Lichtfleck liegen.
|
|
|
|
Ohne das legt sich der absolut gesetzte Lichtfleck über den Text —
|
|
absolut positionierte Elemente malen über normalen Fluss-Inhalt,
|
|
auch wenn sie im Quelltext davor stehen. Das Ergebnis wäre ein
|
|
leichter Schleier auf der Schrift, den man erst bemerkt, wenn man
|
|
zwei Kacheln nebeneinander vergleicht. */
|
|
.wd-karte > * { position: relative; z-index: 1; }
|
|
|
|
/* Der Rand zieht mit. Ein Lichtfleck ohne mitleuchtende Kante wirkt
|
|
wie ein Fleck AUF der Kachel statt wie Licht darauf. */
|
|
.wd-karte { transition: border-color .28s ease, box-shadow .18s cubic-bezier(.2,.8,.3,1), transform .18s cubic-bezier(.2,.8,.3,1); }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.wd-karte::after { display: none; }
|
|
}
|
|
|
|
/* =====================================================================
|
|
HANDY UND INSTALLIERTE APP — Sicherheitsabstände
|
|
|
|
AUSGANGSLAGE (gefunden am 23.08.2026)
|
|
Die Seite trug bereits `apple-mobile-web-app-status-bar-style:
|
|
black-translucent`. Das heißt wörtlich: Der Seiteninhalt beginnt bei
|
|
y=0 und läuft UNTER Uhr, Empfangsbalken und Akkuanzeige durch. Auf
|
|
einem iPhone mit Aussparung stand die Kopfzeile also im installierten
|
|
Betrieb hinter der Statusleiste.
|
|
|
|
Gleichzeitig fehlte `viewport-fit=cover` auf allen dreizehn Seiten.
|
|
Ohne diese Angabe liefert jedes `env(safe-area-inset-*)` schlicht
|
|
null. Die eine Stelle, die den unteren Abstand bereits benutzte (der
|
|
Installations-Hinweis), war damit wirkungslos — sie sah richtig aus
|
|
und tat nichts. Genau die Sorte Fehler, die man nie bemerkt, weil der
|
|
Code stimmt.
|
|
|
|
LÖSUNG IN ZWEI TEILEN
|
|
1. `viewport-fit=cover` in jeder Seite (dort erledigt).
|
|
2. Die Abstände hier einmal zentral benennen, statt sie an fünfzehn
|
|
Stellen einzeln zu schreiben. Wer sie einzeln schreibt, vergisst
|
|
eine — und dann liegt genau ein Knopf unter der Gestenleiste.
|
|
|
|
WARUM `max()` UND NICHT NUR `env()`
|
|
Auf einem Gerät ohne Aussparung ist der Wert 0. Ein Kopfbereich mit
|
|
0 Abstand klebt aber am oberen Rand. `max(env(...), <Mindestwert>)`
|
|
gibt beiden Fällen ein brauchbares Ergebnis: Notch-Geräte bekommen
|
|
den echten Abstand, alle anderen den normalen.
|
|
===================================================================== */
|
|
:root {
|
|
--wd-sicher-oben: env(safe-area-inset-top, 0px);
|
|
--wd-sicher-unten: env(safe-area-inset-bottom, 0px);
|
|
--wd-sicher-links: env(safe-area-inset-left, 0px);
|
|
--wd-sicher-rechts: env(safe-area-inset-right, 0px);
|
|
}
|
|
|
|
/* Die Kopfzeile klebt oben (position: sticky). Im Browser sitzt sie
|
|
unter der Adressleiste und braucht nichts. Installiert gibt es keine
|
|
Adressleiste mehr — dann muss sie sich selbst unter die Statusleiste
|
|
schieben, sonst steht die Marke hinter der Uhr. */
|
|
.wd-kopf {
|
|
padding-top: var(--wd-sicher-oben);
|
|
}
|
|
|
|
/* Querformat: Bei gedrehtem Gerät liegt die Aussparung seitlich. Ohne
|
|
diesen Abstand verschwindet die linke Spalte halb darunter. `92vw`
|
|
allein hilft nicht — vw zählt die Aussparung mit. */
|
|
.wd-container,
|
|
.wd-container--schmal {
|
|
padding-left: var(--wd-sicher-links);
|
|
padding-right: var(--wd-sicher-rechts);
|
|
}
|
|
|
|
/* Unten die Gestenleiste. Betrifft den Fußbereich und alles, was fest
|
|
am unteren Rand sitzt. */
|
|
.wd-fuss {
|
|
padding-bottom: calc(1.5rem + var(--wd-sicher-unten));
|
|
}
|
|
|
|
@media (display-mode: standalone), (display-mode: window-controls-overlay), (display-mode: minimal-ui) {
|
|
/* ------------------------------------------------------------------
|
|
NUR IM INSTALLIERTEN BETRIEB
|
|
|
|
Installiert fehlt alles, was ein Browser sonst beisteuert: keine
|
|
Adressleiste, kein Zurück-Knopf, kein Neuladen durch Herunterziehen
|
|
im gewohnten Sinn. Was im Browser eine Kleinigkeit ist, wird hier
|
|
zum Fehler.
|
|
------------------------------------------------------------------ */
|
|
|
|
/* Das Gummiband-Nachfedern am Seitenende sieht in einer App nach
|
|
einem Darstellungsfehler aus -- im Browser erwartet man es, in
|
|
einer App nicht. Innerhalb scrollbarer Bereiche bleibt Scrollen
|
|
natürlich unverändert. */
|
|
html, body {
|
|
overscroll-behavior-y: none;
|
|
}
|
|
|
|
/* Der Hinweis "Als App installieren" ist installiert sinnlos. Er wird
|
|
zwar schon per JavaScript unterdrückt -- aber nur, wenn das Skript
|
|
lädt. Diese Regel greift auch dann, wenn es das nicht tut. */
|
|
.wd-install { display: none !important; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
TIPP-VERHALTEN
|
|
|
|
Auf Android legt der Browser über jede angetippte Fläche ein graues
|
|
Rechteck. Bei runden Kacheln und Knöpfen zeichnet es die eckige
|
|
Trefferfläche nach und sieht nach einem Fehler aus. Ersetzt wird es
|
|
nicht ersatzlos: Jeder Knopf hat einen sichtbaren :active-Zustand,
|
|
sonst fehlte die Rückmeldung, dass der Tipp angekommen ist.
|
|
--------------------------------------------------------------------- */
|
|
.wd a, .wd button, .wd [role="button"], .wd summary, .wd label {
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
.wd .wd-btn:active,
|
|
.wd .vw-ub-kachel:active,
|
|
.wd .vw-ub-projekt:active,
|
|
.wd .vw-filter-knopf:active {
|
|
/* Kein Verschieben, nur ein kurzes Einsinken: Bewegung nach unten
|
|
wird als Druck gelesen und braucht keine Farbe. */
|
|
transform: scale(.985);
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.wd .wd-btn:active,
|
|
.wd .vw-ub-kachel:active,
|
|
.wd .vw-ub-projekt:active,
|
|
.wd .vw-filter-knopf:active { transform: none; }
|
|
}
|