# Eine App im neuen Standard

Ein Widget steht in einer Szene selten bildschirmfüllend: oft als kleine Kachel, hochkant am Rand oder als Leiste. Der Standard sorgt dafür, dass es in jedem Rahmen gut aussieht, dass der Kunde beim Einfügen eine passende Vorlage findet und dass das Einstellungs-Fenster zeigt, was später am Display passiert. Diese Seite führt eine bestehende App Schritt für Schritt dorthin, mit der Wetter-App als durchgehendem Beispiel.

> **Typ:** anleitung
> **Für wen:** Entwickler, die eine App der Plattform auf Vorlagen, Formate und das deklarative Formular umstellen oder eine neue App von Anfang an so bauen.
> **Voraussetzung:** eine App im Quellbaum, die mit `pnpm --filter @szenera-app/<id> build` baut; die Felder der Widget-Definition aus [Widget, Konfiguration und Vorschau](/de/apps-sdk/widget-and-preview).

## Was der Standard verlangt

| Baustein | Woran man ihn erkennt | Schritt |
|---|---|---|
| Vorlagen | Jede Variante trägt eine Startgröße, genau eine ist `primary`. | [1](#1-vorlagen-mit-größe-und-primary) |
| Formate | Die Anordnung folgt Form und Größe des Rahmens, nicht einer Einstellung. | [2](#2-die-anordnung-folgt-dem-rahmen) |
| Passt-Bericht | Was eingeschaltet ist, aber nicht passt, meldet das Widget. | [3](#3-der-passt-bericht) |
| Flächen, Symbole, Bausteine | Hintergrund aus den gemeinsamen Flächen, Symbole aus dem gemeinsamen Satz, Listen, Laufband, Code, Quelle und leerer Zustand aus den Anzeige-Bausteinen. | [4](#4-flächen-symbole-und-bausteine) |
| Formular | Deklarativ beschrieben, mit festen Gruppen, Schnellfeldern und Texten aus dem Schema. | [5](#5-das-formular-deklarativ) |
| Eigene Felder | Nur dort, wo keine Feldart passt, und dann als einzelnes Feld. | [6](#6-eigene-felder) |
| Vorschau-Zustände | Regen, Nacht oder „keine Daten“ sind im Fenster umschaltbar, ein Widget mit Quelle hat den Zustand `empty`, und am Display steht nie Editor-Text. | [7](#7-vorschau-zustände) |
| Passt-Prüfung | Jede Vorlage und jede Randgröße passt, lesbar und ungekürzt, jeder Zustand ist am Display ruhig. | [8](#8-die-passt-prüfung) |
| Store-Bilder | Jede Vorlage im echten Rahmen auf ruhiger Fläche. | [9](#9-store-bilder) |
| Alte Configs | Ein Seed-Schritt hebt den Bestand, das Schema kennt nur die neuen Felder. | [10](#10-alte-configs) |
| Host-Vertrag | Das Bündel verlangt die Zusage der Anzeige, die seine Importe decken, und geht erst nach ihr hinaus. | [11](#11-host-vertrag-und-freigabe) |

## 1. Vorlagen mit Größe und `primary`

Die Varianten unter `preview.variants` sind die Vorlagen beim Einfügen, die Bilder im Store und die Kacheln „Vorlage“ im Einstellungs-Fenster, alles aus einer Quelle. Jede trägt eine Startgröße in Bezugspixeln einer 1920 × 1080-Szene und nur den Teil der Config, der sie ausmacht. Genau eine ist `primary`: Ein Klick auf die App im Editor setzt sie ein. Die Größe ist ein Anfang, kein Käfig, der Kunde zieht den Rahmen danach, wie er will.

Aus `apps/weather/src/widgets/weather/definition.ts` (gekürzt):

```ts
size: { min: { w: 160, h: 90 } },
preview: {
  thumbnailUrl: '/apps/weather/thumbnails/weather.png',
  variants: [
    {
      id: 'compact',
      label: 'Kompakt',
      description: 'Ort, Temperatur, Wetterlage und die Spanne des Tages auf einer kleinen Kachel.',
      size: { w: 300, h: 300 },
      config: { showHourly: false, showDaily: false },
    },
    {
      id: 'hourly',
      label: 'Mit Stunden',
      description: 'Dazu die nächsten Stunden in einer Zeile.',
      size: { w: 600, h: 300 },
      config: { showHourly: true, showDaily: false },
      primary: true,
    },
    // … daily 760 × 300, full 640 × 640, column 340 × 640, bar 1320 × 110
  ],
},
```

Bewährt hat sich: eine Vorlage je Form, die die App beherrscht (Kachel, quer, hochkant, Leiste), und die Größe so wählen, dass in ihr alles passt, was sie einschaltet. `size.min` ist der kleinste Rahmen, in dem das Widget noch etwas Sinnvolles zeigt, jede Vorlage muss mindestens so groß sein. Gestaltungen, die sich nur im Inhalt unterscheiden, sind Vorlagen desselben Widgets, keine zweiten Widgets.

## 2. Die Anordnung folgt dem Rahmen

`useWidgetFormat()` aus `@szenera/widget-foundation/hooks` nennt die Form des Rahmens (`band`, `wide`, `square`, `tall`), die Größenklasse (`compact` unter 400 Bezugspixeln kurzer Seite, sonst `regular`) und die Maße. Die App zeichnet je Form eine Anordnung. Gemessen wird nichts im DOM: Die Plattform kennt den Rahmen, die Anordnung steht deshalb schon beim ersten Zeichnen. Die Schwellen und die Rechnung stehen unter [Formate](/de/apps-sdk/widget-and-preview#formate-wie-ein-widget-seinen-rahmen-nutzt).

Die Wetter-App rechnet die Anordnung als reine Funktion (`runtime/layout.ts`) und ruft sie aus der Laufzeit auf. Aus `apps/weather/src/widgets/weather/runtime.tsx` (gekürzt):

```tsx
const config = useWidgetConfig(WeatherConfigSchema);
const format = useWidgetFormat();
const fit = useFitReport();

// Bühnenpixel je Bezugspixel: Die kurze Seite des Rahmens kennt die Plattform in beiden Maßen.
const short = Math.min(format.width, format.height);
const scale = scaleOf(format.shortSideRef > 0 && short > 0 ? short / format.shortSideRef : 1);
const layout = planWeatherLayout({
  shape: format.shape,
  width: format.width / scale.k,
  height: format.height / scale.k,
  wants: { hourly: config.showHourly, daily: config.showDaily, highLow: config.showHighLow },
});
```

Drei Regeln, die jede Anordnung einhält:

- **Alle Maße wachsen mit dem Rahmen.** Gerechnet wird in Bezugspixeln, Schrift, Abstände und Eckenradius sind Anteile davon. So sieht dieselbe Vorlage in einer 4K-Szene aus wie in Full HD.
- **Eine feste Wegfall-Folge.** Was in einem Rahmen keinen Platz hat, fällt in einer Reihenfolge weg, die die App einmal festlegt. Beim Wetter bleiben Ort, Temperatur und Wetterlage immer, dann fallen Tage, Stunden, Höchst- und Tiefstwert. In der Spalte (`tall`) kommen die Stunden erst ab der 1,7-fachen Höhe dazu und fallen deshalb zuerst weg.
- **Breiter Ziehen nimmt nie Inhalt weg.** Bei gleicher Höhe blendet ein breiterer Rahmen nie mehr aus als ein schmalerer, auch nicht an der Grenze zweier Formen. Ein Test der Anordnung hält das fest.

Die Anordnung als reine Funktion zu schreiben lohnt sich: Ihre Tests laufen ohne Browser und decken jede Form und jede Grenze ab.

## 3. Der Passt-Bericht

Blendet das Widget einen eingeschalteten Inhalt aus, meldet es die Teile mit den Schlüsseln der Config-Felder, die sie einschalten. Der Editor sagt dann unter der Vorschau und am Schalter, warum ein Inhalt fehlt, statt dass er wie ein Fehler wirkt. Die Wetter-App gibt die Liste aus ihrer Anordnung weiter:

```tsx
const hiddenKey = layout.hidden.join(',');
useEffect(() => {
  fit.reportHidden(hiddenKey === '' ? [] : hiddenKey.split(','));
}, [fit, hiddenKey]);
```

Gemeldet wird bei jeder Anordnung die vollständige Liste, leer, sobald alles zu sehen ist, und immer, ohne zu fragen, wo das Widget läuft: Auf dem Display bleibt die Meldung ohne Wirkung.

## 4. Flächen, Symbole und Bausteine

Der Hintergrund kommt aus den gemeinsamen Flächen in `@szenera/widget-foundation/widget-ui/tokens`: `light`, `dark`, `glass` und `transparent` (`WIDGET_SURFACE_IDS`, aufgelöst mit `resolveWidgetSurface(id)`, das Hintergrund und Schriftfarbe liefert). Eine App darf eigene Flächen ergänzen, das Wetter hat `condition`, einen Verlauf je Wetterlage. Eigene Hex-Farben im Formular entfallen. Das Feld der Config ist eine Auswahl der Kennungen:

```ts
surface: z
  .enum(WEATHER_SURFACE_IDS)
  .default('condition')
  .describe(
    'Hintergrund|Wetterlage färbt die Fläche nach dem Wetter. Hell, Dunkel, Glas und Transparent bleiben gleich.',
  ),
```

Symbole kommen aus dem gefüllten Satz `ConditionIcon` in `@szenera/widget-foundation/widget-ui` (Sonne, heiter, Wolke, Regen, Schnee, Gewitter, Nebel, Mond), nicht aus eigenen Grafiken der App. Gestaltet wird schlicht: keine Karten in Karten, keine Rahmen um Kacheln, die Hausschrift Inter.

Was mehrere Apps brauchen, baut keine App selbst nach. Die Anzeige-Bausteine in `@szenera/widget-foundation/widget-ui` tragen keinen eigenen Stil, sie nehmen Fläche, Schrift und Maße der App:

- **`PagedList`**, sobald eine Anzeige eine Folge gleichartiger Einträge zeigt, deren Zahl sie nicht bestimmt (Termine, Gerichte, Schlagzeilen). Die Liste blättert im festen Takt, statt die Schrift unter die Mindestgröße zu drücken.
- **`QuietState`**, immer wenn Daten fehlen. Am Display die Fläche und höchstens ein neutraler Satz, im Editor die Erklärung mit dem nächsten Schritt.
- **`CompanionQr`**, wann immer ein Code erscheint. Er hält Ruhezone, Kontrast und Modulgröße, die Beschriftung schiebt ihn nie aus seiner Ruhezone.
- **`MarqueeBand`** für eine einzelne Zeile in einer Leiste, die länger ist als die Leiste. Mehrere Zeilen blättert `PagedList`.
- **`SourceCredit`** in jeder Anzeige mit fremden Daten: die Quelle als Text, nie abschaltbar, nie gekürzt.

Zweck und Einzelheiten stehen unter [Anzeige-Bausteine](/de/apps-sdk/widget-and-preview#anzeige-bausteine). Die Bausteine kamen mit der Fassung 1.2.0 des Host-Vertrags, eine App, die sie nutzt, verlangt `^1.2.0` (Schritt [11](#11-host-vertrag-und-freigabe)).

## 5. Das Formular deklarativ

Das Einstellungs-Fenster baut sein Formular aus einer Beschreibung (`defineWidgetConfigUI` aus `@szenera/apps-sdk/config`), die die App in ihrem Authoring-Bündel registriert. Die Gruppen folgen einer festen Folge, damit sich ein Kunde in jeder App zurechtfindet: Quelle, Inhalt, Aussehen, Erweitert (eingeklappt). Vorlage und Platzierung ergänzt der Editor selbst. Aus `apps/weather/src/widgets/weather/config-ui.ts` (gekürzt):

```ts
/** Beschriftung und Hilfetext eines Feldes, wie das Schema sie trägt. */
const text = (field: string): ConfigUIFieldText => schemaFieldText(WeatherConfigSchema, field);

export const weatherConfigUI = defineWidgetConfigUI({
  sections: [
    { id: 'source', label: 'Quelle' },
    { id: 'content', label: 'Inhalt' },
    { id: 'appearance', label: 'Aussehen' },
    { id: 'advanced', label: 'Erweitert', collapsed: true },
  ],
  fields: {
    location: { kind: 'location', ...text('location'), section: 'source', fallback: true },
    showHourly: { kind: 'toggle', ...text('showHourly'), section: 'content' },
    surface: {
      kind: 'surface',
      ...text('surface'),
      section: 'appearance',
      options: [
        { value: 'condition', label: 'Wetterlage', swatch: SWATCHES.condition },
        { value: 'light', label: 'Hell', swatch: SWATCHES.light },
        // … dark, glass, transparent
      ],
    },
    // … showDaily, showHighLow, corners, units
  },
  quickFields: ['surface'],
});
```

- **Texte aus dem Schema.** Beschriftung und Hilfetext stehen einmal in `.describe('Beschriftung|Hilfetext')` und kommen über `schemaFieldText` ins Formular. Ein Feld heißt im Editor so wie im Schema, das ein Assistent liest.
- **Schnellfelder.** `quickFields` nennt höchstens zwei kompakte Felder, die an der schwebenden Leiste über dem Widget stehen, beim Wetter der Hintergrund. Die Vorlage steht dort ohnehin.
- **Ort.** Die Feldart `location` gehört zu `placeSelection('display')` im Schema: „Standort des Displays“ oder „Fester Ort“, mit `fallback: true` dazu der Ersatzort für Displays, deren Standort keine bekannte Lage hat, im Ort-Feld unter „Standort des Displays“. Wer den Standort liest, erklärt den Lesebereich `player-location` und nennt ihn in seinen Bedingungen, siehe [Datenzugriff, Rechte und Bedingungen](/de/apps-sdk/data-access).
- **Fläche.** Die Feldart `surface` zeigt Kacheln mit einem Farbmuster je Fläche, damit man sie erkennt, bevor man sie wählt.
- **Sichtbarkeit.** `showWhen: { field, equals }` (oder `in`, mit `not: true` umgekehrt) blendet ein Feld oder eine ganze Gruppe aus, solange es nichts bewirkt, etwa eine Farbe nur bei einer bestimmten Fläche. Ein ausgeblendetes Feld behält seinen Wert.
- **Pflicht.** `required: true` kennzeichnet ein Feld als Pflicht. Ob ein Wert fehlt oder falsch ist, entscheidet weiter das Schema, und bei einem Fehler sperrt das Fenster „Übernehmen“.

`pnpm app:check` prüft jede Formular-Beschreibung, etwa Schnellfelder, die kein beschriebenes Feld nennen, keine kompakte Feldart haben oder doppelt stehen.

## 6. Eigene Felder

Passt keine Feldart, registriert die App ein einzelnes Feld, nie ein ganzes Formular: So erreichen Verbesserungen des Fensters jede App, ohne dass sie nachzieht. Die Wetter-App bringt nur die Ortssuche selbst mit und hängt sie an den Pfad `location.place`. Aus `apps/weather/src/authoring/index.ts`:

```ts
export function registerAuthoring(registry: AuthoringRegistry): void {
  registry.registerConfigUI(WEATHER, weatherConfigUI);
  // Die Ortsauswahl arbeitet mit einem Ort als Wert, die Registry kennt Felder allgemein.
  registry.registerConfigField(
    WEATHER,
    'location.place',
    CityPicker as ComponentType<ConfigFieldProps>,
  );
}
```

Das Feld bekommt Wert, Änderungs-Rückruf und den Formular-Kontext (Rahmen, Sprache, Displays der Organisation) als Eigenschaften und rendert nur sich selbst. Beschriftung, Gruppe und Hilfetext kommen weiter aus der Beschreibung.

## 7. Vorschau-Zustände

`preview.states` sind benannte Beispiel-Nutzlasten, die das Fenster neben „Echte Daten“ zum Umschalten anbietet. So sieht man Regen, Nacht oder „keine Daten“, ohne auf das Wetter zu warten:

```ts
states: [
  {
    id: 'sunny',
    label: 'Sonne',
    description: 'Klarer Himmel am Mittag.',
    mockData: WEATHER_PREVIEW_STATES.sunny,
  },
  // … rain, snow, night
],
```

Die Nutzlasten stehen neben den Demo-Daten der App und folgen demselben Schema wie die echte Nutzlast. Ein Zustand, den die Anzeige nicht kennt, fällt in ihren Tests auf, nicht erst beim Kunden.

**Ein Widget mit Quelle hat den Zustand `empty`.** Er zeigt das Widget ohne Daten (`mockData: null`), `pnpm app:check` verlangt ihn. Beim Wetter:

```ts
{
  id: 'empty',
  label: 'Keine Daten',
  description: 'So sieht das Widget aus, solange der Wetterdienst nichts liefert.',
  mockData: null,
},
```

**Nie Editor-Text am Display.** Leer, gestört oder unkonfiguriert heißt am Display eine ruhige Fläche und höchstens ein neutraler Satz. Wer vor dem Bildschirm steht, kann nichts einstellen, und für den Laden wirkt eine Anleitung wie ein Fehler. Die Erklärung mit dem nächsten Schritt gehört in den Editor: Die App fragt `useWidgetMode()` oder nimmt den Baustein `QuietState`, der beides trennt. Das Wetter zeigt am Display ohne Daten nur „Wetterdaten vorübergehend nicht verfügbar“, im Editor dazu, ob ein Ort, ein Standort oder nur die Daten fehlen. Die Passt-Prüfung rendert jeden Zustand im Anzeige-Modus und meldet einen Satz an den Bearbeiter (Schritt [8](#8-die-passt-prüfung)).

## 8. Die Passt-Prüfung

Die Passt-Prüfung rendert jede Vorlage in ihrem Rahmen und meldet, was übersteht, angeschnitten oder ganz verdeckt ist, Zeilen, die ein kürzender Kasten durch die Buchstaben schneidet, Texte, die einander überdecken, Schrift unter der Mindestgröße und was das Widget im eigenen Rahmen ausblendet. Sie steht als Gate im Pull Request.

```bash
pnpm --filter @szenera-app/<id> build
pnpm app:fit-check --only=<id>                       # Vorlagen, Randgrößen und Zustände der App
pnpm app:fit-check --try=<id>:<variante>@1000x300    # eine Größe messen, bevor sie im Manifest steht
```

Für eine App im neuen Standard misst sie mehr als die Vorlagen:

- **Der Randgrößen-Satz.** Mit `size.min` bekommt jedes Widget die Rahmen, an denen Anordnungen brechen: die Mindestgröße, je Form den kleinsten erlaubten Rahmen und den größten in der Szene, die Leiste als volle Breite in Mindesthöhe, die Spalte als volle Höhe in Mindestbreite. Ausblenden ist dort erlaubt, abschneiden und zu kleine Schrift nicht. Beim Wetter (Mindestgröße 160 × 90) sind das acht Rahmen, darunter die Kachel 161 × 131, die Leiste 1920 × 90 und die Spalte 160 × 1080.
- **Die Mindestschrift.** Inhalt nie unter 12, Quellen- und Standzeilen nie unter 10 Bezugspixeln. Eine Anordnung, die Platz braucht, lässt Inhalt weg oder blättert, statt die Schrift zu drücken. Die Quellenzeile trägt `data-fit-meta` (der Baustein `SourceCredit` ist als ganzer Text markiert).
- **Ganze Texte.** Uhrzeit, Datum, Preis, Pflichtangaben und Telefon tragen `data-fit-whole`. Ein solcher Text wird nie gekürzt, weder mit „…“ vom Kasten noch von einem Skript.
- **Die Zustände am Display.** Jeder Vorschau-Zustand im Anzeige-Modus, `empty` und `error` in jeder Vorlage, ohne Satz an den Bearbeiter.

Die Bilder eines Rahmens mit Befund liegen danach unter `scratchpad/fit-check/`. Mit `--try` lohnt es sich, die Grenzen abzufahren: knapp unter und über jeder Formschwelle. Läuft ein Inhalt absichtlich durch seinen Kasten und bewegt ihn ein Skript statt einer CSS-Animation, trägt das bewegte Element oder sein Kasten `data-fit-scroll`. Schneidet eine App in jeder vernünftigen Größe ab, weil ihre Gestaltung erst in ihrer eigenen Welle neu entsteht, gehört der Rahmen mit einem Satz Grund („eigene Welle“) in `tools/app-screenshots/fit-exceptions.mjs`. Für eine App, die gerade umgestellt wird, ist das kein Weg: Ihre Vorlagen, Randgrößen und Zustände passen, das Wetter trägt keine Ausnahme.

## 9. Store-Bilder

Die Bilder im Store zeigen jede Vorlage im echten Rahmen auf einer ruhigen Fläche, Name und Maß darunter, kleine Vorlagen vergrößert. Sie entstehen mit demselben Renderer wie die Anzeige:

```bash
node tools/app-screenshots/run.mjs --only=<id>
```

Das Werkzeug schreibt `apps/<id>/thumbnails/<widget>--<variante>.png` je Vorlage, eine Kopie der `primary`-Vorlage als `<widget>.png` und das Szenenbeispiel. `pnpm app:check` prüft danach, ob jedes Bild da und nicht leer ist. Die Bilder gehören in denselben Commit wie die Vorlagen.

## 10. Alte Configs

Gespeicherte Szenen tragen Configs früherer Fassungen. Sie werden nicht beim Lesen umgedeutet, sondern einmal durch einen Seed-Schritt in die neue Form geschrieben, Bestand und Szenen-Vorlagen gleichermaßen. Danach kennt das Schema nur die neuen Felder, und Formular, Vorlagen-Erkennung, Schnittstelle und Assistenten sehen denselben Stand wie die Anzeige.

- **Die Abbildung** ist eine reine Funktion mit Tests über jede Kombination der alten Werte. Beim Wetter: Ein gesetzter Ort wird zum festen Ort, die Tage sind an, wenn die alte Config Tage zeigte (`forecastDays` über 0 und `layout` nicht `current-only`), ein transparenter Hintergrund bleibt `transparent`, jeder andere wird `dark`.
- **Alte Schlüssel bleiben im JSON stehen.** Eine Organisation, die das Update noch nicht angenommen hat, läuft mit der älteren Fassung weiter und liest sie. Das neue Schema verwirft unbekannte Schlüssel still.
- **Neue Felder haben eine Vorgabe**, damit auch eine Config ohne sie gültig ist. Die Grundlinie `tests/compat-baseline.json` der App wird mit `pnpm app-compat --update <id>` fortgeschrieben, sobald die alten Felder das Schema verlassen.
- **Szenen-Vorlagen und Demo-Quellen** stehen in der neuen Form. Eine Vorlage, die alte Felder schreibt, erzeugt den Fall, den der Seed-Schritt gerade aufgelöst hat.

## 11. Host-Vertrag und Freigabe

Formate, Passt-Bericht, Flächen und Symbole kamen mit der Fassung 1.1.0 des Host-Vertrags in die Anzeige. Der Bau einer App schreibt nach `dist/renderer-host.json`, welche Namen das Bündel aus der Anzeige bezieht, und setzt die Zusage im Manifest (`apiCompatibility.rendererHost`) auf die niedrigste Fassung, die diese Importe deckt. Das Wetter verlangt deshalb `^1.1.0`, eine App, die keinen der neuen Namen nutzt, bleibt bei `^1.0.0`.

Eine Anzeige mit älterer Zusage weist ein Bündel, das mehr verlangt, als `host-incompatible` ab. Daraus folgt die Reihenfolge der Freigabe: zuerst die Anzeige mit der neuen Zusage durch ihre Kanäle, und erst wenn die Geräte sie angenommen haben, die App. Fire TV und Web-Display laden die Anzeige aus der Cloud, ein Raspberry Pi holt sie über die Fernwartung. Vor der Freigabe nach Produktion steht die Sichtprüfung auf Staging am echten Gerät: Pi, Fire TV und Web-Display, hell und dunkel, jede Vorlage. Liest die neue Fassung Daten, denen die Organisation noch nicht zugestimmt hat, wartet ihr Update auf diese Zustimmung, und bis dahin läuft die ältere Fassung weiter.

## Die nächsten Apps

Die Wetter-App ist die erste App im Standard. Die Reihenfolge der übrigen richtet sich nach dem Nutzen für Kunden und nach dem, was die Passt-Prüfung und der Blick auf die Store-Bilder heute zeigen:

| Reihenfolge | App | Warum jetzt |
|---|---|---|
| 1 | Öffnungszeiten | Jeder Standort jeder Branche zeigt sie. Die Anzeige ist überschaubar, ihre vier Vorlagen passen schon. Als zweite App prüft sie den Leitfaden mit wenig Risiko, bevor eine große App folgt. |
| 2 | Notdienst-Apotheken | Für Apotheken Pflicht im Schaufenster und das Kerngeschäft der Branche. Sie trägt die beiden offenen Ausnahmen der Passt-Prüfung: Hochkant überdecken sich Titel und Plakette mit der Notdienst-Nummer, in der Vorlage `karte` verschwindet die Beschriftung einer Marke unter der Liste. Wie das Wetter gewinnt sie am meisten vom Standort des Displays: eine Szene für alle Filialen, jede zeigt ihre Notdienste. |
| 3 | Nachrichten mit Marken-Apps und Ticker | Ein Code für sieben Apps (Tagesschau, BBC, BILD, Deutschlandfunk, NDR, SPIEGEL, RSS), der Hebel ist groß. Die Laufzeile wächst heute nicht mit der Höhe ihres Bandes, und der Ticker kappt auf ganzer Bühne die Unterlängen seiner Meldungen. Beide Leisten folgen danach derselben Form `band`. |
| 4 | Menükarte | Gastronomie und Bäckereien, oft hochkant am Tresen. Die Vorlagen passen, eine Anordnung je Form fehlt ihr wie jeder App außer dem Wetter. |
| 5 | Kalender | Das Wochenraster skaliert seine Schrift kaum und wird in kleinen Rahmen unlesbar. Der Hintergrund ist als Vorgabe transparent, im Store-Bild ist der Rahmen deshalb nicht zu sehen. |

Die Uhren-Familie (Uhr, Wortuhr, Weltuhr, Countdown, Countup) folgt danach: Sie passt heute schon in jeder Vorlage und gewinnt vor allem Formate, Flächen und das deklarative Formular.

## Weiterführendes

- [Widget, Konfiguration und Vorschau](/de/apps-sdk/widget-and-preview) — jedes Feld der Widget-Definition, Formate, Passt-Bericht und Vorschau-Zustände im Detail.
- [Von der Vorlage bis zur Freigabe](/de/apps-sdk/template-to-release) — der ganze Weg einer neuen App, die mit `pnpm app:new` schon im Standard beginnt.
- [Datenzugriff, Rechte und Bedingungen](/de/apps-sdk/data-access) — der Lesebereich `player-location` und was eine App vor der Installation offenlegt.
- [Signieren und der Weg in den Katalog](/de/apps-sdk/signing-and-catalog) — Kanäle und Freigabe einer Fassung.
