KiFu

Styleguide

Grundlagen

Worauf alles Weitere baut: was das System ausmacht und woher es stammt, wie Bedienelemente auf Zeiger und Tastatur antworten, wie Seiten aufgeteilt sind und was auf Papier gilt.

Grundsatz und Herkunft

KiFu folgt Material 2 im dunklen Thema. Eine einzige Fläche trägt die ganze Anwendung: #101613 - Materials Dunkelgrau mit so viel Grün, dass der Platz im Bild bleibt. Höhe entsteht nicht durch eine zweite Farbe, sondern durch ein weisses Overlay auf eben dieser Fläche (Höhe). Akzent ist ein Lila, das im Dunkeln hell genug ist, um selbst Text zu sein; Schwarz steht darauf, nicht Weiss (Farbrollen). Farbe umrandet und beschriftet - sie füllt nur dort, wo eine Fläche wirklich gemeint ist. Ausgenommen sind die drei Bausteine von Atlassian (unten): Lozenge und Section Message tragen eine getönte Fläche, die Badge eine gefüllte.

Übernommen

  • Das Farbsystem: Rollen mit ihren On-Farben, Schrift als Weiss in Deckungen.
  • Die Höhe als gerechnete Overlay-Leiter über einem einzigen Grund.
  • Die Zustands-Deckungen (4 / 12 / 10 %) in der Farbe des Inhalts; überfahren in einer schon überfahrenen Fläche 8 %.
  • Die Typo-Rollen: Display, Headline, Title, Body, Label.

Nicht übernommen

  • Ripple und Bewegung. Die Zustands-Ebene blendet auf und ab, sie läuft nicht vom Klickpunkt aus. Das Kit animiert keine Höhen und nur eine Fläche: die Breite der Seitenleiste beim Umschalten (siehe Seitenleiste & Tabs).
  • Primary Variant. Das dunkle Zweit-Lila der Baseline stammt aus dem hellen Thema; auf dem Grund käme es auf 1.58:1. Eine Rolle mit genau einem möglichen Ort lädt zum Missgriff ein - das System kennt ein Lila.
  • Secondary. Der zweite Akzent der Baseline konkurrierte neben Primary nur, ohne etwas zu benennen - das System kennt einen Akzent.
  • Eine eigene Farbe für den nicht blockierenden Hinweis am Feld. Material kennt nur Error. Der Befund trägt darum dieselbe Farbe wie die Fehleingabe und unterscheidet sich im Verhalten (siehe Textfelder, Text-Area, Datum & Zeit).

Von Atlassian (wie Jira)

Drei Bausteine folgen nicht Material, sondern dem Atlassian Design System - Anatomie, Namen und Farben wie in Jira: die Lozenge (unsere Plakette) und die Badge (der Zähler am Knopf), beide unter Lozenge, Badge & Chips, und die Section Message (die Meldung im Fluss der Seite, Leerzustand, Hinweiszeile & Section Message). Ihre Farben stehen wörtlich aus @atlaskit/tokens - am Schirm das Dark-, im Druck das Light-Theme - und werden in lib/farben.ts gegen unseren Grund nachgerechnet.

Zustände

Jede bedienbare Fläche legt beim Überfahren, Fokussieren und Drücken eine Ebene auf - in der Farbe ihres eigenen Inhalts, mit fest vorgegebener Deckung. Die Ebene steckt im Basis-Bündel der Bausteine (state in Button, Chip, Icon-Knopf, Menüzeile, Navigationszeile), nicht an den Aufrufstellen: Darum kennt das Kit kein einziges hover:bg-*. Sie gehört zudem auf das fokussierbare Element: Deckt ein Link eine ganze Karte, trägt der Link die Ebene und nicht das <div> darum - sonst bliebe sie beim Tabben und beim Drücken stumm. Drei Zustände, nicht Materials vier: «gezogen» fehlt, weil das Einzige, was hier gezogen wird, Diagramm-Elemente sind - und die leben im SVG, nicht im DOM (siehe Feld-Diagramm). Ebene in Ebene: Liegt eine bedienbare Fläche in einer anderen («Training hinzufügen» in der Terminzeile), ist beim Überfahren auch die äussere aufgehellt; die innere trägt darum 8 % statt 4 % (--state-hover-innen). Menü und Auswahlliste schweben auf eigenem Grund und bleiben bei 4 %.

Inhalt weiss - auf neutraler Fläche

Ruhe-
Überfahren4 % · hover
Fokus12 % · focus-visible · dazu der Ring
Gedrückt10 % · active

Inhalt in Primary - dieselben Deckungen

Ruhe-
Überfahren4 % · hover
Fokus12 % · focus-visible · dazu der Ring
Gedrückt10 % · active

Am lebenden Objekt - überfahren, mit Tab fokussieren, gedrückt halten

aktiver Icon-Knopf: state-primary

Warum die Ebene ÜBER dem Text liegt

Das klingt verkehrt und ist der Grund, warum sie nie schadet: Die Overlay-Farbe ist die Textfarbe. Sie hellt Fläche und Schrift im selben Ton auf und kann den Kontrast des Textes damit rechnerisch nicht senken. Und weil nichts untergeschoben werden muss, erspart sie jede z-index-Buchhaltung im Inhalt - ::after mit pointer-events: none genügt.

Warum der Fokus-Ring bleibt (bewusste Abweichung)

Material macht den Tastaturfokus allein über die 12-%-Ebene plus voll ausgefahrene Kontur sichtbar. Auf einer Fläche, die ohnehin eine Kontur trägt, ist der Sprung von 0 auf 12 % kein verlässlicher Unterschied - und in Forced-Colors-Modi wird die Ebene gar nicht gezeichnet. Der 2-px-Ring in Primary mit Offset bleibt darum (focus-ring, als outline statt als Schatten: Er folgt dem Radius und kollidiert nicht mit dem Schatten schwebender Flächen). Die Ebene kommt dazu, sie ersetzt ihn nicht. Die Kontur rührt er nicht an: Sie sagt an vielen Stellen schon etwas anderes - Fehler, Befund, Auswahl, offenes Panel -, und eine Utility, die border-color setzte, schlüge jede dieser Farbklassen am Element.

Layout

Fenstergrössen und Seitenränder: vier Stufen, an denen sich das Layout ändert (Tabelle unten). Ein Spaltenraster gibt es nicht - die Lesebreite setzt der Seitenrahmen, Übersichten reihen Kacheln, so viele die Breite fasst (repeat(auto-fill, minmax(16rem, 1fr))).

Lange Formulare gliedert FormAbschnitt: eine Überschrift in type-title-medium, gedämpft - dieselbe, die die Abschnitte der Übungs-Detailseite tragen, damit Maske und Ansicht gleich gegliedert sind. Die Übungsmaske teilt sich darum wie die Detailseite in Inhalt und Einordnung (ZweiSpalten); die Einordnung steht schmal VOR dem Inhalt, weil sie bestimmt, welche Felder er verlangt. Ihre Felder stehen in jeder Breite untereinander, eins pro Zeile - eine Spalte liest sich von oben nach unten, ohne dass das Auge zwischen Nachbarn springt (PO 2026-10-04). Auch zusammengehörige Werte stehen als eigene Felder mit eigenem Namen untereinander - «Spielfeldlänge», «Spielfeldbreite» statt eines gemeinsamen Namens über zwei Teilnamen. Ein Feld ohne eigenes Label (Dateifeld, Material-Gruppe) bekommt die Id der Überschrift für aria-labelledby, statt den Namen doppelt zu zeigen.

Durchführung

Foto

Das Foto ist grösser als erlaubt. Mit fehler zeigt die Überschrift den Fehler eines Felds ohne eigenes Label an.

Jedes Formular mit Eingabefeldern trägt noValidate: Fehler meldet die App, nicht der Browser. Dessen eigene Prüfung (Pflicht, Mindestlänge, Zahlengrenzen, E-Mail-Form) hielte das Absenden an und zeigte eine Sprechblase in der Sprache des Browsers, in seinem Aussehen - und die deutsche Meldung der App unter dem Feld käme nie zum Zug. Die Regeln selbst prüft der Server ohnehin. Die Attribute bleiben stehen: required und min/max sagen der Vorlesehilfe, was das Feld verlangt (PO 2026-10-04).

Jede Seite steht in einem Seitenrahmen: linksbündig neben der Seitenleiste, Übersichten über die ganze Fläche (voll, Kachelraster mit so vielen Spalten, wie Platz ist), Formulare und Lesetext in ihrer Lesebreite (xl bis 5xl). Nicht zentriert, denn rechts steht, wo eine Seite eine hat, die zweite Spalte (spalte, etwa die Einordnung einer Übung, siehe Eigenschaften, ZweiSpalten). Ab xl ist die Seite dann geteilt (geteilt): beide Spalten füllen Breite und Höhe des Fensters und scrollen je für sich; die rechte wächst von 20 bis 26 rem mit und lässt sich am Griff dazwischen ziehen (Kit-Baustein Ziehgriff: role="separator", Pfeiltasten, Pos1/Ende, Doppelklick = Vorgabe; Cookie kifu-spalte). Derselbe Griff trennt unter «Versionen» und hier das Verzeichnis von den Texten (Verzeichnis). Schmaler steht sie nach dem Inhalt (in der Maske davor), der Inhalt in seiner Lesebreite; auf Papier daneben. Zuoberst die Kopfzeile mit dem Umschalter der Seitenleiste, den Brotkrumen und rechts den Aktionen der Seite - sie klebt ab lg beim Scrollen oben (ausser in der Durchführung), 64 px hoch mit den Brotkrumen auf der Linie der Marke. Einen Innenabstand bekommt sie nie, er zählte zur Höhe und schöbe die Brotkrumen aus der Mitte; darunter beginnt ab lg direkt der Inhalt, schmaler mit einem Rand von 24 px. Brotkrumen sind Pflicht, auch auf den Einstiegsseiten. Ab lg gehen 280 oder 72 px an die Seitenleiste (siehe Seitenleiste & Tabs); die Stufen unten meinen das ganze Fenster.

