Skip to content

Letter

Generated from front/ui/catalogue/examples/Letter.json

section · static (no JavaScript) · no children. All components: component playground.

Personal letter from the tutors with portraits, paragraphs and a pull quote (editorial).

Rendered from the example props below with the real component. Theme: coffee · oncall · nightsky · gravity · poland · ulam · platform · open on its own

{
"component": "Letter",
"props": {
"eyebrow": "A note from the roaster",
"title": "Why we teach brewing",
"paragraphs": [
"Most bad coffee is a process problem, not a bean problem.",
"In this course you learn to taste what is wrong and change one thing at a time."
],
"quote": "Change one variable, then taste.",
"people": [
{
"name": "Ada Kowalska",
"role": "Head roaster",
"place": "Krakow",
"bio": "Fifteen years of roasting and teaching extraction."
}
]
}
}
Prop Type Required Notes
eyebrow string Small label above the title. max length 80
title string yes Section title. max length 160
paragraphs array of string yes Paragraphs. max 6 items
quote string Pull quote. max length 400
people array of objects Signatories. max 3 items
people[].name string yes Full name. max length 80
people[].role string Role or title. max length 80
people[].place string Place. max length 80
people[].bio string Short bio. max length 600
people[].image object An image with explicit size (prevents layout shift)
people[].image.src string (href) yes Image URL (local /images/… or the tenant storage). max length 2048
people[].image.alt string yes Text alternative; empty string only for decorative images. max length 300
people[].image.width integer yes Intrinsic width in px. ≥ 1
people[].image.height integer yes Intrinsic height in px. ≥ 1
id string Anchor id for in-page links (letters, digits, dashes). max length 40

What a text-only client, an unknown renderer or a plain-text channel shows for the example above.

Why we teach brewing
Most bad coffee is a process problem, not a bean problem.
In this course you learn to taste what is wrong and change one thing at a time.
Change one variable, then taste.

A node whose props fail the schema never breaks the page: the renderer shows the plain-text fallback instead (and logs the issues in development).

{
"paragraphs": "text"
}

Issues:

  • /title is required
  • /paragraphs expected array, got string

Rendered as:

Nothing: this component has no text of its own.

axe-core: 13 rules passed, 0 violations, 0 need manual review. Run at build time on the server-rendered HTML in jsdom. Colour contrast and layout rules need a browser and are covered by the Playwright axe scans of the reference frontend.