Skip to content
Hey AlbertBrand and design system
As MarkdownDeutschDE

Screens

Screens

How a Hey Albert screen is built – on iPhone, iPad, Mac, Watch and in the browser. Devices, places, roles, density, grid, header and cards, with every screen of the Sonntag family.

Hey Albert has one data model and many views. An event is a card in the hour grid on the Mac, a row in the list on the iPhone and a question with two answers on the watch. It is always the same row in the database. This chapter covers what applies to every device. The chapters iPhone, iPad, Mac and Watch show the layout region by region, in points.

One data model, many views

Principle 2 is the foundation of every screen. Week, Today and calendar render the same things. A view may filter, group and condense. It may never hold data of its own.

Devices and their role

DeviceRoleWhat belongs there
Macthe planning machineplanning the week, safe, finances, Sunday round, managing the household
iPhonethe everyday deviceon the way, in the shop, in the car, in the hallway – one-handed
iPadfamily and children’s devicein the kitchen, at the table, in the children’s room
Apple Watchthe five-second deviceleaving, arrived, ticked off, voted
Browserthe web appplanning and paperwork on any computer, the same layout as the Mac

The rule behind it is in docs/11-produkt.md §10: what is planned belongs on the Mac. What happens together belongs on the iPad. What happens on the way belongs on the iPhone. What takes one second belongs on the watch.

Places in the app

The app has three kinds of places. Albert himself is not a place. He works in all of them.

  • Surfaces (Flächen): Today (Heute), Week (Woche), Inbox (Eingang). They show things from every area.
  • Areas (Bereiche): Food (Essen), Tasks (Aufgaben), School (Schule), Joy (Freude), Important (Wichtiges). Each shows one kind of thing in full depth.
  • Personal (Persönlich): Me (Ich) and Household (Haushalt). Profile, your own things, people and rights.

The groups are not destinations. Nobody clicks on “Areas”; you click on “Food”.

DeviceNavigationComponent
Mac and browserblack sidebar on the left, 220 pt, collapsed 72 ptLeisteMac
iPad landscapesidebar on the left as on the Mac (proposal)LeisteMac
iPad portraitsidebar collapsed (proposal)LeisteMac
iPhoneblack bar at the bottom, five places, the plus sticks outLeistePhone
Watchnone, one question per screen–
Child space, wall modeno bar, a dedicated entry point–

On the iPhone the bar has five places: Today · Week · Plus · Inbox · Me. On the Mac every place sits in three groups.

Roles get different entry points

Hey Albert is not an app with permissions that greys out what someone may not do. From the same data model, every role gets its own entry point. What someone may see is decided by the database, never by a hidden button.

RoleWhoFirst page
owner, adultAnna, TobiasMac: the whole week · iPhone: Today by urgency · iPad: portal
child · small (6–9)LenaiPad: her space, three picture tiles, 56 pt targets · iPhone: only “what’s now”
child · mid (10–12)FelixiPad: day path, two buttons · iPhone: school folder, take-along list, ask for a ride
child · teen (13+)–almost the adult view, without safe, vault and finances
guestOma Grete, Opa Werner, Oma HildeiPhone: three things – events they are invited to, album, “I’ll drive”
serviceSofiaiPhone: her list – shifts, her drives, shopping; every grant with an expiry date

Safe, vault and finances only open via albert.may_enter(). Children never see them, not even greyed out.

Density: five seconds

The first page holds as much as this role can take in on this device in five seconds. For Oma Grete that is three things. For Lena four. For Anna at the Mac it may be the whole week; she has sat down. Whoever needs more goes one level deeper.

Three questions come before every screen:

  1. Who is this page for? “For everyone” means for no one.
  2. How many things are on it, and how many seconds does this role have?
  3. Am I hiding things, or building a dedicated entry point? Greying out is always the worse answer.

Grid, margins, safe areas

Everything sits on the 8 pt grid with 4 pt as a half step. The surface margin is --flaeche-rand-mac on the Mac and --flaeche-rand-phone on the iPhone. Cards have --karte-innen inside and --karte-abstand between them.

--raum-halb4px
--raum-18px
--raum-216px
--raum-324px
--raum-432px
--raum-540px
--raum-648px
--raum-864px
--karte-innen12px
--karte-abstand8px
--flaeche-rand-mac32px
--flaeche-rand-phone20px

Everything sits on the 8 px grid, with 4 px as a half step.

Safe areas belong to the system: status bar, Dynamic Island, home indicator. We draw nothing there and never imitate a status bar. Controls never sit below the iPhone bar.

Target sizes are minimums, not guidelines: pointer 28, finger 44, child 56.

28px
Pointer · Mac--ziel-zeiger
44px
Finger · iPhone, iPad--ziel-finger
56px
Child · everything children use--ziel-kind

The header of a surface