Das Training teilt sich ebenso, aber nur breit (nurBreit, Epic #369): Links stehen die Übungen, rechts die Eigenschaften des Trainings oder die geöffnete Übung (siehe Liste mit Detail daneben). Schmal und auf Papier fehlt die Spalte, und die Seite behält ihren bisherigen Aufbau - dort gibt es nichts daneben zu öffnen. Eine Ausnahme: Trägt eine Maske in der Spalte ungesicherte Angaben (data-ungesichert), bleibt sie auch gestapelt stehen, damit sie sich noch sichern lässt, wenn das Fenster schmal wird. Der Griff nennt, was die Spalte zeigt (spaltenName), und eine Spalte mit Eingabefeldern ist kein aside (beiseite): Eine Vorlesehilfe soll sie nicht als Nebensache ankündigen.

schmal< 640Rand 16 px, Seitenleiste als Drawer hinter der 48-px-Zeile mit dem Menüknopf
smab 640Rand 24 px
lgab 1024Seitenleiste daneben (280 oder 72 px), Kopfzeile 64 px und klebend
xlab 1280geteilte Fläche: zweite Spalte neben dem Inhalt (Seitenrahmen geteilt)

Druck

Was auf Papier geht, kommt aus derselben Anwendung - nur legt ein einziger Block (@media print :root) die Rollen um. Die Höhenleiter kippt: Aus dem aufgehellten Dunkel wird ein abgedunkeltes Weiss, die Reihenfolge der Stufen bleibt, sodass gestapelte Karten sich weiter voneinander abheben. Einen Sonderfall im Klassenstring kennt kein Baustein: Alle benutzen am Schirm wie auf Papier dieselben Tokens. Lozenge und Section Message wechseln dabei in Atlassians helles Theme - dieselben Rollen, die Werte aus atlassian-light.

#FFFFFF

elev-00

Papier

#F6F7F6

elev-01

Karte

#F1F2F1

elev-02

Block

#E6E6E6

elev-08

Menü

#DCDCDC

elev-24

Dialog

#4527A0

primary

10.24:1 auf Papier

#A32036

error

7.45:1 auf Papier

#121A16

on-surface

17.72:1 auf Papier

  • Primary wird dunkel. #BB86FC kommt auf Papier nur auf 2.65:1 und trüge dort keinen Text mehr; #4527A0 trägt 10.24:1. Error macht denselben Schritt.
  • Lozenges und Section Messages werden hell: zarte Tönung mit dunkler Schrift, wie Jira im hellen Theme. Am häufigsten gedruckt sind die Alterskategorien in der Druckansicht des Trainings; scripts/pruefe-farben.ts rechnet jede Darstellung auf Papier nach.
  • Schrift und Striche werden Tinte statt Deckung: on-surface #121A16, mittel #3C423F, kante #9AA0A0, linie #CFD3D2 - halbtransparentes Weiss hätte auf Papier keinen Sinn.
  • print-color-adjust: exact bleibt gesetzt, damit Diagramme und Kategorien wirklich so kommen, wie sie gesetzt sind; App-Chrome ist über print:hidden ausgeblendet.
  • Das Feld-Diagramm hat einen eigenen Druck-Satz (Feld-Diagramm): weisse Fläche statt Rasengrün, schwarze Pfeile, gedämpfte Elementfarben. Der grüne Rasen deckte 1600×1000 und kam auf geschätzt 125 % Farbauftrag - das Blatt allein trug damit fast den ganzen Verbrauch; weiss mit Raster liegt bei rund 3 %.

Stile

Wie KiFu aussieht: Farbe, Schrift, Höhe, Form und Zeichen.

Farbrollen

Material vergibt Rollen, keine Bedeutungen: Es gibt einen Akzent, eine Fehlerfarbe und Schrift in Deckungen - was davon wofür steht, entscheidet die Anwendung. Die Flächen unten sind die lebenden Klassen, die Zahlen daneben rechnet lib/farben.ts beim Rendern nach. Weichen sie voneinander ab, ist das hier zu sehen.

Akzente

#BB86FC

primary

Der eine Akzent. 6.92:1 auf dem Grund - hell genug, um selbst Text zu sein.

#000000

on-primary

Schrift auf gefüllter Akzentfläche: Schwarz, 7.93:1.

#E58A95

error

Fehleingabe und Befund, als Schrift und Kontur. 7.33:1 auf dem Grund, 4.56:1 noch im Dialog.

#C9372C

danger

Fläche des destruktiven Knopfs - dunkler als Error, weil sie Weiss trägt: 5.16:1 (auf Error nur 2.50:1).

Error liegt eine Stufe über Materials Baseline. Die Baseline (#cf6679) ist als Fläche gedacht: Als Schrift trägt sie nur auf dem Grund und fällt im Dialog auf 3.17:1 - die Anwendung setzt Error aber fast nie als Fläche, sondern als Schrift auf der Karte, in der Menüzeile und im Dialog. Der hellere Ton trägt auf jeder Höhenstufe über 4.5:1, am engsten auf 24dp mit 4.56:1. Gefüllt wird Rot nur im destruktiven Knopf, und dort mit eigener Rolle (danger, weisse Schrift 5.16:1). Nachgerechnet wird das seither auf jeder Stufe und zusätzlich als Kontur (scripts/pruefe-farben.ts), nicht mehr nur auf dem Grund - dort lag die Lücke, durch die die Baseline kam.

Schrift - Weiss in drei Deckungen

100 %

on-surface

18.32:1 auf dem Grund - Titel, Werte, alles Wesentliche.

74 %

on-surface-mittel

10.26:1 auf dem Grund - Beschriftungen und Beiwerk.

38 %

on-surface-tief

3.59:1 - NUR Deaktiviertes, wo der Kontrast bewusst preisgegeben ist.

Unterschieden wird über die Deckung, nicht über eine zweite Farbe: So trägt jede Höhenstufe dieselbe Schrift, ohne dass sie pro Fläche neu gemischt werden müsste. Halbtransparente Schrift lässt sich nicht direkt rechnen - die Zahlen oben stehen für den Kompositwert auf dem Grund (#c1c2c2 bei 74 %).

Striche

12 % · 1 px

linie

Trenner und Haarlinie. 1.40:1 - sie teilt, sie umreisst nicht.

28 % · 1.5 px

kante

Kontur von Feld, Chip und Knopf. 2.50:1 - 1 px verschwände im Dunkeln.

Die Kante umreisst, sie behauptet nichts: Wo eine Kontur selbst etwas aussagt - Fehler, Befund, Auswahl -, trägt sie border-error oder border-primary statt der Kante, und dann steht die Aussage auch im Text daneben.

Atlassian - Lozenge und Section Message

Je Darstellung ein Paar aus Atlassians Dark-Theme: Die Lozenge trägt die zarte Tönung (lozenge-* = ADS background.<x>.subtler) mit kräftiger Schrift (on-lozenge-* = text.<x>.bolder), die Section Message eine noch leisere Fläche (section-* = background.<x>) mit farbigem Zeichen (icon-*). Die Zahlen sind die Schrift auf ihrer Fläche, die neutrale Lozenge (halbtransparent) über dem Grund gemischt.

neutral

lozenge-neutral

Herkunft, Entwurf, Altersstufe, Termin ausgefallen

10.25:1

information

lozenge-information

gilt nach aussen: öffentlich, Community

9.53:1

discovery

lozenge-discovery

etwas Zusätzliches: mehrere Varianten, neue Version

9.35:1

warning

lozenge-warning

braucht Aufmerksamkeit: Termin ohne Training

8.16:1

success

lozenge-success

erledigt - im Kit, derzeit ohne Ort

8.12:1

danger

lozenge-danger

blockiert - im Kit, derzeit ohne Ort

9.37:1

Section Message (Schrift / Zeichen auf der Fläche): information 14.25:1 / 4.07:1 · warning 13.46:1 / 8.59:1 · danger 14.19:1 / 4.29:1 · success 13.59:1 / 5.57:1 · discovery 14.23:1 / 4.27:1.

Die Alterskategorien sind Accent-Lozenges. Wie Jira Kategorien ohne Wertung färbt, trägt jede Stufe einen festen Atlassian-Akzent - G blau, F gelb, E orange, D grün, C magenta, B lila, A grau (Lozenge, Badge & Chips). Die Akzente teilen die Palette mit den Bedeutungen - G hat die Farbe von information, B die von discovery, E die von warning, wie in Jira. Auseinander hält sie die Form: Die Kategorie ist immer ein einzelner Buchstabe, jede andere Lozenge ein Wort (a11y: nie nur über Farbe).

Typografie

Eine Familie für alles. Geist trägt Display, Titel, Fliesstext, Label und Lozenge; unterschieden werden die Rollen über Gewicht, Versalien und Sperrung, nicht über eine zweite Schrift. Was in Kolonnen fluchten muss - Dauern, Zählungen, Positionsnummern -, hält font-variant-numeric: tabular-nums auf jeder Label-Stufe bündig; dafür braucht es keine Monospace mehr.

Display, Headline und Titel stehen in normaler Schreibung und im selben Gewicht (600): Die Rangfolge trägt die Grösse, nicht die Wucht (Epic #363). Eine Neo-Grotesk in Gemischtschreibung will eng stehen, darum laufen die grossen Stufen mit leicht negativem Tracking - je grösser, desto enger. Namen, die Trainer:innen selbst erfassen, erscheinen so in jeder Überschrift genau so, wie sie sie geschrieben haben.

Label gehen den umgekehrten Weg: Sie allein stehen versal, klein und mit 8–10 % weit gesperrt, und trennen sich so von jeder Überschrift. Bei 400 verlöre die kleinste Stufe auf dem dunklen Grund ihre Stämme - darum steht Label Small auf 500.

Regel: Nutzertext nie in Label-Typografie. Die type-label-*-Stufen sind gesperrt, halbfett und versal - sie verändern, was dasteht. Für Beschriftungen, die wir selbst schreiben, ist das gewollt; ein Gruppenname wie „Grosse" käme daraus als „GROSSE" zurück und wäre nicht mehr das, was die Trainerin eingetippt hat. Alles, was aus der Datenbank kommt, gehört darum in type-body-*.

Display Large

Geist 600 · 57/60 · −.02 em

Display Medium

Geist 600 · 45/50 · −.02 em

Display Small

Geist 600 · 36/42 · −.02 em

Headline Large

Geist 600 · 32/38 · −.015 em

Headline Medium

Geist 600 · 28/34 · −.015 em

Headline Small

Geist 600 · 24/30 · −.01 em

Title Large

Geist 600 · 22/28 · −.01 em

Title Medium

Geist 600 · 16/24 · −.005 em

Title Small

Geist 600 · 14/20

Body Large

Geist 400 · 16/24

Body Medium

Geist 400 · 14/21

Body Small

Geist 400 · 12/18 · +.005 em

Label Large

Geist 600 · 14/20 · +.08 em · versal

Label Medium

Geist 600 · 12/16 · +.09 em · versal

Label Small

Geist 500 · 11/16 · +.09 em · versal

Lozenge und Badge

Geist 400 · 12/16 · Atlassian body.small

type-lozenge stammt von Atlassian (font.body.small): 12/16, normal gesetzt, für Lozenge und Badge. Keine Versalien - die Lozenge sagt, was ist, sie ist keine Rubrik. Eine Zeile niedriger als type-body-small, damit die Lozenge mit 2 px Polsterung genau 20 px misst.

Höhe

Im Dunkeln trägt nicht der Schatten die Höhe, sondern die Helligkeit: Jede Stufe legt ein weisses Overlay über denselben Grund. Die Werte stehen als literale Hex im @theme - ausgerechnet statt zur Laufzeit gemischt, damit die Prüfung sie lesen kann; die Herleitung steht daneben in lib/farben.ts.

StufeOverlayHexFlächeVerwendung
00dp0 %#101613Seitengrund, Feldfläche im Grund
01dp5 %#1C221FKarte, Teil-Karte, Übungszeile, Seitenleiste
02dp7 %#212624Block im Teil, dichtes Feld, Platzhalter
03dp8 %#232926- frei -
04dp9 %#262B28Kopfzeile unter lg (deckend, kein Blur)
06dp11 %#2A302DOverlay-Icon-Knopf
08dp12 %#2D322FMenü, Select-Panel, Tonal-Knopf, Drawer, aktives Segment, offener Navigationseintrag
12dp14 %#313734Avatar, offener Navigationseintrag im Drawer
16dp15 %#343936- frei -
24dp16 %#363B39Dialog, Tooltip

Zwei Stufen - 03 und 16 dp - sind frei. Sie stehen in der Leiter, weil Material sie führt und weil eine Lücke später schwerer nachzutragen wäre als eine ungenutzte Stufe; angewandt wird keine von beiden. Wer eine braucht, trägt hier ein, wofür.

Die Höhe trägt die Fläche, der Schatten nur, was schwebt. Karte, Block und Seitenleiste bekommen keinen Schatten - sie liegen im Bild, sie stehen nicht darüber. Vier Schatten gibt es, und jeder gehört zu genau einer Sorte schwebender Fläche:

dp-06

Snackbar - sie schwebt über dem Inhalt.

dp-08

Menü, Select-Panel, Drawer, Tooltip.

dp-24

Dialog - das Einzige, was die Seite anhält.

Masse, Radien, Konturen

Abstände - Vielfache von 4

4px
space-1
8px
space-2
12px
space-3
16px
space-4
24px
space-6
32px
space-8
48px
space-12
64px
space-16

Ecken

rounded-klein · 2 pxKontrollkästchen, Badge, Fokusfläche eines Textlinks - die kleinste Rundung.
rounded-flaeche · 4 pxKarte, Feld, Knopf, Menü, Snackbar, Auswahl-Panel, Lozenge.
rounded-dialog · 6 pxDialog und Section Message: die grössten Flächen vertragen mehr Rundung.
rounded-full · vollChips - Werte und Schalter, die man antippt und wieder loslässt.

Eckig mit gerundeten Kanten für alles, was Inhalt hält oder eine Handlung auslöst - Karte, Feld, Knopf, Icon-Knopf, Filterknopf; voll gerundet nur der Chip, ein Wert oder Schalter, den man antippt und wieder loslässt (Epic #363: Icon-Knöpfe sind kein Kreis mehr). Mehr Werte gibt es nicht - 3 px, 5 px und 8 px sind aus dem System gefallen, und ein rounded--Wert in eckigen Klammern ist ein Fehler, kein Sonderfall.

Kontur - kontur, 1.5 px

1 px - verschwindet1.5 px - trägt1 px Linie - trennt, umreisst nicht

kontur setzt nur Breite und Stil; die Farbe kommt separat (border-kante, border-primary, border-error). Im Dunkeln verschwindet eine 1-px-Kontur gegen den Grund - die Haarlinie bei 12 % bleibt trotzdem 1 px, weil sie trennt und nicht umreisst.

Höhen und Trefferflächen

h-4 · 16 pxBadge - die Zahl am Knopf (Atlassian).
h-5 · 20 pxLozenge, auch als Alterskategorie (Atlassian).
h-9 · 36 pxDas eine Mass alles Bedienbaren (Epic #363): Feldkasten, Knopf, Icon-Knopf, Glied der Knopfgruppe, jeder Chip samt geteiltem Chip und Menühälfte, Reiter, Zeile in Menü und Auswahlpanel, Kontrollkästchen, Eintrag der Seitenleiste, Werkzeug im Diagramm-Editor - auf dem Platz wie am Schreibtisch. Weil alles gleich hoch ist, fluchtet jede Leiste von selbst.
h-12 · 48 pxKopfzeile mit Menüknopf unter lg.

Zeichen - Lucide

Open-Source Lucide, umrissen, Strichstärke 2, runde Enden. „Gewählt" zeigt sich über Farbe und Zustands-Ebene, nicht über eine Füllung. Grössen 14 · 16 · 18 · 20 · 24 - 14 und 16 stehen neben Text, 18 und 20 in Knöpfen, 24 allein.

14px
16px
18px
20px
24px

Komponenten

Die Bausteine aus components/ui, geordnet nach ihrer Aufgabe - zuletzt die fachlichen, die nur KiFu kennt.

Formulare und Eingabe

Knöpfe

Sechs Varianten, eine Regel: Gefüllt trägt Schwarz - ausser Rot. filled ist Primary-Fläche, tonal eine Höhenstufe (08dp), outlined Kontur auf der Kante, text nur Schrift, danger gefüllt in danger mit weisser Schrift - Löschen soll man nicht übersehen (PO 2026-10-06). Das helle Error-Rot trüge Weiss nicht, darum hat die Fläche ihre eigene, dunklere Rolle; dazu der leise Knopf (quiet) weiter unten, der als einziger nicht über die Emphase leiser wird, sondern über die Schrift. Alle tragen state in der Basis und rounded-flaeche; es gibt kein hover:bg-* und kein Verschieben beim Drücken - die Zustands-Ebene färbt sich in der Farbe des Knopfinhalts ein und passt damit auf jede Stufe.

Leiser Knopf (variant="quiet") - eine Stufe unter text

Alle Knöpfe stehen normal gesetzt in type-title-small (Geist 600, 14/20), nicht versal - wie die Reiter - und sind 36 px hoch; eine Grössen-Prop gibt es nicht mehr. Der leise Knopf ist die knappe Bauform des text-Knopfes: dieselbe Farbe und Schrift, nur mit knapperer Polsterung. Er gilt für Handlungen, die am Rand mitlaufen: ein Knopf in einer Leiste aus Chips, auf deren Linie er sitzen soll. Er gilt nicht für Knöpfe, die einen Vorgang abschliessen oder abbrechen - Dialog-Knöpfe, Formularfüsse und alles, was neben einem filled steht, bleibt text.

quiet · text

Button-Link (navigiert als <a> - kein <a><button>-Nesting)

Verbundene Knopfgruppe

Icon-Knöpfe - Zeichen plus Zustands-Ebene, aktiv in Primary

ruhig · aktiv (state-primary) · overlay (06dp über Bild)

Icon-Knopf als Link (IconButtonLink) + Tooltip (24dp)

IconButtonLink ist die Navigations-Variante (rendert ein <a> statt <button>, gleiche Optik).Tooltip umschliesst einen Trigger ohne Text und macht ihn lesbar - Pflicht, sobald das Zeichen allein mehrdeutig ist (Globus = öffentlich vs. Schloss = privat). CSS-only, aria-hidden(der Name kommt schon vom aria-label des Triggers). Er steht auf 24dp wie der Dialog: Was über allem schwebt, trägt die oberste Stufe. Verborgen ist er display: none, damit er am Rand die Seite nie verbreitert. Mit ende steht er bündig zur rechten Kante des Triggers statt mittig - für Trigger am rechten Rand; das Überlaufmenü (⋮) trägt ihn immer so, wie sein Menü.

(hovern oder per Tab fokussieren)

Drucken (PrintButton)

Öffnet den Druckdialog des Browsers. Auf der Druckansicht eines Trainings ist Drucken der Zweck der Seite - dort steht er beschriftet und gefüllt; auf der Übungsseite ist er eine Aktion unter mehreren und reiht sich als Icon-Knopf ein (variant="icon"). Im Druck blendet ihn der Aufrufer aus.

Ansichts-Umschalter (TabNav)

Mehrere Sichten auf denselben Gegenstand - etwa ein Team mit Trainingsplan, Trainings und Verwaltung. Bewusst Links statt Schaltflächen: jede Ansicht hat ihre eigene Adresse, ist damit weitergebbar, und der Zurück-Schritt des Browsers funktioniert. Deshalb auch kein Auswahl-Baustein (Offene Einfachauswahl, Einfachauswahl mit Panel) - die sind Eingabefelder für eine Auswahl, kein Navigationsmittel, und ihr Wert lebt im Formularzustand. Die Leiste trennt sich nach unten mit border-linie, die offene Ansicht trägt einen 2 px starken Strich in Primary. Die Reiter stehen in type-title-small, normal gesetzt.

Überlaufmenü (OverflowMenu) - der Ort für Destruktives

Reihen aus Icon-Knöpfen enden mit einem ⋮. Dort liegt, was nicht offen stehen soll - allen voran Löschen und Entfernen: ein Klick daneben darf nichts Unwiderrufliches auslösen, darum zweistufig (⋮ → Eintrag → Bestätigungsdialog). Deshalb hat IconButton bewusst keine danger-Variante. Trigger-Zustand und -Ref stecken in der Komponente: ein geteilter Ref zeigte stets auf den zuletzt gerenderten Trigger, und der Outside-Click-Handler erkennt dann den eigenen Trigger nicht mehr - das Menü togglet doppelt und öffnet sofort wieder. In Listen gehört der Gegenstand ins label („Weitere Aktionen zu …"); der Tooltip bleibt kurz.

hovern, klicken, ⋮ öffnen

Ausnahme: Favoriten-Knopf (Füllung)

Ist ein IconButton (gleiche Grösse, Zustands-Ebene, Fokus-Ring, Primary im aktiven Zustand). Einzige Abweichung von der Zeichen-Regel „gewählt = Ebene statt Füllung": Das Favoriten-Herz wird im aktiven Zustand gefüllt - der etablierte, sofort lesbare Favoriten-Code. Optimistisch (sofortiges Umschalten, Rücksetzen plus Snackbar bei Fehler).

inaktiv (Umriss) · aktiv (gefüllt, Primary)

Formulare und Eingabe

Textfelder, Text-Area, Datum & Zeit

Leer steht der Name im Feld, sonst darüber (Epic #363, nach dem Vorbild von Jira). Ein leeres Feld zeigt nur seinen Namen, gedämpft an der Stelle des Werts - kein zweiter Satz wie «… wählen», ein Formular mit vielen leeren Feldern bleibt eine ruhige Liste von Namen. Klickt man hinein oder steht ein Wert drin, springt der Name in eine eigene Zeile darüber, und das Feld wird um diese Zeile höher - eine von Anfang an freigehaltene Zeile wäre zu grosszügig. Im Fehler steht der Name immer darüber. Er steht dort klein und gedämpft in der Lesetype (type-body-small), nicht in der Versal-Type der Label - er benennt, er ruft nicht. Darunter folgt der Feldkasten, darunter Hinweis oder Fehler in derselben kleinen Schrift. Der Rahmen dafür ist Feld. Jedes Feld trägt genau einen Namen: Zwei zusammengehörige Werte (Länge und Breite, Mindest- und Höchstanzahl) sind zwei Felder untereinander, nicht ein gemeinsamer Name über zwei Teilnamen - zwei Namensstufen brächen die ruhige Liste aus Namen und Werten (PO 2026-10-04). Bildet ein Knopf mit dem Feld eine Handlung (Mitglied suchen), steht er in aktion: in derselben Zeile wie der Feldkasten, auf einer Linie mit ihm - ob der Name darüber steht oder das leere Feld ihn ausblendet.

Der Feldkasten ist ruhend leer: keine Kontur, keine Fläche (Utility feldkasten). Ein Formular liest sich so als Text statt als Stapel von Kästen. Beim Überfahren hellt die ganze Angabe auf, Name und Kasten zusammen, mit einer leisen Ebene in der Schriftfarbe (6 %), die ringsum 6 px über den Kasten hinausragt - gerade ein leeres Feld gibt sich so deutlich als Feld zu erkennen, ohne dass sich etwas verschiebt. Im Fokus trägt die Kontur Primary, bei Fehler und Befund Error. Die Stärke bleibt dabei immer 1.5 px - nur die Farbe wechselt, der Kasten verschiebt sich beim Hineinklicken nicht. Der Name hält immer 6 px zu dem, was unter ihm sichtbar ist: im Fokus zur Kontur, ruhend - wo die Kontur fehlt - zur Schrift des Werts. Beim Hineinklicken springt er darum um 12 px hoch, ohne Übergang und ohne das Formular zu verschieben (nach dem Vorbild von Jira). 36 px hoch wie jedes Bedienelement, der Wert in type-body-large. Wo ein Feld keinen sichtbaren Namen trägt - die Suche in der Filterleiste -, gibt umrandet ihm auch ruhend die Kante, sonst fehlte es dort schlicht. Auf Touch-Geräten gibt es kein Überfahren: Ein leeres Feld kündigt sich dort allein über seinen Namen im Feld an. Das ist gewollt (PO-Entscheid 2026-10-03, Variante «ohne Kontur») - jedes Feld zeigt entweder seinen Namen oder einen Wert.

Hinweise: Was ein Feld nur erklärt («Höchstens 200 Zeichen»), steht nach dem Vorbild von Jira hinter einem ⓘ rechts im Feld (info, Baustein InfoKnopf): beim Zeigen ein Tooltip, ein Klick öffnet ein kleines Panel. Das ⓘ zeigt sich nur beim Überfahren der Angabe - nicht ruhend, nicht während man im Feld arbeitet, und auf Touch-Geräten gar nicht (PO 2026-10-04). Muss man den Hinweis auch dort lesen, bevor man weitermacht - dass die Altersstufe eines Trainings lebenslang bindet -, zeigt infoAufTouch ihn auf Touch-Geräten als Hinweis unter dem Feld. Das ⓘ steht senkrecht mittig auf der ganzen Angabe, zwischen Name und Wert. Die Tastatur erreicht es weiterhin und macht es dabei sichtbar; die Vorlesehilfe hört den Hinweis ohnehin mit dem Feld. Fehler und Hinweise, die sich mit der Eingabe ändern, bleiben sichtbar unter dem Feld (supportingText) - die muss man sehen, ohne zu klicken. Ein fester Hinweis steht also nie dauernd unter einem Feld, auch nicht in eigenen Bausteinen. Betrifft ein Hinweis mehrere Felder, wird er auf sie aufgeteilt: Jedes Feld sagt hinter seinem ⓘ, was für es gilt - kein Sammelhinweis über einer Gruppe (PO 2026-10-06).

Grosser Wert (schrift="title"): Für den Namen, mit dem etwas erst angelegt wird - zuoberst in «Neues Training» und «Neue Übung», nach dem Vorbild der Zusammenfassung in Jira. Der Wert steht in type-title-large, das Feld ist 44 px hoch; Name, Fläche beim Überfahren und das Verhalten leer und gefüllt bleiben die eines gewöhnlichen Felds. Wo ein bestehender Name dort geändert wird, wo er steht, gilt weiter das Kopf-Feld.

Ein fester Hinweis steht hinter dem ⓘ, nicht dauernd unter dem Feld.

Bitte eine Zahl ≥ 2 eingeben.

Mit Auge-Zeichen ein- und ausblendbar.

Leer zwei Zeilen hoch - wächst bis 10 Zeilen, dann scrollen.

Leer steht der Name im Feld; der Hinweis darunter bleibt.

Suchfeld (SearchField)

Dasselbe Feld, dessen Zeichen aber rechts steht - an demselben Platz, an dem das Passwortfeld sein Auge trägt. Das ist die Hausregel: links steht Schmuck, rechts steht Bedienbares. Und das Zeichen am Suchfeld ist beides nacheinander - solange nichts eingegeben ist, sagt die Lupe, wofür das Feld da ist; sobald etwas dasteht, tritt an ihre Stelle ein Kreuz, das die Suche mit einem Klick leert und den Cursor zurück ins Feld setzt. Das Kreuz meldet sich über dasselbe onChange wie eine Tastatureingabe - es gibt keinen zweiten Rückkanal, den ein Aufrufer vergessen könnte, und eine verzögerte Suche verzögert auch das Leeren. In der Filterleiste steht es ohne sichtbaren Namen (labelVersteckt), dafür umrandet und mit Platzhalter.

Kopf-Feld (HeadlineField)

Für den Fall, in dem ein vom Trainer vergebener Name dort geändert wird, wo er steht - der Trainingsname im Editor-Kopf und der Name beim Bearbeiten einer Übung. Es trägt die Schrift der Überschrift (type-headline-medium), damit der Kopf seine Gliederung behält, und zeigt sich in drei Lagen: Ruhend sieht man eine Überschrift und kein Feld - keine Kontur, keine Fläche. Beim Zeigen legt sich eine Fläche darunter (bg-elev-04), und die ist die ganze Ankündigung: Hier lässt sich etwas eintragen. Erst im Fokus kommt die Kontur in Primary. Die Stufe 04 ist mit Absicht kein Nachbar der Karte, auf der das Feld gewöhnlich liegt (01): Eine Stufe darüber wäre rechnerisch eine Fläche und am Bildschirm keine.

Es folgt derselben Idee wie der Feldkasten - ruhend nichts, beim Zeigen eine Fläche, im Fokus die Kontur -, nur in der Schrift der Überschrift und ohne Namen darüber. Die Konturstärke bleibt zwischen Ruhe und Fokus gleich und wechselt nur die Farbe - ein Sprung verschöbe bei 28 px Schrift die ganze Zeile sichtbar.

Kein Name darüber: Der Wert ist bereits die Überschrift, ein Label daneben benennte dieselbe Sache ein zweites Mal. Den Namen trägt darum aria-label - Pflicht, nicht Kür. Und weil ein <input> keine Überschrift ist, gehört daneben eine echte, nur vorgelesene (sr-only), sonst verlöre die Seite ihre Gliederung.

Schrift der Überschrift, die es ersetzt: schrift="headline" (Vorgabe, Trainingsname) oder schrift="title" für den Namen einer Übung - ihre Seite führt ihn in type-title-large.

Zahlenfelder

Zahlenfelder (type="number") zählen nie von selbst: keine Pfeile im Feld, und weder Pfeiltasten noch Mausrad ändern den Wert. Eine Zahl wird getippt; ein Scrollen über dem fokussierten Feld verstellte sie sonst unbemerkt.

Bitte eine Zahl ≥ 1 eingeben.

Befund am Feld (befund) und gemischter Supporting-Text

Zwei Ergänzungen aus der Gruppenverteilung (Story #151). befund färbt den Rahmen in Error: Der Wert ist gespeichert und richtig erfasst, geht aber mit anderen nicht auf - etwa eine Dauer in einem Wechsel, dessen Übungen ungleich lang sind. Befund und Fehleingabe tragen dieselbe Farbe; sie unterscheiden sich in aria-invalid und im Verhalten, nicht im Bild. Material kennt nur eine Fehlerrolle; Atlassians Warnfarbe (warning) gehört der Lozenge und der Section Message, nicht dem Feld. Was bleibt, ist der Unterschied im Verhalten: Ein error weist die Eingabe ab und meldet sich der Vorlesehilfe als ungültig, ein befund lässt speichern und trägt seinen Satz im Supporting-Text. Am Rahmen gilt die Rangfolge error > befund > Fokus: Der Fokus färbt nur den ruhigen Rahmen um und zeigt sich im Fehler über einen halben Pixel nach innen, damit ein Befund nicht ausgerechnet beim Hinschauen verschwindet. Weil der Rahmen allein nur sehend wahrnehmbar ist, gehört zu befund ein Hinweis für Screenreader (an der Dauer einer Übung ein sr-only-Satz per aria-describedby).

supportingText nimmt seit derselben Story einen ReactNode, weil unter einem Feld zwei Aussagen in einer Zeile stehen können - so trägt die Gruppenzeile die Zeitsumme (eine Auskunft) und dahinter den Konflikt (ein Befund). Nur der zweite Teil ist eingefärbt - die ganze Zeile zu färben liesse nicht mehr erkennen, was daran gemeldet ist.

Zugewiesen 40 min · Steht im 1. Wechsel an zwei Übungen.

Hinzufügen in Feldgestalt

Wo ein Formular eine Liste gleichartiger Einträge führt - Felder eines Termins, Material einer Übung -, steht unter der Liste kein Textknopf, sondern HinzufuegenFeld: eine Zeile in der Gestalt eines leeren Felds, nach dem Vorbild von «Add subtask» in Jira (PO 2026-10-06). Gleiche Höhe, gleicher Einzug und gleiche Schrift wie der Name im leeren Feldkasten, ruhend ohne Fläche, beim Überfahren dieselbe leise Aufhellung; ohne Zeichen - der Text sagt, was ein Klick tut (PO 2026-10-06). Ein fachlicher Hinweis zur ganzen Liste - was ein Eintrag ist - steht über info hinter dem ⓘ rechts in der Zeile, wie bei einem Feld nur beim Überfahren sichtbar.

Was ein Eintrag dieser Liste ist und was nicht hierher gehört.

Datum & Uhrzeit

Für Trainings-Termine, mit Name und Feldkasten wie jedes Feld. Das native Steuerelement ist Absicht - Datumsauswahl, Tastatureingabe und Lokalisierung kommen vom Betriebssystem. Damit der Browser sie dunkel zeichnet - auch das Kalender- und Uhr-Zeichen im Feld -, erklärt sich die Anwendung als dunkel (color-scheme: dark auf :root und im Wurzel-Layout); der Druck schaltet auf hell um. Leer zeigt es sich wie jedes leere Feld (nach dem Vorbild von «Start date» in Jira, PO 2026-10-06): keine Maske («dd/mm/yyyy», «--:--») und kein Name darüber, sondern das Kalender- bzw. Uhr-Zeichen und der Name gedämpft im Feld. Ein Klick oder ein Wert bringt das native Steuerelement zurück.

Checkbox

Für eine Ja/Nein-Angabe in einem Formular, die weitere Felder zuschaltet oder eine Folge hat - «Wiederholender Termin» im Termin-Dialog, «Foto entfernen» im Übungsformular. Neu ist sie, weil beide Stellen sonst ein unverkleidetes Browser-Kästchen trügen. Sie trägt dasselbe eckige Kästchen wie die Optionen der Mehrfachauswahl (Mehrfachauswahl): gewählt gefüllt in Primary, Haken in on-primary. Darunter liegt ein echtes <input type="checkbox">; das Label gehört zur Klickfläche. Zwischen Feldern eines Formulars steht sie auf der Linie der Feldnamen, eingerückt wie sie (px-3.5), damit alles linksbündig liest (PO 2026-10-06). Ein Filter ist sie nicht - der bleibt ein FilterChip (Lozenge, Badge & Chips).

Formulare und Eingabe

Offene Einfachauswahl

Genau ein Wert aus einer Menge, die offen liegt - kein aufklappendes Menü. Ein Baustein: ChoiceChipGroup, mit Pfeiltasten-Navigation und wanderndem Tabstopp.

Die offene Einfachauswahl ist seit dem 2026-09-13 der Sonderfall, nicht die Regel: Formulare führen ihre Einfachauswahl in der Einfachauswahl mit Panel, ihre Mehrfachauswahl in der Mehrfachauswahl - siehe den Kasten unten. Offen bleibt, was in kein Menü gehört: die Variantenwahl, deren Werte der Trainer selbst benannt hat.

ChoiceChipGroup - lange Werte, umbrechend

Radiogroup-Semantik (role=radiogroup / role=radio, aria-checked) - es ist ein Eingabefeld, keine Ansicht, und darum keine Tabs. Optik aus den Chip-Bündeln, ausgewählt gefüllt in Primary (chipSelected) und ohne Häkchen: Einfachauswahl ist kein Ein/Aus-Zustand, und der Flächenwechsel trägt die Aussage bereits. Mit look="nutzertext"steht die Wahl dagegen umrandet wie ein Filter (Lozenge, Badge & Chips). Die Chips umbrechen - das ist ihr eigentlicher Vorzug: Eine Reihe, die stattdessen seitlich scrollte, zeigte dem Nutzer seine Optionen nicht mehr nebeneinander. In Gebrauch ist der Baustein bei der Variantenwahl, deren Bezeichnungen bis vierzig Zeichen lang sein dürfen.

AuswahlListe - Einträge mit Titel und Untertitel

Dieselbe Radiogroup-Semantik wie die Chip-Gruppe, aber senkrecht und mit zwei Zeilen je Eintrag - für Trainings und Termine, die zu lang für Chips sind; ein listbox mit verschachtelten Knöpfen wäre kein gültiges ARIA. Pfeil hoch/runter wählt und bewegt den Fokus. Gewählt trägt der Eintrag eine Kontur in Primary und ein Häkchen, aber keine Fläche: Die Liste steht im Dialog auf 24dp, und jede tiefere Stufe läge dort eingesunken statt hervorgehoben. Die Schrift bleibt neutral - Primary trüge auf 24dp keine zwei Zeilen Lesetext.

Warum das Übungsformular nichts mehr offen legt

Altersstufe und Einordnung lagen zwischen dem 2026-08-30 und dem 2026-09-13 offen, mit einem guten Grund: Beide entscheiden über die halbe Maske darunter, und diese Tragweite sollte man sehen, ohne erst zu klicken. Das Argument gilt weiter - es verliert nur gegen ein stärkeres. Ein Formular mit sieben Auswahlfeldern, von denen zwei eine Segmentleiste sind, eins eine Chip-Reihe, zwei ein Auswahlmenü und zwei ein Chip-Bündel, sieht nicht nach Gewichtung aus, sondern nach Zufall: Der Trainer liest keine Rangordnung ab, er lernt vier Bedienweisen für dieselbe Handlung. Seit dem 2026-09-13 führt die Maske darum jede Einfachauswahl als Einfachauswahl mit Panel und jede Mehrfachauswahl als Mehrfachauswahl (PO-Vorgabe). Die Tragweite trägt jetzt der Hilfstext unter dem Feld, nicht seine Bauform.

AltersstufeField - eine Wahl, zwei Domänen

Übung und Training wählen dieselbe Altersstufe und teilen sich darum denselben Baustein im Kit - auch wenn er seit dem 2026-09-13 keine offene Wahl mehr ist. Er hat drei Zustände: Wahl (ein Select, siehe Einfachauswahl mit Panel), fest (neutrale Lozenge plus Erklärsatz) und ungewählt (wert = null). Der letzte ist der Ausgangszustand am Training: Die Wahl bindet dort lebenslang und darf nicht durch eine Voreinstellung durchrutschen - also steht dort der Leerfall als erste Option in der Liste, und nur dort. An der Übung ist sie vorbelegt, weil eine Übung umwandelbar bleibt; einmal gesetzt, lässt sich die Stufe nicht auf «keine» zurückstellen. Die Lozenge ist bewusst neutral: Die Altersstufe ist keine Alterskategorie und borgt deren Akzentfarben nicht. Der feste Zustand nimmt über aktion ein Bedienelement neben der Lozenge auf - dort hängt das Überführen einer eigenen Übung in die andere Altersstufe. Es gehört nicht ins Auswahlfeld: An einer gespeicherten Übung ist der Stufenwechsel kein Feld, sondern ein eigener, zu bestätigender Vorgang.

Formulare und Eingabe

Einfachauswahl mit Panel

Auswahl eines Werts - kein natives <select>. Der Auslöser ist ein Feldkasten wie am Textfeld (Textfelder, Text-Area, Datum & Zeit), mit dem Namen darüber; das aufgeklappte Panel ist ein Menü (08dp, Haarlinie, shadow-dp-08, Häkchen auf der Auswahl). Die Zeile, auf der die Tastatur gerade steht, trägt state-aktiv - dieselbe Deckung wie der Fokus, aber ohne echten :focus-visible, denn der liegt auf dem Trigger. Listbox-Semantik mit voller Tastatursteuerung (↑/↓, Home/End, Enter, Esc). Offen trägt der Auslöser die Kontur in Primary - er gehört dann zum Panel darunter. Den Pfeil zeigt das Feld nur, solange man darin arbeitet (Fokus oder offene Liste): Ruhend zeigt das Formular Namen und Werte, keine Bedienelemente - sobald man hineingeht, sagt der Pfeil, dass hier gewählt wird (nach dem Vorbild von Jira). Der gewählte Wert steht ganz im Feld und bricht um, statt abgeschnitten zu werden: Eine Einordnung ist oft ein Satz.

Keine Option «- kein … -»: Ist nichts gewählt, ist das Feld leer und zeigt nur seinen Namen (Textfelder, Text-Area, Datum & Zeit) - bei einem optionalen Feld heisst das schon «nicht angegeben». Eine Option für «keiner» sähe aus wie eine getroffene Wahl und verdoppelte, was das leere Feld sagt. Wo «keiner» fachlich doch eine Antwort ist, gehört sie als eigener Wert ins Vokabular (beim Feldtyp etwa «Freies Feld»).

group stellt einer Option eine nicht wählbare Kopfzeile voran, sobald die Gruppe wechselt - wie bei der Mehrfachauswahl und mit derselben Pflicht: Die Optionen müssen gruppensortiert übergeben werden, sonst erscheint dieselbe Kopfzeile mehrfach. Das trägt die Einordnung einer Junioren-Übung: Gewählt wird einer der sieben Blöcke, der Trainingsteil steht als Kopfzeile darüber - so bleibt sichtbar, wozu ein Block gehört, ohne dass das Formular eine zweite Bedienebene aufmachen muss. Im Kinderfussball fällt die Gruppierung weg; dort ist der Trainingsteil selbst die Einordnung, vier flache Werte. Im Übungsformular laufen ausserdem Altersstufe, Hauptteilkategorie, Feldtyp und Übungstyp über diesen Baustein - jede Einfachauswahl der Maske, ohne Ausnahme (PO-Vorgabe 2026-09-13, siehe Offene Einfachauswahl).

Öffnet ein eigenes Panel statt des Betriebssystem-Dropdowns.

Jede Option ist ein Wert - kein Platzhalter nötig.

Noch nichts gewählt: Der Name steht gedämpft im Feld.

Formulare und Eingabe

Mehrfachauswahl

Auswahl mehrerer Werte im Formular: ein Feldkasten mit dem Namen darüber, der die gewählten Werte als kommagetrennte Zeile zeigt und umbricht, wo sie nicht in eine Zeile passen (Epic #363). Er öffnet ein Panel mit Suchfeld im Kopf, Optionsliste (eckige Checkbox, rounded-klein) und Aktions-Fuss (Zurücksetzen / Alle auswählen, respektiert den aktiven Filter). Keine Tags im Feld: Entfernt wird in der Liste, wo auch gewählt wird; ein Kreuzchen pro Wert im Feld wäre ein zweiter Ort dafür. Die Werte stehen in der Reihenfolge der Optionsliste, nicht in der des Anklickens: Dieselbe Auswahl soll immer gleich lauten. Ist nichts gewählt, ist das Feld leer und zeigt seinen Namen (Textfelder, Text-Area, Datum & Zeit). Combobox- und Listbox-Semantik (aria-multiselectable) mit voller Tastatursteuerung (↑/↓, Home/End, Enter toggelt, Esc schliesst). searchable / actions einzeln abschaltbar für kurze feste Listen. group stellt einer Option eine nicht wählbare Kopfzeile voran, sobald die Gruppe wechselt - für Dimensionen, deren Werte aus zwei Welten stammen (in der Anwendung: die Altersstufe, siehe lib/filter-optionen.ts). Weil die Kopfzeile positional entsteht, müssen die Optionen gruppensortiert übergeben werden, sonst erscheint dieselbe Kopfzeile mehrfach. Eine einzige Gruppe ist ausdrücklich erlaubt und der Normalfall dort, wo eine Dimension ganz zu einer Welt gehört; die Beschriftung sagt dann, zu welcher. Die Kopfzeile ist nicht nur optisch: Jede Option verweist per aria-describedby auf sie, damit die Zugehörigkeit auch vorgelesen wird («Wert, Gruppe») - sonst hörte man eine lange Liste ohne jede Gliederung.

Der Baustein trägt beide Mehrfachauswahlen des Übungsformulars - Alterskategorie und Erscheinungsform; die Filterleisten führen ihre Dimensionen dagegen als Filterknopf. Im Formular unterscheiden sich die beiden in der Ausstattung: Die Alterskategorie schaltet searchable und actions ab (drei bis vier kurze Werte liest man schneller, als man sie filtert), die Erscheinungsform behält beides (der Junioren-Katalog führt elf Werte, und jeder ist ein ganzer Satz). Im Formular heisst nichts gewählt nichts, im Filter alles - darum ist der Filter ein eigener Baustein (Filterknopf).

Suche im Panel-Kopf · Footer: Zurücksetzen / Alle auswählen.

gewählt: passen, dribbling

searchable={false} actions={false}: Trigger treibt die Liste, ↑/↓ + Enter.

Leer: der Name steht im Feld · gewählt: Name darüber, die Werte umbrechend.

group: nicht wählbare Kopfzeile je Gruppe. Werte beider Gruppen bleiben gemeinsam wählbar.

WochentagWahl - sieben feste Werte, sichtbar

Für die sieben festen Wochentage einer Terminserie; alle Werte stehen sichtbar nebeneinander. Neu ist der Baustein, weil die Mehrfachauswahl ein Panel öffnet - bei sieben kurzen Werten, die man auf einen Blick vergleichen will, wäre das ein Klick zu viel. Jeder Wert ist ein FilterChip (Ein/Aus, aria-pressed, gewählt in Primary umrandet); das Kürzel steht sichtbar, der volle Wochentag für Screenreader. Montag zuerst, die Wahl bleibt sortiert. Ein Fehler steht unter den Chips.

Wochentage

Formulare und Eingabe

Variantenwahl

Zwischen den Varianten des Hauptteils eines Trainings wechseln (Epic „Hauptteil-Varianten"). Kein neuer Baustein, sondern eine Anwendung der ChoiceChipGroup (Offene Einfachauswahl) - hier steht, warum gerade sie:

  • Die Werte sind Nutzertext - bis vierzig Zeichen, vom Trainer vergeben. Eine Reihe, die damit seitlich scrollte, zeigte ihm seine Varianten nicht mehr nebeneinander; Chips umbrechen stattdessen. Aus demselben Grund steht die gewählte Variante umrandet und nicht gefüllt (siehe Lozenge, Badge & Chips).
  • Es ist ein Element von n und keine Ansicht: Radiogroup-Semantik, nicht die tab-artige Leiste.
  • Bei einer Variante rendert sie nichts. Ein Training ohne zweite Variante sieht aus wie vorher - eine Einfachauswahl mit einem einzigen Wert wäre eine Frage ohne Alternative. Die Schranke sitzt im Baustein, nicht bei den Aufrufern.

drei Varianten - ein Element von n, Pfeiltasten bewegen die Auswahl

eine Variante - der Baustein rendert nichts (unten steht nur dieser Satz)

Zwei Bedienelemente, eine Zeile

Im Editor steht die Wahl zusammen mit „Variante hinzufügen" in einer eigenen Zeile unter dem Kartenkopf des Hauptteils - nicht IM Kopf: Dort stehen Überschrift und Dauer-Summe, und eine umbrechende Chip-Reihe daneben risse die Kopfzeile auseinander. Über der Gruppenleiste, weil die Variante die grössere Klammer ist: Sie entscheidet, welche Übungen darunter stehen; die Gruppen gelten für alle Varianten.

Auf Server-Seiten: dieselbe Optik, aber Links. Ansehen und Drucken halten keinen Zustand - die angezeigte Variante steht im Suchparameter, jede Variante hat damit eine eigene Adresse. VariantenLinks rendert darum <nav> mit Links und aria-current="page", leiht sich aber die Nutzertext-Pille der Offene Einfachauswahl (chipTextBase, chipTextOutlined, chipTextSelected): gleiche Sache, gleiches Bild. Kein wandernder Tabstopp - durch Links tabbt man, Pfeiltasten gehören der Radiogroup. Nicht TabNav (Knöpfe): Die wechselt die Sicht auf einen Gegenstand; hier bleibt die Sicht dieselbe und der Inhalt wechselt. Weil Nutzertext versal verfälscht stünde, kennt ChoiceChip seit dem Chip-Umbau ein look="nutzertext" mit denselben Bündeln: dieselbe Pille, aber normal gesetzt und h-9 hoch, damit sie neben dem geteilten Chip mit Menü und dem leisen Knopf (Knöpfe) auf einer Linie sitzt.

drei Varianten als Links - die offene trägt aria-current

Formulare und Eingabe

Filterknopf

Ein Filter ist ein Knopf mit seinem Namen (Epic #363, nach dem Vorbild der Filter in Jira). Er nennt, wonach gefiltert wird, und zählt, wie viele Werte gewählt sind; welche, sieht man im geöffneten Panel. So bleibt eine Filterleiste eine Zeile aus Wörtern - auf dem Handy umbrechend, aber nie ein Stapel aus Feldern mit abgeschnittenen Wertlisten. Neu ist der Baustein, weil die Mehrfachauswahl ein Formularfeld ist: Sie zeigt ihre Werte, weil sie dort die Eingabe sind; im Filter sind sie nur ein Zustand der Übersicht.

Er trägt Schrift und Kleid des Filter-Chips (Lozenge, Badge & Chips), der in derselben Leiste steht - normal gesetzt in type-body-medium, leiser als ein halbfetter Knopf, denn er grenzt ein, statt etwas auszulösen; nur eckig statt rund, weil er ein Panel öffnet statt bloss umzuschalten. Grenzt er ein, steht er in Primary umrandet wie ein gewählter Chip und trägt die Zahl als Badge (Lozenge, Badge & Chips) - vorgelesen wird «Alterskategorie, 2 gewählt». Das Panel ist breiter als der Knopf, wo der Inhalt es braucht (bis 34 rem; der längste Übungstyp misst 484 px), und rückt am rechten Rand nach links (usePanelAnker, geteilt mit der Mehrfachauswahl). Es ist kein Menü und keine Listbox, sondern eine Gruppe gewöhnlicher Bedienelemente: Kontrollkästchen im AuswahlFilter, ein Zahlenfeld im ZahlFilter («Verfügbare Kinder»). ↑/↓ wandern zwischen ihnen, Esc schliesst und gibt den Fokus an den Knopf zurück. Eine Wahl wirkt sofort, das Panel bleibt offen; Zahl und Suche wirken nach einer Tipppause.

Die Suche der Leiste (FilterSuche) steht ohne sichtbaren Namen, dafür umrandet und mit Platzhalter (Textfelder, Text-Area, Datum & Zeit) - ohne Kante stünde neben den umrandeten Knöpfen ein Feld, das man nicht sieht. Schalter wie «Meine Übungen» bleiben FilterChip (Lozenge, Badge & Chips): Sie haben kein Panel, nur an und aus.

Formulare und Eingabe

Chip mit Menü

Ein Chip, der ein Menü öffnet - für Werte, die man an ihrem Ort umsortieren oder herausnehmen können muss. Warum der Assist-Chip nicht reicht: Der AssistChip löst genau eine Aktion aus, nicht mehrere zur Wahl. Er trägt ausserdem type-label-medium, also versal: ein Gruppenname stünde dort verfälscht (siehe Regel unter Typografie). Der Chip mit Menü trägt darum type-body-medium und ist ein Bedienelement mit einem Tabstopp - kein Chip plus angehängter Knopf.

Geteilte Bauform (onSelect). Sobald an demselben Wert zwei Aufgaben hängen - „zeig mir diese Variante" und „benenne, verschiebe, entferne sie" -, wird der Chip in der Mitte geteilt: links wählen, rechts das Menü. Ein Menüeintrag „Anzeigen" allein reichte nicht, denn Wechseln ist die häufigste Handlung der Leiste und darf nicht zwei Klicks kosten. Die Menühälfte ist 36 px breit wie jeder Icon-Knopf - ein eigenes Bedienelement, nicht ein angehängtes 16px-Chevron. Der Umriss gehört trotzdem der Gruppe: eine Reihe von Varianten, nicht eine Reihe von Knopfpaaren; der Trennstrich darin folgt dem Zustand.

Warum hier keine Radiogroup mehr (anders als bei der Variantenwahl): Eine Radiogroup verlangt genau EIN fokussierbares Element je Wert und übernimmt die Pfeiltasten. Hier sind es zwei Elemente, und die Pfeiltasten gehören dem geöffneten Menü. Die Wahl sagt darum aria-pressed an der linken Hälfte; durch die Leiste tabbt man.

tone="befund" färbt Kontur und Chevron in Error, nie die Fläche - dieselbe Regel und dieselbe Farbe wie am Feld (Textfelder, Text-Area, Datum & Zeit): Der Wert ist gespeichert, er geht bloss mit anderen nicht auf.

Sequenz aus Nutzertext - jeder Chip ein Bedienelement, ein Tabstopp

geteilt - links wählt (aria-pressed), rechts öffnet das Menü (36 px)

angezeigt: Standard

tone="befund" - Rahmen und Chevron, nie die Fläche; dazu ein gedämpfter trailing-Zusatz

klicken oder Enter, dann ↑/↓

Plaketten

Lozenge, Badge & Chips

Lozenge heisst die Plakette wie bei Atlassian: ein kurzer Status oder eine Eigenschaft, auf einen Blick erkennbar - kein Bedienelement. Anatomie wie @atlaskit/lozenge: 20 px hoch, rounded-flaeche (4 px), 2 px Polsterung oben und unten, 4 px seitlich, type-lozenge, höchstens 200 px breit, Überlänge endet mit «…». Ein Zeichen davor (iconBefore) steht 12 px gross in der Schriftfarbe.

Die Darstellung (appearance) trägt Atlassians Namen und Bedeutung: neutral sagt, woher etwas stammt oder in welchem Zwischenstand es liegt (Kifu-Manual, Entwurf, Altersstufe, ausgefallen), information, was nach aussen gilt (Community, Öffentlich), discovery etwas Zusätzliches (mehrere Varianten, «Neu» an der Version), warning eine Lücke, die jemand schliessen muss (Termin ohne Training). success und danger stehen im Kit bereit. Herkunft und Sichtbarkeit stehen fertig als HerkunftLozenge und SichtbarkeitLozenge; der Entwurf trägt den Stift, damit er sich vom Manual-Bestand nicht nur im Wort unterscheidet.

Über einem Bild (aufBild, etwa die Herkunft auf der Übungskarte): Die neutrale Fläche ist halbtransparent und hinge dort am Foto darunter. Mit aufBild steht sie im deckenden accent-gray, das am Schirm gleich aussieht und über jedem Bild trägt; alle übrigen Darstellungen sind ohnehin deckend.

neutralinformationdiscoverywarningsuccessdanger
Kifu-ManualEntwurfCommunityÖffentlich2 VariantenKinderfussballAusgefallen
Kifu-ManualEntwurfCommunityaufBild - über einem hellen Foto

Alterskategorien - Accent-Lozenges

GFEDCBA

Wie Jira Kategorien ohne Wertung färbt, trägt jede Stufe einen festen Atlassian-Akzent (accent-blue bis accent-gray); der Titel nennt die Stufe ausgeschrieben. Die Zuordnung steht einmal in KategorieLozenge und gilt überall, wo eine Kategorie angezeigt wird - auch im Druck, wo die Rollen ins helle Theme wechseln. Wo eine gewählt wird, gilt sie seit dem 2026-09-13 nicht mehr: Die Alterskategorien stehen am Training, am Team und an der Übung in einer Mehrfachauswahl, und die führt Text, keine Lozenges (PO-Entscheid).

Badge

Badge heisst der Zähler wie bei Atlassian: eine Zahl an einem Knopf, die zählt, was dessen Handlung bewirkt (gewählte Werte am Filterknopf, Übernahmen in der Übungsauswahl). Anatomie wie @atlaskit/badge: rounded-klein, 4 px seitlich, mindestens 24 px breit, type-lozenge. Gefüllt in Primary - Atlassians Markenfarbe ist bei uns das Lila -, weil sie als Teil des Knopfes gelesen wird, nicht als eigene Aussage über den Inhalt. Für die Vorlesehilfe stumm: Der Knopf sagt die Zahl in Worten.

Chips

Ungewählt steht jeder Chip auf der Kante. Gewählt gibt es zweimal. Umrandet (chipTextSelected - Primary-Kontur, Primary-Schrift, keine Fläche, kein Häkchen) sind der Filter und der Chip, der Nutzertext trägt - eine Variante, ein Gruppenname. Dasselbe trägt das gewählte Glied der verbundenen Knopfgruppe (Knöpfe) und der eingrenzende Filterknopf. Ohne Fläche steht die Primary-Schrift auf dem dunklen Grund am klarsten (Epic #363); eine getönte Fläche nahm ihr Kontrast. Ein Filter steht neben Suchfeld, Auswahl und Knöpfen; gefüllt wäre er lauter als die Handlung daneben, und der Farbwechsel sagt «an» bereits. Eine gefüllte Fläche schriee zudem den Namen an, den die Trainerin selbst vergeben hat. Gefüllt (chipSelected - Primary-Fläche, schwarze Schrift) bleibt allein die Offene Einfachauswahl. Im geteilten Chip folgt der Trennstrich dem Zustand (border-primary/50 gewählt, border-kante sonst).

Schrift. Der Filter steht normal gesetzt in type-body-medium, wie der Nutzertext-Chip - er sitzt in Leisten neben Suchfeld, Auswahl und Knöpfen und liest sich dort als Wort («Meine Termine»), nicht als Rubrik, und bleibt leiser als der halbfette Knopf daneben, der die Handlung trägt. Der Assist-Chip und die offene Einfachauswahl bleiben versal in type-label-medium.

Eine Höhe. Jeder Chip ist 36 px hoch, im Fliesstext wie in einer Filterleiste - dasselbe Mass wie Knopf, Feld und Filterknopf, darum fluchtet er überall ohne eigene Stufe.

Filter-Chips (toggelbar)

Assist-Chip

Meldungen

Leerzustand, Hinweiszeile & Section Message

Ein leerer Abschnitt sagt zuerst nur, dass er leer ist - type-body-small, text-on-surface-mittel, kein Zeichen. Hat die Anwendung fachlich etwas dazu zu sagen (im Trainings-Editor: dieser Block gehört ins Training), tritt die Hinweiszeile an die Stelle dieser neutralen Zeile - nie beides. Dieselbe Sachlage erscheint nur einmal und nur in einem Schriftschnitt.

Die Hinweiszeile trägt darum denselben Schnitt wie der Leerzustand und ordnet sich der Struktur unter: schwächer als Titel und Inhaltszeilen. Das Merkmal ist das Info-Zeichen (15 px, text-primary, aria-hidden) - es bleibt ohne Farbwahrnehmung erkennbar. Der Text nennt den Grund, die Position den betroffenen Abschnitt; er blockiert nichts. Zählende Meldungen einer ganzen Karte („Ungewöhnlich viele Übungen …") bleiben davon unberührt und stehen weiter als type-label-medium am Kartenfuss.

Fläche für Blöcke einer dichten Karte: Trägt eine Karte mehrere gleichrangige Blöcke - die Unterkategorien des Kinderfussball-Hauptteils, die Blöcke des Junioren-Einstiegs -, steht jeder auf einer eigenen Fläche: bg-elev-02, rounded-flaeche, p-3. Also eine Stufe die Leiter hoch gegenüber der Karte, während die Inhaltszeilen darin auf bg-elev-01 bleiben und sich dadurch als Inhalt im Block lesen. Nicht dieselbe Stufe wie die Karte: Bei gleicher Fläche verschwimmen Block und Karte, und ein leerer Block - beim Planen die wichtigste Auskunft - wäre bloss eine Zeile Text im Nichts. Ein Teil mit nur einem Block bekommt keine Fläche: Sie wiederholte dort bloss die Karte.

Hauptteil

Vielseitigkeit erleben

Noch keine Übung zugeordnet.

Fussball spielen

Das freie Spiel ist noch leer - im Kinderfussball gehört es in jedes Training.

Seiten-Leerfeld (Leerzustand)

Ist nicht ein Block leer, sondern eine ganze Liste - der Katalog ohne Treffer, die Team-Übersicht vor dem ersten Team -, dann steht an ihrer Stelle ein Feld mit gestrichelter Kontur, Zeichen, Titel und einem Satz zum Weiterkommen. Die gestrichelte Linie ist die ganze Aussage: Eine durchgezogene Kontur umreisst etwas, das da ist; die gestrichelte sagt, dass hier etwas hingehört und noch fehlt. Die Fläche bleibt der Grund - ein eigener Ton machte aus dem Fehlenden eine Karte.

Abgrenzung zur Block-Leerzeile oben: Die steht innerhalb eines Blocks, ist blosser Text und bekommt weder Rahmen noch Zeichen - ein Rahmen im Rahmen zöge einen zweiten Strich um etwas, das der Block schon abgrenzt. Das Leerfeld hier füllt umgekehrt eine ganze Seite oder einen ganzen Abschnitt. dicht nimmt die Polsterung zurück, wo es unter einer Überschrift im Abschnitt steht statt allein auf der Seite; das Zeichen entfällt dort meist mit. Ist das Leerfeld die ganze Seite - nicht gefunden, Training nicht verfügbar -, macht ueberschrift="h1" den Titel zur Überschrift der Seite: dieselbe Schrift, aber die Vorlesehilfe findet die Seite gegliedert.

Keine Übung gefunden

Keine Übung erfüllt alle gesetzten Filter. Entferne einzelne Filter oder setze sie zurück.

Noch keine Termine

Lege die Trainingszeiten des Teams als Termine fest. Welches Training dort stattfindet, ordnest du danach zu.

Section Message (SectionMessage)

Die dritte Sorte Zeile: keine Auskunft über den Bestand, sondern eine Nachricht an den Nutzer - das Speichern ist gescheitert, die Mail ist unterwegs, das Feld-Diagramm zeigt anderes Material. Ohne Knöpfe meldet sie bloss; mit ein oder zwei Knöpfen verlangt sie eine Antwort und bleibt stehen, bis eine gewählt ist. Baustein und Name stammen von Atlassian wie in Jira. Nicht Atlassians Banner: Der ist ein kräftig gefüllter, einzeiliger Streifen über die ganze Seite für seitenweite Ankündigungen - eine solche gibt es in KiFu nicht.

Anatomie wie @atlaskit/section-message: eine getönte Fläche ohne Kontur (section-*), 16 px Polsterung, rounded-dialog, das Zeichen 16 px (im 24-px-Feld) in icon-* links, 16 px zum Text. Der Text steht in type-body-medium und on-surface; den Ton tragen Fläche und Zeichen. Die Knöpfe (text) stehen wie Atlassians Aktionen unter dem Text und fluchten mit ihm, abweisend zuerst.

Die Darstellungen tragen Atlassians Namen: error meldet, dass etwas nicht ging, information (Vorgabe) alles andere; warning, success und discovery stehen im Kit bereit. Das Zeichen lässt sich überschreiben, die Farbe bleibt die der Darstellung. Die Vorlesehilfe erfährt den Ton über role: ein Fehler ohne Knöpfe unterbricht (alert), alles andere reiht sich ein (status).

Im Dialog steht ein gescheiterter Vorgang als error zuoberst, vor dem Inhalt, mit mb-4 Abstand; der Dialog bleibt offen. Was nur ein Feld betrifft, bleibt dagegen Fehlertext am Feld (Textfelder, Text-Area, Datum & Zeit).

Am Fuss der öffentlichen Trainings-Seiten steht für Besucher ohne Konto der AnmeldeHinweis: eine Meldung mit eigenem Zeichen und dem Weg zum Konto als Aktion. Auf Papier fehlt er.

warning - im Kit, derzeit ohne Ort.
success - im Kit, derzeit ohne Ort.
discovery - im Kit, derzeit ohne Ort.

Meldungen

Dialog & Snackbar

Der Dialog steht auf nativem <dialog> (Fokus-Falle, Escape, Scrim) und trägt die oberste Stufe: bg-elev-24, rounded-dialog - der einzige Ort mit 6 px -, shadow-dp-24 und ein Scrim bei 60 %. Sein Titel steht in type-title-large wie der Name einer Übung - ein Dialog ist ein Arbeitsschritt, kein Plakat. Er ist 28 rem breit; Formulare mit vielen Angaben - die Termin-Dialoge mit Feldern und Spielerzahl - nehmen breit (40 rem), schmal bleibt er bis zum Rand minus 2 rem (PO 2026-10-06). Die Snackbar ist die eine umgekehrte Fläche der Anwendung (umkehr): Weiss zu 87 % über dem Grund, darauf der Grund als Schrift (13.97:1) und das dunkle Violett als Aktion (7.81:1). Sie meldet am Bildrand und geht von selbst, also muss sie beim ersten Hinsehen auffallen. Auf elev-06 hob sie sich nur 1.36:1 vom Grund ab und blieb unbemerkt; hell steht sie bei 13.97:1. So meint Material sie auch. Innerhalb der Fläche gelten die Rollen umgekehrt - Primary ist dort das dunkle Violett -, damit Textknopf, Zustands-Ebene und Fokus-Ring ohne Sonderklassen tragen. Beim Erscheinen fährt sie kurz von unten ein; bei reduzierter Bewegung blendet sie nur ein.

Bewusste Abweichung: Die Textknöpfe im Dialog bleiben Primary und kommen auf 24dp damit auf 4.31:1 - knapp unter 4.5:1. Materials eigene Baseline tut dasselbe, und die Alternative wäre schlechter: Weisse Knopfschrift wäre von der Fliesstextzeile darüber nicht mehr zu unterscheiden. Die Knöpfe sind gross gesetzt, stehen abgesetzt am Fuss und tragen den Ring; wer sie nicht als Knöpfe liest, verliert nichts, denn der Dialog nennt seine Handlung auch im Text.

Die Snackbar meldet einen Vorgang, die Section Message einen Zustand. Darum hat sie genau einen Platz: unten in der Mitte, für die ganze Anwendung. Niemand rendert sie selbst - gemeldet wird über useSnackbar(), und der Platz im App-Rahmen zeigt immer nur eine. Weitere warten; ihre Zeit läuft erst, wenn sie erscheinen. Jeder Aufruf des Hooks ist eine eigene Stelle: Meldet sie erneut, ersetzt die neue Meldung ihre ältere, und ein Text, der schon ansteht, kommt nicht zweimal in die Reihe. Nach 6 s geht sie von selbst, solange nicht der Zeiger auf ihr liegt oder der Fokus in ihr steht; das X schliesst sie sofort und gibt den Fokus dorthin zurück, woher er kam.

Sie ist tonlos: Ob etwas gescheitert ist, sagt der Text, nicht die Farbe. Die Vorlesehilfe liest sie eingereiht vor, auch einen Fehler, und nur den Text, nicht die Knöpfe - unterbrechen darf nur eine Section Message. Sie gehört zur Ansicht, in der sie entstand, und fällt beim Wechsel weg; wer eine Bestätigung für die Zielansicht braucht, schickt sie über die Adresse mit (Flash). Höchstens eine Aktion - Rückgängig, Erneut versuchen -, nie ein blosses «OK». Und sie liegt unter jedem Dialog: Scheitert ein Vorgang und bleibt der Dialog offen, steht der Grund als Section Message im Dialog.

Ein Link zum Kopieren (Kalender-Abo, AboDialog) ist kein neuer Baustein, sondern eine Zeile aus dem Kit: ein TextField mit readOnly und ein tonaler Button daneben. Das Feld wählt beim Fokus alles aus, damit sich der Link auch von Hand kopieren lässt. Das Ergebnis des Knopfes erscheint im Dialog, nicht in der Snackbar - die liegt unter ihm: Gelingt es, zeigt der Knopf kurz «Kopiert» (mit Häkchen, dazu eine Live-Region für die Vorlesehilfe); scheitert es, steht eine Section Message error im Dialog, und das Feld ist markiert. Ist der Link ein Geheimnis, geht die Warnung als Section Message im Dialog voran.

Übung löschen?

Diese Übung wird dauerhaft entfernt. Das kann nicht rückgängig gemacht werden.

Navigation

Verzeichnis

Lange Seiten zum Nachschlagen tragen ab lg links ein Inhaltsverzeichnis (Verzeichnis in VerzeichnisFlaeche): «Versionen» und diese Seite - das Verzeichnis links ist das Beispiel. Es klebt unter der Kopfzeile, scrollt für sich und führt mit jedem Eintrag zu einem Abschnitt. Der Abschnitt, der oben im Fenster steht, trägt seine Zeile auf 08dp (aria-current="location"); das Verzeichnis scrollt so, dass sie sichtbar bleibt.

  • Obertitel wie die Bereiche bei Material (type-title-small, Pfeil davor): Sie klappen auf und zu. Steht der aktuelle Abschnitt in einem zugeklappten Bereich, trägt dessen Titel den Akzent.
  • Untertitel wie die Gruppen der Komponenten bei Atlassian (type-body-small in on-surface: kleiner als die Einträge, aber heller als ihr ruhiges Mittel - versal waren sie kaum zu unterscheiden): Sie benennen nur, was folgt, und klappen nicht. Auf der Seite stehen sie als Zeile in Primary über dem Abschnitt.
  • Einträge in type-body-medium, ruhig in on-surface-mittel; mit zusatz eine kleine Zeile darüber, bei «Versionen» die Nummer (aktiv in Primary). Ohne Obertitel und Untertitel bleibt das Verzeichnis eine flache Liste - so bei «Versionen».
  • Breite am selben Griff wie die Spalte der geteilten Fläche (Ziehgriff, siehe Layout), zwischen 11 und 30 rem, nie mehr als die halbe Fläche. Gemerkt wird eine Breite für alle solchen Seiten (Cookie kifu-verzeichnis). Schmal fehlt das Verzeichnis.

Die Gliederung dieser Seite steht einmal in GLIEDERUNG: Verzeichnis, Abschnittsköpfe und Verweise im Text (Siehe) lesen dieselbe Quelle. Abschnitte verweisen mit Namen aufeinander, nicht mit Nummern - so bleibt ein Verweis richtig, wenn ein Abschnitt dazukommt.

Layout und Struktur

Liste mit Detail daneben

Die Übungen eines Trainings öffnen ihr Detail in der Spalte daneben, statt auf eine eigene Seite zu führen (Epic #369) - der Trainer behält die Zusammenstellung im Blick. Breit ist darum die ganze Zeile die Fläche, die öffnet, und hellt beim Überfahren auf wie eine Trainingskachel der Übersicht (Übungs- und Trainingskarten): Die Zustands-Ebene (state, Zustände) liegt auf der Zeile, der Knopf dazu ist der Name (UebungsName), dessen Fläche über die Zeile reicht. Was die Zeile sonst trägt - Umsortieren, Entfernen, Dauer, Notiz -, liegt mit relative darüber und bleibt für sich bedienbar. Was man erst nach dem Ansehen tut, steht dagegen im Detail: Bearbeiten und «In meine Bibliothek kopieren» gibt es breit nur dort, schmal weiter an der Zeile.

  • Geöffnet - die Zeile trägt eine Kontur in Primary, der Name ist Primary und aria-current. Ein zweiter Klick schliesst.
  • Schmal - der Name steht als Text, die Zeile öffnet nichts; die Weiche ist CSS, so stimmt schon das erste HTML.
  • Bearbeiten in der Spalte - die Maske steht in der Reihenfolge des Detail untereinander; «Sichern», «Verwerfen» (ohne Änderung «Abbrechen») und Schliessen kleben auf dem Grund (bg-elev-00) am oberen Rand, während die Spalte darunter scrollt. Wer die Übung mit ungesicherten Änderungen verlässt, wird gefragt: weiter bearbeiten oder verwerfen - ein «Sichern und weiter» gibt es nicht.
  1. Autorennen
  2. Berge und Seen

Layout und Struktur

Disclosure

Ein Abschnitt, der zugeklappt beginnt. Gedacht für lange Listen, die vollständig erreichbar bleiben sollen, ohne die Seite zu beherrschen - im Team-Trainingsplan liegt der Rückblick darin, der über die Jahre auf mehrere hundert Einheiten anwächst. Die Anzahl steht am Kopf, damit man weiss, was einen erwartet, bevor man öffnet.

Der Knopf sitzt in der Überschrift, wie es das Disclosure-Muster vorsieht: So springt man mit der Überschriften-Navigation eines Screenreaders auf den Abschnitt und erfährt dort, dass er sich öffnen lässt. Der Inhalt wird nur gerendert, solange er offen ist; die Hülle bleibt stehen, damit aria-controls immer greift. Wie beim Akkordeon im mobilen Drawer bewegt sich nur der Pfeil, nicht die Fläche - das Kit animiert nirgends Höhen.

Mit defaultOpen, wenn der Abschnitt das Einzige ist, was die Seite noch zu zeigen hat.

Text und Daten

Eigenschaften

Bezeichnung und Wert paarweise - die Einordnung einer Übung in der Spalte rechts (Epic #350), angelehnt an das Details-Panel von Jira. Neu, weil kein Baustein Bezeichnung und Wert zusammen führt: FormAbschnitt gliedert Formulare, die Eckdatenzeile der Karte reiht Werte ohne Bezeichnung.

  • Beschreibungsliste - dl mit dt/dd. Die Bezeichnung steht in fester Spalte (8.5 rem), der Wert bricht in seiner um. Ein Wert darf ein Baustein sein: Lozenge, Chips, MaterialListe.
  • Gedämpfte Lesetype statt Versalien - gesperrte Versalien bräuchten für «Hauptteilkategorie» mehr Breite, als neben dem Wert bleibt.
  • Über beide Spalten - EigenschaftBreit für das, was zu einer Zeile gehört, aber keine sichtbare Bezeichnung braucht (der Material-Hinweis). Die Bezeichnung bleibt für Vorlesehilfen.
  • Bearbeitbar - wo eine Angabe in der Liste selbst geändert wird (Ziel und Alterskategorien eines Trainings), sieht die Zeile ruhend aus wie jede andere; nach dem Vorbild von Jira zeigt erst der Wert beim Überfahren und im Fokus, dass er ein Knopf ist (Zustands-Ebene). Ein Klick macht ihn an derselben Stelle zum Feld, die Bezeichnung bleibt links. Fehlt der Wert, steht gedämpft, was zu tun ist («Ziel hinzufügen»). EigenschaftText: Freitext mit ✓ und ✕ darunter - Enter oder ✓ speichert, Esc oder ✕ verwirft, ein Klick daneben speichert. EigenschaftAuswahl: Die Liste geht beim Klick sofort auf, jede Wahl speichert für sich. Nach Esc, ✓, ✕ und Enter steht der Fokus wieder auf dem Wert. Ohne Zeile steht derselbe Baustein frei als InlineWert - als Text oder als Zahl, etwa die Dauer an einer Übung im Training; was nicht gilt, bleibt mit seiner Meldung am Feld stehen.
  • Nicht erfasst - EigenschaftFehlt zeigt eine vorgesehene, aber leere Angabe (nur der Eigentümerin, #352): der Wert gedämpft wie die Bezeichnung, damit er sich vom Erfassten abhebt, ohne nach einem Fehler auszusehen. Nie auf Papier.
  • Fläche - eine Card; auf Papier stehen Bezeichnung und Wert untereinander, weil die Spalte dort schmaler ist.

Eigenschaften

Altersstufe
Kinderfussball
Alterskategorien
Ziel

Einordnung

Altersstufe
Kinderfussball
Alterskategorien
FE
Trainingsteil
Hauptteil
Hauptteilkategorie
Fussball spielen lernen
Erscheinungsform
Nicht erfasst
Anzahl Spieler:innen
9–11
Material
  • 2 Minitore
  • 4 Pylonen, orange

WeiteresPfeife

Hinweis zum Material
Über beide Spalten, die Bezeichnung nur für die Vorlesehilfe.

Text und Daten

Release-Text

Ein Eintrag unter «Versionen» (#408): das Thema des Releases als Titel in type-title-large (ohne «KiFu X.Y.Z -», das die Metazeile schon sagt), darunter eine Metazeile in type-body-small (Version, Tag der Veröffentlichung, «Auf GitHub ansehen»), dann der Text, wie er auf GitHub steht. Er ist Markdown und erscheint mit seiner Gliederung in der Schrift der Anwendung: Überschriften eine Stufe unter dem Titel (type-title-medium), Listen wie im Freitext, Fettes, Links in Primary, Code auf 08dp. Eingebettetes HTML und Bilder fallen weg. Einträge trennt eine Haarlinie. Ab lg steht links das Verzeichnis, flach: je Version Nummer und Thema. Die Texte der neuesten 30 Versionen stehen gleich da, die älteren erst nach «… ältere Versionen anzeigen» (?alle=1); das Verzeichnis nennt alle und führt bei einer älteren dorthin. Das Markdown ist eine Ausnahme: Was Trainer:innen selbst schreiben, bleibt Freitext ohne Markdown.

Neuigkeiten in der Seitenleiste

Version 1.28.0Mi., 07.10.2026Auf GitHub ansehen

Du siehst jetzt, welche Version läuft und was neu ist.

Neu

  • Versionen: Die Seitenleiste zeigt die laufende Version und führt zu allen Versionen. (#408)

Technisch

  • Die Versionen kommen einmal pro halbe Stunde von GitHub.
  • Noch ungeprüft: die Markierung auf einem echten Telefon.

Training und Termine

Übungs- und Trainingskarten

Die Karte ist eine Höhenstufe (bg-elev-01, rounded-flaeche) und trägt keinen Rand: Höhe und Kontur nebeneinander sagten dasselbe zweimal. Das Bild ist das einzige satte Farbfeld auf der Karte; an seinem Kopf liegt ein Verlauf aus scrim (top-0 h-16) - er schützt, was dort steht: die Herkunfts-Lozenge links und den Favoriten-Knopf rechts. Den Titel trägt die Kartenfläche unter dem Bild; er braucht den Verlauf nicht. Darunter stehen die Eckdaten in type-body-medium, getrennt durch «·»: Alterskategorien als Buchstaben (aufsteigend G bis A), die feinste Einordnung, das Feld und die Spieler:innen - genug, um ohne Öffnen zu sehen, ob eine Übung zu Mannschaft und Platz passt. Das Feld ist die Spielfeldgrösse, wo eine erfasst ist, sonst der Feldtyp; die Spielerzahl kürzt «Sp.» ab und wird voll vorgelesen. Was eine Übung nicht trägt, fällt ohne Platzhalter weg. Die Zeile hat höchstens zwei Zeilen (line-clamp-2) und endet sonst in Auslassungspunkten. Die Zeile setzt uebungEckdaten zusammen - im Katalog wie in diesen Beispielen. Überfahren färbt die ganze Karte über state - kein eigener Hover-Ton, und die Ebene sitzt auf dem Link, der die Karte deckt.

Die Trainingskachel (TrainingCard) folgt derselben Regel: Höhenstufe ohne Rand, die Zustands-Ebene auf dem Link, der die ganze Kachel deckt. Ein Bild hat sie nicht; oben stehen die Alterskategorien - nur ohne Kategorie die Altersstufe -, ab zwei Varianten die discovery-Lozenge und am eigenen Eintrag, ob er ein Entwurf oder öffentlich ist. Darunter der Name, die Kennzahlen der ersten Variante (Übungen, Gesamtdauer) und zuunterst Urheber oder Änderungsdatum.

Training und Termine

Methodischer Fahrplan

  1. Offen starten

    Die Kinder dribbeln auf die Abschlusszone zu und schliessen ab.

  2. Üben

    • Mit linkem und rechtem Fuss kontrolliert führen und in die freie Ecke zielen.
  3. Wetteifern

    Wie viele Treffer gelingen mit links, wie viele mit rechts?

Freitext - Freitext: Ablauf, Fahrplan-Stufen und Varianten einer Übung (Story #282). Kein Markdown: Zeilenumbrüche bleiben, wie sie erfasst sind; nur Zeilen mit «- »/«* » werden Aufzählung, Zeilen mit «1. » nummerierte Liste. Dieselben Regeln gelten für die drei Stufen des methodischen Fahrplans. Jede andere Zeile, auch eine Leerzeile, beendet eine Liste.

4 gegen 4 mit je 2 Zielspieler:innen pro Team. Alle bleiben in ihren Zonen.

  • Zeitdruck: Ball muss nach 4 Sekunden die Zone verlassen
  • Nur Direktpässe

Wertung:

  1. Vertikaler Ball ins Ziel: 1 Punkt
  2. Tor nach vertikalem Ball: 3 Punkte

Training und Termine

Feld-Diagramm

Spielfeld-Diagramme (Epic #47) werden als SVG aus der gespeicherten Struktur und dem zentralen Symbol-Register gerendert - DiagrammView ist die eine Anzeige-Komponente für Karte, Detailseite, Trainings, Druck und mobil; UebungsBild schaltet zwischen Diagramm, Foto und Platzhalter. Gezeichnet wird in der Maske der Übung: Die Zeichenfläche (DiagrammZeichnen) sitzt ohne Autosave als DiagrammFeld unter der Zuordnung, beim Erfassen wie beim Bearbeiten. Dort wacht VerlassenWarnung über ungesicherte Angaben - ein Bestätigungs-Dialog aus dem Kit für Links (auch die der Seitenleiste) und Browser-Zurück, die Abfrage des Browsers für Neuladen und Schliessen. Symbol-Geometrie ist im Register verankert (Anker = Mittelpunkt), damit zentrale Symbol-Updates bestehende Diagramme nie verschieben.

Das Diagramm ist Gegenstand, nicht Oberfläche - es folgt weiterhin nicht der Palette der Anwendung. Es hat aber eine eigene, und die kennt mehr als einen Satz: dieselbe gespeicherte Zeichnung erscheint am Bildschirm auf einem Nachtrasen und kommt auf Papier weiss aus dem Drucker. Die Rollen heissen --diagramm-* und stehen bewusst neben dem @theme-Block, ohne --color--Präfix: Tailwind macht aus jeder Farbrolle des Themes eine Utility, und bg-rasen auf einem Knopf wäre genau die Vermischung, die dieser Absatz seit je verhindert. Auf die Tokens der Anwendung gelegt ist nur das Drumherum des Editors: die Leisten (bg-elev-08, shadow-dp-08) und die aktive Werkzeug-Kachel (border-primary). Einen Rahmen um die Zeichenfläche gibt es dort nicht mehr - das Feld zeichnet seine Kante selbst (--diagramm-feldkante), und ein zweiter Strich davor legte nur eine Linie auf die andere.

Zwei Sätze, ein Bestand: Gespeichert wird nur der Farb-Slug, was er zeigt, entscheidet das Medium. Am Bildschirm liegt der Rasen tief im entsättigten Grün des App-Grunds, die Bewegungspfeile werden hell und die Elementfarben sind angehoben - die Manual-Palette kam auf dem dunklen Grund bei Rot auf 2.6:1 und bei Blau auf 2.2:1, zwei Mannschaften, die sich nicht mehr unterscheiden liessen. Auf Papier kehrt sich fast alles um: weisse Fläche mit 6-%-Raster, schwarze Pfeile wie in der Zeichenerklärung des Manuals, und alles, was am Bildschirm hell gezeichnet ist, kippt ins Graue, weil Weiss auf Papier nicht existiert. Einzige Ausnahme ist der Ball - er bleibt weiss und bekommt eine kräftigere Kontur, sonst wäre er ein grauer Fleck unter lauter grauen Flecken. Die Werte stehen in app/globals.css, die Rollennamen in lib/diagramm-farben.ts; npm run check:diagramm-farben rechnet beide Sätze nach (3:1 nach WCAG 1.4.11 - auf dem Rasen steht kein Text) und verbietet im Zeichencode jeden rohen Farbwert.

Spieler und Torwart sind Cartoon-Kinder, der Trainer eine erwachsene Figur (Kappe, lange Ärmel, lange Hose, rund 38 % grösser - so zeichnet ihn das Manual): das Trikot trägt die Team-Farbe (ein konfigurierbarer Fill), Frisur und Hautton werden pro Element deterministisch variiert. Der Spieler hat eine wählbare Pose, beide Figuren statt Rotation eine Blickrichtung (links/rechts, Spiegeln). Die beiden -hinten-Posen zeigen dieselbe Haltung von hinten - damit lässt sich ein Kind darstellen, das vom Betrachter weg (im Diagramm „nach oben") schaut, etwa eine wartende Kolonne. Nur die Frontal-Posen haben diese Variante; die übrigen zeigen die Figur ohnehin im Profil. Torwart und Trainer haben je eine feste Standfigur ohne Pose. Alle Posen als GlyphVorschau:

stehen
stehen-hinten
laufen
laufen-hinten
dribbeln
passen
schiessen
graetschen
torwart
trainer

Das Minitor ist perspektivisch: statt sich flach zu drehen, zeigt es je Orientierung eine eigene 2.5D-Ansicht im Manual-Look (Front, Dreiviertel, Seite, Rück). Der äussere rotate() entfällt - das Symbol bekommt den Winkel über opts.rotation und wählt das passende Sprite (Spiegelung für 225°/270°/315°). Die acht Schritte als GlyphVorschau:

0°
45°
90°
135°
180°
225°
270°
315°

Element-Optionen (Drehen, Farbe, Linienstil, Kopieren, Entfernen) erscheinen auf der Zeichenfläche als kontextuelle Bedienleiste, die am ausgewählten Element schwebt - ein bewusst neues Muster (#65): Das Kit kennt nur an DOM-Trigger verankerte Overlays (Menu, Select), aber kein Panel an einer Position innerhalb einer Canvas. Die Leiste liegt als absolutes Overlay über der Fläche (08dp, shadow-dp-08), nicht im Dokumentfluss - so verschiebt das Ein- und Ausblenden die Fläche nie. Sie weicht oberhalb/unterhalb des Elements aus, tritt während eines Drags zurück und verschwindet beim Abwählen. Textboxen werden per Doppelklick direkt am Element bearbeitet.

Mehrere Elemente werden per Auswahlrahmen (Aufziehen auf der freien Fläche, erfasst vollständig umschlossene Elemente) oder additivem Umschalt-/Cmd-Klick ausgewählt (#67). Bei mehr als einem Element tritt an die Stelle der Eigenschaften-Leiste eine schlanke Mehrfach-Leiste (Anzahl, Kopieren, Löschen), verankert an der gemeinsamen Box; verschoben wird die Gruppe per Drag. Das Ziehen meldet die Zeichnung selbst - ein gezogenes Element ist SVG und hat kein ::after, auf das sich eine Zustands-Ebene legen liesse. Darum kennt das Kit drei Zustände und nicht Materials vier (siehe Zustände).

Abschlusszone

Die Werkzeug-Palette des Editors zeigt jedes Element als GlyphVorschau - dieselbe ElementGrafik wie auf dem Feld, in eine Kachel auf dem Feldgrün eingepasst (WYSIWYG; weisse Glyphen brauchen den grünen Grund). Die Kacheln sind gruppenweise aneinandergereiht, der Name kommt nur über Tooltip und aria-label (kein sichtbarer Text). Wiederverwendbar auch für die Diagramm-Bibliothek.

Das Überziehleibchen ist ein färbbares, drehbares Symbol: ein zusammengelegtes Tuch mit gerader Oberkante und Wellensaum. In den Manual-Vorlagen wird es in der Hand gehalten („Trikottausch", „Spiel mit dem Feuer") - es lässt sich aber ebenso am Boden oder als Stapel platzieren. Die unruhige Silhouette grenzt es bewusst vom Markierungsteller ab (Ellipse mit Loch), der in dieser Grösse sonst kaum zu unterscheiden wäre:

Gezeichnet wird in der Maske der Übung, beim Erfassen wie beim Bearbeiten, in der Bibliothek wie im Training: DiagrammFeld zeigt im Abschnitt «Feld-Diagramm» die Zeichenfläche (DiagrammZeichnen), und die Zeichnung geht mit dem Speichern der Übung mit. Eine eigene Editor-Seite gibt es nicht. Unter sm steht an ihrer Stelle die bisherige Zeichnung mit dem Hinweis, dass Zeichnen mehr Platz braucht.

Training und Termine

Material

Das Material einer Übung (Epic „Material aus dem Feld-Diagramm") steht zweigeteilt: oben die gezählte Liste aus dem Diagramm-Vorrat nach Art, Farbe und Menge, darunter die freie Ergänzung für alles, was das Diagramm nicht kennt. Die Gliederung ist fachlich: nur die Liste wird in der Gesamtliste eines Trainings verrechnet.

  • Erfassen - kein Repeat-Baustein im Kit, darum ein eigenes Feld aus bestehenden Teilen: je Zeile Select für Art und (nur bei färbbarem Material) Farbe, TextField für die Menge, IconButton mit X zum Entfernen (PO 2026-10-06). Hinzufügen ist HinzufuegenFeld (siehe Textfelder, Text-Area, Datum & Zeit) mit dem fachlichen Hinweis, was in die Liste gehört und was unter «Weiteres Material».
  • Vorschlag - das Angebot des Diagramms steht als SectionMessage über der Liste: es verlangt eine Antwort (übernehmen, bei einer Änderung auch beibehalten), siehe Leerzustand, Hinweiszeile & Section Message.
  • Lesen - MaterialListe: ein Posten pro Zeile, die Ergänzung als «Weiteres» abgesetzt. Präsentational, auf Übungsseite, im Training und im Druck derselbe.

Material (optional)

Was die Übung braucht, nach Art, Farbe und Menge - so zählt es in die Materialliste des Trainings. Was sich so nicht erfassen lässt, gehört unter «Weiteres Material».
Was das Feld-Diagramm nicht erkennt, eines pro Zeile.

MaterialListe

  • 2 Minitore
  • 4 Pylonen, orange
  • 6 Überziehleibchen, rot
  • 6 Überziehleibchen, blau

WeiteresPfeife, Stoppuhr

Training und Termine

Kalenderblatt

Ein Termin wie ein Blatt vom Abreisskalender: Wochentag, grosse Tageszahl, Monat - nie das Jahr, das steht in der Überschrift des Monats (Epic #401). Neu, weil ein Datum als Text in einer Zeile (datumKurz) sich beim Überfliegen nicht finden lässt. Im Trainingsplan steht es links an jeder Terminzeile. Eine leise Tönung sagt, was der Termin trägt (zustand): Training in Primary, noch kein Training in der Warnfarbe - je eine schwache Fläche (12 %) mit der Tageszahl in der Farbe selbst -, ausgefallen grau mit durchgestrichener Zahl, vergangen ohne Training ohne Fläche. Die Farbe trägt den Zustand nie allein, die Zeile daneben sagt ihn in Worten. Heute hebt das Blatt nicht hervor; dafür steht der nächste Termin zuoberst. Wo kein Blatt steht (der nächste Termin), sagt eine Lozenge in derselben Tönung den Zustand: BlattLozenge - Form der Lozenge, Farbe des Blatts.

Dienstag, 6. Oktober 2026
Donnerstag, 8. Oktober 2026
Sonntag, 11. Oktober 2026
Mittwoch, 30. September 2026
Noch kein Training

Training und Termine

Mini-Monat

Ein kleiner Monat zum Navigieren neben einer Liste (Epic #401). Neu, weil kein Baustein ein Kalenderraster kennt. MiniMonat legt um jeden Tag mit Einträgen einen gepunkteten Ring und setzt die Einträge als kleine Badges oben rechts darauf - wie der Punkt an einem Zeichen für Neuigkeiten. Die Zellen sind alle gleich hoch, und jeder Monat zeigt sechs Wochen: Beim Blättern springt die Höhe nicht (wie im Google und Proton Kalender). Ein Tag mit Einträgen ist ein Knopf zu seinem ersten Eintrag (onWahl), ein leerer Tag ist keiner. Blättern und «Heute» melden nur den Monat (onMonat): Wie im Google Kalender folgt der Monat der Liste, die Liste aber nicht ihm.

  • Zustand als Zeichen - Punkt in Primary (Training), Punkt in der Warnfarbe (noch kein Training), rotes Kreuz (ausgefallen); vergangen ohne Training zeigt nur den Ring. Die beiden Punkte unterscheidet bewusst nur die Farbe, damit das Gelb auffällt. Eine Legende gibt es nicht: Die Liste daneben trägt dieselben Farben, und vorgelesen wird jeder Zustand beim Namen.
  • Mehr als zwei - zwei Badges oben rechts, das zweite halb hinter dem ersten, und «+n» unten rechts am Ring; die übrigen stehen in der Liste.
  • Zielgrösse - geklickt wird der ganze Tag (36 px hoch), nicht das einzelne Badge, das dafür zu klein wäre (WCAG 2.5.8).
  • Belegt - der Ring ohne Badge: Dort liegt etwas, das der Monat nicht zeigt (bei «Meine Termine» die Termine anderer), oder nur Vergangenes ohne Training. Heute trägt die Zahl auf Primary, ohne Ring.

Oktober 2026

Nur deine Termine

Montag
Dienstag
Mittwoch
Donnerstag
Freitag
Samstag
Sonntag
28. September 2026
30. September 2026
2. Oktober 2026
3. Oktober 2026
4. Oktober 2026
5. Oktober 2026
7. Oktober 2026
9. Oktober 2026
10. Oktober 2026
12. Oktober 2026
13. Oktober 2026
14. Oktober 2026
16. Oktober 2026
17. Oktober 2026
18. Oktober 2026
19. Oktober 2026
20. Oktober 2026
21. Oktober 2026, belegt
23. Oktober 2026
24. Oktober 2026
25. Oktober 2026
26. Oktober 2026
27. Oktober 2026
28. Oktober 2026
29. Oktober 2026
30. Oktober 2026
31. Oktober 2026
1. November 2026
2. November 2026
3. November 2026
4. November 2026
5. November 2026
6. November 2026
7. November 2026
8. November 2026

Gewählt: -

Training und Termine

Platz und Spielerzahl eines Termins

Der Platz eines Termins (Epic #388): ein oder mehrere getrennte Felder, je mit Länge und Breite der verfügbaren Fläche, den Toren je Torart und dem Untergrund. FelderField ist neu, weil das Kit keinen Repeat-Baustein kennt - gebaut nach dem Muster des Material-Felds (Material) aus bestehenden Teilen.

  • Ein Block je Feld - umrandet (border-linie), mit «Feld 1», «Feld 2» und dem IconButton mit X zum Entfernen (PO 2026-10-06, kein Papierkorb). Die Felder sind getrennte Flächen; der Block macht das sichtbar, wo eine Zeile wie beim Material sie zu einem Posten verkürzte. Hinzufügen ist HinzufuegenFeld (siehe Textfelder, Text-Area, Datum & Zeit), sein ⓘ sagt, was ein Feld ist. Jeder Block ist eine Gruppe (role="group"), benannt nach seinem Titel.
  • Alles untereinander - Länge über Breite, die drei Torarten untereinander, jedes Feld mit eigenem Namen (wie die Spielfeldgrösse einer Übung, siehe Formularfelder). Kein Nebeneinander: Auf dem Handy bräche es ohnehin um, und so liest sich jede Angabe gleich.
  • Leer heisst unbekannt, 0 heisst keine - steht als Hinweis hinter dem ⓘ jedes Felds - bei Länge und Breite «leer heisst unbekannt», bei jeder Torart dazu «0 heisst keine» -, weil der Unterschied für den KI-Assistenten zählt. Der Hinweis der Torarten steht auf Touch-Geräten auch unter dem Feld (infoAufTouch). Länge und Breite sind ein Paar: Ein Fehler färbt beide, der Satz steht unter der Breite (wie die Spielfeldgrösse einer Übung).
  • Untergrund mit «Unbekannt» - anders als sonst bei einem optionalen Select eine eigene Wahl: Unbekannt ist hier eine Aussage, und nur so lässt sich ein gewählter Untergrund wieder zurücknehmen.
  • Lesen - im Trainingsplan knapp in einer Zeile mit dem Zeichen LandPlot (ein Feld: Grösse und Untergrund, mehrere: ihre Zahl), in der Durchführen-Ansicht je Feld ausführlich, Unbekanntes als «unbekannt», damit es nicht wie «keine» aussieht. Die Torart steht vor der Zahl («Minitore: 4, 5-m-Tore: keine») - «2 5-m-Tore» läse sich wie «25 m».
  • Erwartete Spielerzahl (#390) - ein gewöhnliches Zahlenfeld (SpielerzahlField = TextField), dessen Hinweis hinter dem ⓘ sagt, was die Zahl zählt (auf Touch-Geräten auch unter dem Feld, infoAufTouch); sonst steht unter dem Feld nur ein Fehler. Es heisst «Erwartete Spielerzahl» wie in der Auskunft des Assistenten. Im Trainingsplan steht sie in derselben Zeile wie die Felder, mit dem Zeichen Shirt - Users trägt schon die Verantwortlichen.

Beide Bausteine bündelt usePlatzAngaben für die Termin-Dialoge: Zustand, Zurücksetzen beim Öffnen und die Prüfung mit den Regeln des Fachkerns.

Alle erwarteten Kinder einschliesslich Torhüter:innen, ohne Trainer:innen.
  • Feld 1

    Länge der Fläche, die euch zur Verfügung steht, in ganzen Metern. Leer heisst unbekannt.
    Breite der Fläche, die euch zur Verfügung steht, in ganzen Metern. Leer heisst unbekannt.
    Wie viele Minitore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
    Wie viele 5-m-Tore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
    Wie viele 7-m-Tore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
  • Feld 2

    Länge der Fläche, die euch zur Verfügung steht, in ganzen Metern. Leer heisst unbekannt.
    Breite der Fläche, die euch zur Verfügung steht, in ganzen Metern. Leer heisst unbekannt.
    Wie viele Minitore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
    Wie viele 5-m-Tore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
    Wie viele 7-m-Tore auf diesem Feld stehen. Leer heisst unbekannt, 0 heisst keine.
Ein Feld ist eine eigene Fläche, die euch zur Verfügung steht - auf einem geteilten Platz nur euer Teil. Mehrere Felder nutzt ihr gleichzeitig; sie lassen sich nicht zu einer grösseren Fläche zusammenlegen.

Trainingsplan

2 Felder · 12 Spieler:innen

Durchführen

  • 30 × 25 m · Minitore: 2, 5-m-Tore: keine · Kunstrasen
  • Grösse unbekannt · Tore unbekannt · Halle