# Shape

> Five radius steps, lines that carry meaning, and depth without shadows – from a veil, an outline and a tilt. Plus sticky notes, playful shapes and the anatomy of a card.

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

Hey Albert’s shapes are soft and flat. Everything is paper on paper. Nothing shines, nothing casts a shadow.

## Radii

Five radii, each with a job. Without a token there is no radius.

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| radius-karte | var(--radius-karte) | 16px |  | Karten und Menüs |
| radius-klein | var(--radius-klein) | 12px |  | Tagesreiter, kleine Karten |
| radius-leiste | var(--radius-leiste) | 24px |  | iPhone-Leiste |
| radius-block | var(--radius-block) | 22px |  | Mac-Block |
| radius-pille | var(--radius-pille) | 999px |  | Pillen, Kreise, Knöpfe |

- `--radius-karte` for cards, menus, dialogs.
- `--radius-klein` for day tabs and small cards.
- `--radius-leiste` for the iPhone tab bar, `--radius-block` for the black block of the Mac sidebar.
- `--radius-pille` for pills, circles and every button. Our buttons are always round.

## Lines mean something

A line is never decoration here. The kind of outline says what state a thing is in.

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| strich-haar | var(--strich-haar) | 1px |  |  |
| strich-stark | var(--strich-stark) | 1.5px |  | Kontur wird stark, statt Schatten |
| strich-gestrichelt | var(--strich-gestrichelt) | 1.5px |  |  |
| muster-gestrichelt | var(--muster-gestrichelt) | 5px 4px |  |  |
| kippung-zettel | var(--kippung-zettel) | 0.3deg |  | was liegt, ist leicht gekippt |
| kippung-null | var(--kippung-null) | 0deg |  | was schwebt, steht gerade |
| schatten | var(--schatten) | none |  | nicht verhandelbar |
| fokus-ring | var(--fokus-ring) | 2px |  |  |
| fokus-abstand | var(--fokus-abstand) | 2px |  |  |

| Outline | Means | Tokens |
|---|---|---|
| solid hairline | calm field, everything settled | `--strich-haar`, `--linie-haar` |
| solid, stronger outline | the pointer is on it | `--strich-stark`, `--linie-stark` |
| dashed grey | suggestion from Albert, not yet accepted | `--strich-gestrichelt`, `--muster-gestrichelt`, `--rand-vorschlag` |
| dashed open-pink | no one responsible | `--rand-offen` |
| thin dashed | area chip in the surface header | `--strich-haar` |
| ring with offset | keyboard focus | `--fokus-ring`, `--fokus-abstand`, `--rand-fokus` |

Hairlines are always `--strich-haar`. The dash pattern is the same everywhere: `--muster-gestrichelt`.

## No shadows

There are no shadows. Not under cards, not under menus, not under buttons. The token `--schatten` is `none` and not negotiable.

Depth comes from three means:

1. **The veil.** `--flaeche-schleier` dims what lies behind a dialog, a menu or the scanner.
2. **The outline.** What the pointer touches gets a stronger line: `--strich-haar` becomes `--strich-stark`. The surface stays the same.
3. **The tilt.** What lies is tilted slightly (`--kippung-zettel`). What floats stands straight (`--kippung-null`). Sticky notes lie, menus float.

> **Don't**
>
> `box-shadow`, `drop-shadow`, Tailwind classes like `shadow-md`, frosted glass, blur under cards, translucent cards, gradients as depth.

## Sticky notes

Every person has their note in their person colour. Avatars, per-person lanes and the notes on the Today surface (*Heute*) are sticky notes.

- Surface `--person-1` to `--person-8`, text `--person-text`.
- Tilted slightly, alternating left and right: `--kippung-zettel`.
- Always with an initial or a name. Colour alone is never enough.

## Playful shapes

Star, heart, blob, circle and puzzle piece (component `DekoForm`) bring joy to a surface. They are not decoration for everything.

- Only on yellow and pink surfaces.
- Always in the darker step of the same colour: `--gelb-dunkel` on yellow.
- Cropped at the edge of the surface, never in the middle of text.
- Never on cards with controls, never in the safe, never in finances, never in the clerk register (*Sachbearbeiter*).

### DekoForm

Source: `packages/design-system/components/bausteine/DekoForm.jsx`

Die spielerische Form auf einer gelben oder rosa Fläche – Freude, kein Schmuck.

```jsx
<DekoForm form="stern" groesse={110} farbe="var(--gelb-dunkel)" style={{ right: -18, bottom: -22 }} />
```

Die Elternfläche braucht `position: relative` und `overflow: hidden`. Nie auf Karten mit Bedienelementen, nie im Safe, nie bei Finanzen.

