Wiederverwendbare Muster, die über alle Ansichten hinweg identisch umgesetzt werden. Ergänzt die Design-Tokens: gleiche Bausteine, gleiches Markup, keine seitenspezifischen Sonderlösungen.
Platzhalter für leere Tabellen und Listen (keine Datensätze bzw. kein Suchergebnis). Immer dasselbe Muster: Warndreieck-Icon im hellen Kreis über einer beschreibenden Zeile — kein generischer Titel mit zusätzlichem Untertitel.
<!-- im .komo-card, direkt nach der Toolbar --> <div class="komo-empty"> <div class="komo-empty__icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 4 2.8 20h18.4z"/> <path d="M12 10v4M12 17.5h.01"/> </svg> </div> <div class="komo-empty__title"> Aktuell sind keine Einträge vorhanden. </div> </div>
.komo-empty__title — konkret formuliert („Aktuell ist kein … erfasst."). Kein zusätzliches .komo-empty__text..komo-card direkt nach der Toolbar; die obere Trennlinie liefert .komo-empty selbst.Jede Seite nutzt dieselbe Hülle. Header oben über die volle Breite, Sidebar links, Main rechts — und der Inhalt in Main ist immer zentriert mit fester Maximalbreite. Nur Main scrollt.
<body class="komo-app"> <header class="komo-header">…</header> /* sticky, 64px */ <div class="komo-shell"> <aside class="komo-sidebar">…</aside> /* 248px */ <main class="komo-main"> /* einzige Scroll-Region */ <div class="komo-content">…</div> </main> </div> </body> /* immer zentriert, überall gleich breit */ .komo-content { max-width: 1000px; margin: 0 auto; }
64px. Logo, App-Name, Nutzermenü; scrollt nicht mit.248px, sticky. Unter 900px als Offcanvas über den Hamburger..komo-content mit max-width: 1000px; margin: 0 auto → immer zentriert.32–40px; darunter greifen dieselben responsiven Stufen.Bei Validierung wird der Fehler doppelt gezeigt: als persistentes Banner im Kontext (nennt was fehlt) und direkt am betroffenen Feld (roter Rahmen + zarte rote Füllung). Kein flüchtiger Toast, der wieder verschwindet.
<!-- persistentes Banner, kein Floating-Toast --> <div class="komo-banner komo-banner--warning"> <svg …>…</svg> <div class="komo-banner__body"> <h3 class="komo-banner__title">1 Pflichtfeld fehlt</h3> <p>Nachname muss einen Wert haben.</p> </div> </div> <!-- Pflichtfeld-Marker + Fehlerzustand --> <label class="komo-label">Nachname<span class="komo-req">*</span></label> <input class="komo-input is-error"> <!-- roter Rahmen -->
* (.komo-req) markieren; einmal pro Formular die Legende „Mit * gekennzeichnete Felder sind Pflichtfelder.".komo-banner--warning) — nie als flüchtiger Floating-Toast..is-error (roter Rahmen + zarte rote Füllung) — der Fehler wird nicht nur im Banner benannt, sondern ist am Feld sichtbar.Zwei verschiedene Dinge, zwei verschiedene Formen. Ein Button löst eine Aktion aus (rechteckig, mit Fläche oder Rahmen). Ein Link navigiert (teal, Unterstreichung bei Hover). Auch sekundäre Buttons behalten Fläche und Rahmen — sonst sind sie nicht als Button erkennbar.
/* Aktion → Button (Fläche/Rahmen, rechteckig) */ <button class="komo-btn komo-btn--primary">Speichern</button> <button class="komo-btn komo-btn--secondary">Abbrechen</button> <button class="komo-btn komo-btn--outline">Exportieren</button> /* Navigation → Link (teal, Hover-Unterstreichung) */ <a class="komo-link" href="…">Zur Übersicht</a>
--secondary oder --outline.Aktionen tragen Text — das Icon unterstützt, ersetzt ihn nicht. Reine Icon-Buttons nur, wenn die Aktion unmittelbar klar ist (Menü, Schließen, Zeile bearbeiten). Und: für identische Aktionen immer dasselbe Icon.
/* Bevorzugt: Text (Icon optional davor) */ <button class="komo-btn komo-btn--primary"> <svg …>…</svg>Person erfassen </button> /* Icon-only nur bei klarer Standardaktion — */ /* immer mit aria-label */ <button class="komo-iconbtn" aria-label="Schließen">…</button>
aria-label ist Pflicht, nicht optional (siehe Hinweis oben).+ Hinzufügen), weiterführender Pfeil rechts (Weiter →).Ein einziger, kräftiger Fokus-Ring für jedes interaktive Element (angelehnt an GOV.UK). Gelb hebt sich auf dunklen Flächen ab, die dunkle Kante auf hellen — sichtbar auf jedem Hintergrund. Nur bei Tastatur-Fokus (:focus-visible).
/* eigene Fokusfarbe — NICHT die Marken-Teal */ --komo-focus: #ffdd00; --komo-focus-ink: #0b0c0c; --komo-focus-shadow: 0 0 0 3px var(--komo-focus), 0 0 0 5px var(--komo-focus-ink); /* eine Regel für alle interaktiven Elemente */ :where(a[href], button, input, select, textarea, summary, [tabindex]):focus-visible { outline: 3px solid transparent; /* Kontrastmodus */ box-shadow: var(--komo-focus-shadow); }
:focus-visible: der Ring erscheint bei Tastatur-Bedienung, nicht bei jedem Maus-Klick.:focus-visible auch beim Maus-Klick. Ein Modalitäts-Flag (data-focus auf <html>, gesetzt in js/komo.js) beschränkt den lauten Ring dort auf die Tastatur — Maus-Fokus zeigt den ruhigen Teal-Rahmen (wie beim Dropdown).outline macht den Fokus im Windows-Kontrastmodus (forced-colors) sichtbar.outline: none nur mit gleichwertigem Ersatz — den Fokus nie ersatzlos entfernen (WCAG 2.4.7, behebt Finding #117).Reine Zahlenwerte werden in Tabellenspalten immer rechtsbündig ausgerichtet — Kopfzelle und alle Datenzellen. So fluchten Einer, Zehner und Nachkommastellen untereinander. Zusätzlich verwenden alle Tabellenzellen tabellarische Ziffern (tabular-nums) — auch Datumsangaben, damit Tag/Monat/Jahr exakt untereinander stehen. Datum, IBAN und Identifikationsnummern bleiben dabei linksbündig.
| Name | Geburtsdatum | Alter |
|---|---|---|
| Martina Edelhofer | 26.08.2017 | 8 |
| Klaus Huber | 04.03.2013 | 12 |
| Eva Muster | 09.11.2021 | 4 |
/* Kopf- UND jede Datenzelle der Zahlenspalte */ <th class="komo-col-num">Alter</th> … <td class="komo-col-num">8</td> /* CSS: alle Zellen tabellarisch (auch Datum) … */ .komo-table th, .komo-table td { font-variant-numeric: tabular-nums; } /* … Zahlenspalten zusätzlich rechtsbündig */ .komo-table th.komo-col-num, .komo-table td.komo-col-num { text-align: right; }
.komo-col-num auf <th> und jede <td> der Spalte setzen.font-variant-numeric: tabular-nums gilt für alle Tabellenzellen — gleich breite Ziffern, sodass Zahlen und Datumsangaben exakt untereinander fluchten.30.06.2008), IBAN, Identifikationsnummer, Telefonnummer — bleiben linksbündig, nutzen aber ebenfalls tabellarische Ziffern.38,5 Std./Woche) bleiben linksbündig — Rechtsbündigkeit würde die Ziffern hier nicht fluchten lassen.Die Aktionen eines Formulars, einer Seite oder eines Dialogs stehen immer unten rechts — die sekundäre Aktion (Abbrechen) links, die primäre Aktion (Speichern) ganz rechts. Nach dem Ausfüllen landet der Blick am Ende des Formulars genau dort, wo die Bestätigung liegt.
/* Seite / Formular */ <div class="komo-formactions"> <button class="komo-btn komo-btn--secondary">Abbrechen</button> <button class="komo-btn komo-btn--primary">Speichern</button> </div> /* Dialog (Modal) — gleiche Ausrichtung */ <div class="komo-modal__foot komo-modal__foot--end"> … </div>
.komo-formactions (sticky Fußleiste, rechtsbündig). Dialoge: .komo-modal__foot--end. Gleiche Logik, gleiches Bild.+ Hinzufügen).