# Accessibility

> Hey Albert is built for a whole family, from nine-year-old Lena to Oma Grete. Contrast, target sizes, focus, screen readers, text sizes, motion and plain language belong to every view, not to the end.

Source: https://brand.heyalbert.family/en/zugaenglichkeit/ · Hey Albert brand and design system

A family is the most varied group you can design for. Lena is nine and reads slowly. Oma Grete sees less well and taps less precisely. Tobias drives the Mac by keyboard. Everyone uses the same app.

So accessibility is not a check at the end. It lives in the tokens.

## The test question

> Could a nine-year-old use this alone?

This question applies to every view. Children take part; they are not an audience (principle 5). If Lena cannot find, hit or understand her checkmark, the view is not done.

## Contrast

- Body text and controls: at least **4.5:1**.
- Surfaces, outlines, dashed borders, focus ring: at least **3:1**.
- Both modes are computed, not estimated.

| Foreground | Background | Light | Verdict | Dark | Verdict |
| --- | --- | --- | --- | --- | --- |
| tinte | grund | 15.62:1 | AAA | 16.43:1 | AAA |
| tinte | karte | 14.27:1 | AAA | 13.13:1 | AAA |
| grau | grund | 4.83:1 | AA | 7.44:1 | AAA |
| grau | karte | 4.41:1 | 3:1 | 5.94:1 | AA |
| text-inaktiv | grund | 2.47:1 | zu schwach | 4.06:1 | 3:1 |
| text-auf-gelb | gelb | 6.85:1 | AA | 6.85:1 | AA |
| text-auf-blau | blau | 10.94:1 | AAA | 10.94:1 | AAA |
| text-auf-rosa | rosa | 10.55:1 | AAA | 10.55:1 | AAA |
| text-auf-leiste | schwarz | 15.65:1 | AAA | 17.28:1 | AAA |
| knopf-primaer-text | knopf-primaer-flaeche | 15.65:1 | AAA | 15.65:1 | AAA |
| rand-offen | grund | 4.47:1 | 3:1 | 9.21:1 | AAA |
| rand-vorschlag | grund | 4.83:1 | AA | 7.44:1 | AAA |
| rand-fokus | grund | 4.47:1 | 3:1 | 9.21:1 | AAA |

Where a row falls below the limit, that is an open defect, not an exception. The state of grey and disabled is described in the [Colour](/en/farbe/#contrast) chapter.

## Colour is never alone

No information depends on colour alone.

- A person colour always with an initial or a name.
- The kind of card always also through the symbol of the thing.
- “No one responsible” is a dashed outline **and** a pill with text, such as “Kein Fahrer” (no driver).
- A suggestion is dashed **and** carries the line “Vorschlag von Albert” (suggestion from Albert).

That way Hey Albert works for people with colour vision deficiency and in greyscale.

## Target sizes

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| ziel-zeiger | var(--ziel-zeiger) | 28px |  |  |
| ziel-finger | var(--ziel-finger) | 44px |  |  |
| ziel-kind | var(--ziel-kind) | 56px |  |  |

Whatever children operate is at least 56. That applies in the children’s area, when ticking off and with the coins (*Taler*). An icon alone is never the target; the whole row or the whole button is.

## Focus and keyboard

- Focus is always visible, but only through `:focus-visible`: a ring in `--rand-fokus`, `--fokus-ring` wide, with `--fokus-abstand`.
- Whoever taps with mouse or finger sees no ring.
- On the Mac everything works by keyboard, including drag and drop: a card can be moved into another lane without a mouse.
- The order follows reading: header, filters, content, sidebar.

## Screen readers

- Icons next to text are decorative and invisible to VoiceOver (`aria-hidden`).
- Icons on their own, such as the three circles in the header (bell, messages, plus), need a label.
- A card should read out as a whole: kind, title, time, place, people, state. For example: “Fahrt. Rückfahrt Auswärtsspiel, 14:00 bis 14:30. Felix. Kein Fahrer.”
- Buttons say what happens: “Ich fahre” (I’ll drive), not “OK”.
- Images that say something have alt text; decorative ones get `alt=""`.

## Text sizes

- In the app every size follows Dynamic Type. That is part of the definition of done: whoever has set larger text gets it everywhere.
- Cards grow in height. Buttons never wrap to two lines: if space runs out, the `Knopfreihe` stacks them.
- On the website, zoom up to 200 % must work without horizontal scrolling.

> **Open**
>
> How the fixed sizes from the tokens map onto the Dynamic Type steps is not documented. The app is not yet in the monorepo (`apps/apple`). The table belongs here once it has moved.

## Motion

With reduced motion every duration is zero and the skeleton does not breathe. Nothing blinks, nothing runs on its own. More in the [Motion](/en/bewegung/) chapter.

## Plain language

Text is part of accessibility.

- One thought per sentence. Short words, verbs instead of nouns.
- Errors and empty states say three things: what belongs here, why it is empty, what you can do – with one button.
- Children read in the reader register (*Vorleser*), in three stages: small (6–9), middle (10–12), large (13+). The limits per register are in the [Voice](/en/stimme/) chapter.

| Register | Where | Hallmark | Words per sentence avg / max |
| --- | --- | --- | --- |
| R1 · Der Erzähler | Website, landing pages, onboarding, manifesto, module names, release notes | Maxims, contrast pairs, concrete pictures from family life | 9 / 18 |
| R2 · Der Family Manager | The everyday interface for adults: buttons, labels, hints, briefings | Brief and action-oriented | 8 / 12 |
| R3 · Der Vorleser | All children’s views, in three stages: small 6–9, middle 10–12, large 13+ | Short, vivid, in the present tense | 6 / 10 |
| R4 · Der Sachbearbeiter | Safe, contracts, deadlines, finances, taxes, privacy, legal texts | Precise, sober, complete | 10 / 14 |
| R5 · Der Briefeschreiber | Replies Albert drafts to school, club, insurer, tradespeople, authorities | Not Albert’s voice but the family’s | 12 / 18 |

Watch and notifications: seven words at most, the most important first. Example: „16:40 · Handball, Halle Süd.“

## A view is done only with

- [ ] empty state
- [ ] skeleton instead of spinner
- [ ] keyboard and :focus-visible
- [ ] phone and desktop
- [ ] light and dark as a token switch
- [ ] optimistic update with „Undo“
- [ ] correct register
- [ ] no hex value
- [ ] target sizes 28/44/56

The `design-pruefer` agent checks views against this list. The brand QA (`pnpm qa` in the design system) finds hex values, shadows, forbidden words, exclamation marks and images without alt text.