```ts
/** Spielerische Form als Deko auf gelben und rosa Flaechen - Stern, Herz, Kleks, Puzzleteil. */
export interface DekoFormProps {
  form?: "stern" | "herz" | "kleks" | "kreis" | "puzzle";
  groesse?: number;
  /** Immer die dunklere Stufe derselben Flaechenfarbe: var(--gelb-dunkel), var(--blau-dunkel). */
  farbe?: string;
  drehung?: number;
  style?: React.CSSProperties;
}
export function DekoForm(props: DekoFormProps): JSX.Element;
```

## The anatomy of a card

The card is what Today, Week and the calendar are made of. It always has the same structure.

- **Surface** by kind: appointment `--flaeche-karte`, drive `--flaeche-karte-fahrt`, family `--flaeche-karte-familie`, suggestion `--flaeche-karte-vorschlag` with a dashed grey outline, open with a dashed open-pink outline.
- **Radius** `--radius-karte`, **padding** `--karte-innen`, **gap** to the next card `--karte-abstand`.
- **Outline:** a hairline as a placeholder for the stronger outline. No shadow.
- **Header:** on the left the symbol of the thing in a light circle, on the right the dots of the people. Nothing in between: no menu, no chevron.
- **Title** in `--grad-karten-titel`, below it time and place in `--grad-zweit`.
- **Pills** for states, for example “Kein Fahrer” (no driver).
- **Buttons** at the bottom, in a `Knopfreihe`. A suggestion always has two: “Übernehmen” (accept) and “Rückgängig” (undo), or a question with two answers.

Three carriers in three places: the card colour tells the kind. The symbol tells the thing. The dots tell the people.

### Karte

Source: `packages/design-system/components/karten/Karte.jsx`

Die Karte – das Ding, aus dem Heute, Woche und Kalender bestehen. Ein Datenmodell, viele Ansichten.

```jsx
<Karte art="fahrt" titel="Rückfahrt Auswärtsspiel" ort="Sportplatz Nord → Zuhause"
  zeit="14:00 – 14:30" leute={["felix"]} hoehe="hoch"
  pillen={<ZustandsPille>Kein Fahrer</ZustandsPille>}
  knoepfe={<Knopf>Ich fahre</Knopf>} />

<Karte art="vorschlag" titel="Bei Tobias steht ab 13:00 nichts. Fragen?"
  unterzeile="Vorschlag von Albert"
  knoepfe={<KarteVorschlagKnoepfe onUebernehmen={…} onZurueck={…} />} />
```

Register Family Manager, kurz und ruhig. Die Bedeutungen werden nicht getauscht: blau ist Fahrt, gelb ist Familie, gestrichelt rosa heisst "ohne Zuständigen". Ein Vorschlag hat immer zwei Knöpfe – Albert erledigt nie still.

```ts
/**
 * Die Karte in fuenf Arten. Die Farbe sagt die Art, das Symbol die Sache, die Punkte die Leute.
 */
export interface KarteProps {
  /** "termin" beige | "fahrt" blau | "familie" gelb | "vorschlag" gestrichelt grau | "offen" gestrichelt rosa. */
  art?: "termin" | "fahrt" | "familie" | "vorschlag" | "offen";
  /** Kartentitel, ein Gegenstand: "Rückfahrt Auswärtsspiel". */
  titel: string;
  /** Zweitzeile: Ort oder Bündel-Teile, mit " · " getrennt. */
  ort?: React.ReactNode;
  /** Zeitspanne als "16:00 – 17:00" (Halbgeviertstrich mit Leerzeichen). */
  zeit?: string;
  /** Wer dabei ist; der Zustaendige zuerst. */
  leute?: string[];
  /** Sach-Symbol, wenn es nicht aus der Art folgt: "schule", "sport", "arzt", "musik". */
  symbol?: string;
  /** "kurz" (78 px) oder "hoch" (132 px) - fuer das Stundenraster. */
  hoehe?: "kurz" | "hoch";
  /** Zustands- und Fahrt-Pillen. */
  pillen?: React.ReactNode;
  /** Handlungsknoepfe; bei Vorschlaegen immer zwei. */
  knoepfe?: React.ReactNode;
  /** Kleine Zeile unter dem Inhalt, z. B. "Vorschlag von Albert". */
  unterzeile?: React.ReactNode;
  /** Einzeiler fuer Listen: Symbol, Titel, Zeit, Punkt. */
  kompakt?: boolean;
  klickbar?: boolean;
  /** Leicht gekippt, wie ein liegender Klebezettel. */
  gekippt?: boolean;
  children?: React.ReactNode;
  style?: React.CSSProperties;
}
export function Karte(props: KarteProps): JSX.Element;
export function KarteVorschlagKnoepfe(props: { uebernehmen?: string; zurueck?: string; onUebernehmen?: () => void; onZurueck?: () => void }): JSX.Element;
```

## In short

> **Do**
>
> - Radius from the five tokens.
> - Show state through the kind of outline.
> - Depth through veil, outline and tilt.

> **Don't**
>
> - Shadows of any kind.
> - Free radii like `rounded-[10px]`.
> - Playful shapes on cards with buttons.
> - Square buttons.