Every surface starts the same way. First the header, then the greeting, then the row with date and filters, then the content.

  • Header (Mac, iPad): search pill with pink magnifier, dashed area chips, three circles on the right in fixed order – bell, messages, pink plus. The iPhone has no header; the plus sits in the bar.
  • Greeting: “Guten Morgen, Anna.” in Bricolage 800. On Today it greets; on every other surface it names: “Woche 36”, “Aufgaben”, “Einkauf”. Below it a subline with the date and what counts: “zwei Sachen offen, ein Vorschlag” (two things open, one suggestion).
  • Row: date pill, person filter, span control.

Kopfzeile

components/kopf/Kopfzeile.jsx
In:

Der Kopf jeder Fläche auf dem Mac und iPad – Suche links, drei Kreise rechts.

<Kopfzeile bereiche={["Termine", "Fahrten", "Aufgaben", "Dokumente", { name: "Post", zaehler: 2 }]}
  onPlus={() => setMenue(true)} />

Die Reihenfolge der Kreise steht fest: Klingel, Nachrichten, Plus – Plus ist rosa und immer der letzte. Chips sind gestrichelt, weil sie Bereiche einschränken und nichts anlegen.

Types (.d.ts)
/**
 * Der Kopf jeder Flaeche: Suchfeld mit rosa Lupe, Bereichs-Chips, drei Kreise rechts.
 */
export interface KopfzeileProps {
  platzhalter?: string;
  /** Bereichs-Chips, gestrichelt: "Termine", "Fahrten", "Aufgaben", "Dokumente", { name: "Post", zaehler: 2 }. */
  bereiche?: Array<string | { name: string; zaehler?: number }>;
  gewaehlterBereich?: string;
  onBereich?: (name: string) => void;
  onSuche?: (e: React.ChangeEvent<HTMLInputElement>) => void;
  /** Rosa Punkt an der Klingel, wenn etwas Neues da ist. */
  klingelPunkt?: boolean;
  onKlingel?: () => void;
  onNachrichten?: () => void;
  /** Oeffnet das Schnellmenue "Schnell anlegen". */
  onPlus?: () => void;
  style?: React.CSSProperties;
}
export function Kopfzeile(props: KopfzeileProps): JSX.Element;

The five kinds of card

Today, Week and calendar are made of cards. The kind sets the surface, the icon the thing, the dots the people.

KindSurface and edgeFor
Event (Termin)beige, hairlineanything with a time and place
Drive (Fahrt)bluedrives from → to
Family (Familie)yellowrituals, shared meals, Sunday round
Suggestion (Vorschlag)dashed grey without fill (Mac) · yellow with shapes (iPhone)Albert’s suggestion, always with two buttons
Open (Offen)dashed open-pinksomething with no one responsible, shown loudly

Karte

components/karten/Karte.jsx
AL
Kieferorthopädin
Praxis Dr. Voss
16:00 – 17:00
TF
Handball, Halle Süd
Schule → Halle Süd
Fr 16:40
Tobias fährt 16:40 · Kombi
ATFL
Mittagessen bei Oma Grete
So 12:30 · alle
Bei Tobias steht ab 13:00 nichts. Fragen?
Vorschlag von Albert
Abholen Halle Süd
19:00
Ohne Zuständigen
Mathe mit Felix17:30F

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

<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.

Types (.d.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;

States are mandatory

No screen is finished without its states: empty, loading, error, offline, undo. They are in the chapter States. A view is only finished with all of this:

  • 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

What is available where

“Full” means it belongs here. “Reduced”: present, deliberately leaner. “Read”: view, not edit. From docs/11-produkt.md §10, cut down to the places of the app.

PlaceMaciPadiPhoneWatch
Todayreducedfullfullreduced
Week (week board)fullreducedread–
Inbox (mail, scan)fullfullreduced, scanning full–
Food and shoppingfull (plan)fullfull (list in the shop)vote
Tasksfullfullreduced, ticking off fulltick off
Drivesplanning fullreducedleaving and arriving fullleaving and arriving
Schooltimetablereducedschool folder fulldictate homework
Joy (feed, occasions, album)fullfullreduced–
Important (safe, vault, finances)fullreducedread–
Sunday roundfullfullread–
Household and rightsfullreducedread–

Every screen of the Sonntag family

These are the screens the website, the App Store and this site work with. Each links to a PNG for download.

Anlass · mac · PNG
Aufgaben · mac · PNG
FamilyFeedMac · mac · PNG
Haushalt · mac · PNG
Safe · mac · PNG
Wochenboard · mac · PNG
Eingang · iphone · PNG
Einkauf · iphone · PNG
Essensplan · iphone · PNG
FamilyFeed · iphone · PNG
Gewohnheiten · iphone · PNG
Main · iphone · PNG
MomentTurnbeutel · iphone · PNG
MomentVersicherung · iphone · PNG
Schule · iphone · PNG
Taler · iphone · PNG
Ueberall · iphone · PNG
LenaBereich · ipad · PNG
Rueckblick · ipad · PNG
Watch · watch · PNG
Sonntagsrunde · breitbild · PNG
Jahresbuch · objekt · PNG