UI catalogue
Generated from front/ui/src/registry.ts
Every component an agent or a page document may use, from front/ui/src/registry.ts. A document is a tree of { "component", "props", "children" } nodes rendered by <Render>; invalid props render the component’s plain-text fallback. See Reference frontend and Generative UI; to add a component, UI components.
Themes: coffee, oncall, nightsky, gravity, poland, ulam, platform. Formats: video, audio, reading, image, pdf, embed, interactive, scorm, tracked, quiz, project.
Structure components
Section titled “Structure components”Root of a page document. Sets the theme and metadata. Children: SiteHeader, Main, SiteFooter in that order.
static (no JS) · renders children
| Prop | Type | Required | Notes |
|---|---|---|---|
theme |
"coffee" | "oncall" | "nightsky" | "gravity" | "poland" | "ulam" | "platform" |
yes | Tenant theme preset |
title |
string | yes | Document title for the browser tab and search results. max length 70 |
description |
string | Meta description, under 160 characters. max length 160 | |
lang |
string | BCP 47 language of the page. max length 10, default "en" |
The page’s main landmark. Put every section between the header and the footer inside it.
static (no JS) · renders children
No props.
Vertical group of components with consistent spacing (e.g. the body of a lesson).
static (no JS) · renders children
| Prop | Type | Required | Notes |
|---|---|---|---|
gap |
"sm" | "md" | "lg" |
Space between children. default "md" |
SiteHeader
Section titled “SiteHeader”Top navigation bar with the brand, up to six links and one call to action. Collapses to a menu on phones.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
brand |
string | yes | Brand name. max length 60 |
tagline |
string | Small line under the brand. max length 60 | |
mark |
"wordmark" | "terminal" | "rocket" | "orbit" | "compass" | "sigma" | "logo" |
Brand mark style; logo = the ulams mark. default "wordmark" |
|
links |
array of objects | Navigation links. max 6 items, default [] |
|
links[].label |
string | yes | Visible text. max length 80 |
links[].href |
string (href) | yes | Target URL. max length 2048 |
cta |
object | A link or call to action | |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
signIn |
object | A link or call to action | |
signIn.label |
string | yes | Visible text. max length 80 |
signIn.href |
string (href) | yes | Target URL. max length 2048 |
homeHref |
string (href) | Where the brand links to; the language home on a translated landing. max length 2048 | |
languages |
array of objects | Language switcher: one entry per language, in display order; the current one is marked. max 4 items, default [] |
|
languages[].code |
string | yes | Language code of the page it links to (BCP 47). max length 10 |
languages[].label |
string | yes | Name of the language in that language, e.g. PL or 中文. max length 20 |
languages[].href |
string (href) | yes | URL of the page in that language. max length 2048 |
languages[].current |
boolean | True for the language of this page. default false |
StatusBar
Section titled “StatusBar”Thin strip of short facts above or below the header: an editorial ribbon or a status-page line (coloured dots by tone).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"ribbon" | "status" |
ribbon = editorial small caps, status = monospace with status dots. default "ribbon" |
|
items |
array of objects | yes | Items. max 6 items, default [] |
items[].label |
string | yes | Text. max length 80 |
items[].tone |
"neutral" | "ok" | "warn" | "alert" | "info" |
Semantic colour. default "neutral" |
SiteFooter
Section titled “SiteFooter”Page footer with brand, a sentence, links and small print.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
brand |
string | yes | Brand name. max length 60 |
text |
string | Sentence under the brand. max length 300 | |
links |
array of objects | Links. max 10 items, default [] |
|
links[].label |
string | yes | Visible text. max length 80 |
links[].href |
string (href) | yes | Target URL. max length 2048 |
note |
string | Small print. max length 200 |
Section components
Section titled “Section components”First screen of a landing page. editorial = magazine cover with a photo; console = dark split with a log panel; adventure = playful with an illustration; cosmos, atlas and notebook = copy on the left and a live interactive package (or a drawing of orbits, a map graticule or an Ulam spiral) on the right.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"editorial" | "console" | "adventure" | "product" | "cosmos" | "atlas" | "notebook" |
Layout. default "editorial" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | yes | Headline (the LCP element: keep it short). max length 90 |
titleAccent |
string | Part of the headline to emphasise; must appear in the title. max length 60 | |
subtitle |
string | Second line under the headline. max length 160 | |
body |
string | Paragraph. max length 500 | |
primaryCta |
object | A link or call to action | |
primaryCta.label |
string | yes | Visible text. max length 80 |
primaryCta.href |
string (href) | yes | Target URL. max length 2048 |
secondaryCta |
object | A link or call to action | |
secondaryCta.label |
string | yes | Visible text. max length 80 |
secondaryCta.href |
string (href) | yes | Target URL. max length 2048 |
image |
object | An image with explicit size (prevents layout shift) | |
image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
caption |
string | Image caption. max length 160 | |
illustration |
"none" | "orbi" | "planets" |
Inline illustration (adventure variant). default "none" |
|
facts |
array of objects | Up to four facts shown under the call to action. max 4 items, default [] |
|
facts[].label |
string | yes | Label. max length 40 |
facts[].value |
string | yes | Value. max length 60 |
facts[].note |
string | Small note. max length 80 | |
panel |
object | Log-style panel for the console variant | |
panel.title |
string | Panel title. max length 80 | |
panel.note |
string | Small note under the panel, e.g. ‘Example drill replay’. max length 120 | |
panel.lines |
array of objects | yes | Log lines. max 8 items, default [] |
panel.lines[].time |
string | Timestamp. max length 12 | |
panel.lines[].tag |
string | Tag. max length 20 | |
panel.lines[].text |
string | yes | Line. max length 200 |
panel.lines[].tone |
"neutral" | "ok" | "warn" | "alert" | "info" |
Semantic colour. default "neutral" |
|
panel.prompt |
string | Command shown at the bottom of the panel, without the $. max length 60 | |
panel.values |
array of number | Series drawn as the sparkline (e.g. minutes per module); omit for none. max 24 items, default [] |
|
panel.valuesLabel |
string | What the sparkline shows, e.g. ‘minutes per module’. max length 60 | |
capabilities |
array of objects | Capability orbit for the product variant: cards on up to three orbits around the logo, one highlighted at a time. max 12 items, default [] |
|
capabilities[].icon |
"check" | "arrow" | "play" | "clock" | "calendar" | "pin" | "users" | "mail" | "shield" | "star" | "moon" | "planet" | "telescope" | "rocket" | "medal" | "book" | "terminal" | "compass" | "sigma" | "pager" | "chart" | "print" | "lock" | "sync" | "quote" | "layers" | "server" | "puzzle" | "cart" | "code" | "sparkle" | "eye" | "chat" |
Icon from the catalogue’s icon set | |
capabilities[].label |
string | yes | Short label of the capability (2 to 4 words). max length 32 |
capabilities[].caption |
string | yes | One line shown under the orbit while this capability is highlighted. max length 90 |
capabilities[].href |
string (href) | In-page anchor of the section that shows it, e.g. #living. max length 2048 | |
capabilities[].ring |
integer | Orbit the card travels on, 1 = inner. ≥ 1, ≤ 3, default 1 |
|
capabilities[].angle |
integer | Start angle on the orbit in degrees (0 = right, 90 = below); spreads the cards evenly when omitted. ≥ 0, ≤ 359 | |
capabilities[].status |
"available" | "preview" | "coming" |
Roadmap status; shown as a Coming marker only in the actual landing mode. default "available" |
|
showcase |
object | A live interactive package for the cosmos, atlas and notebook variants; without it the variant draws its own picture. Nothing is tracked. | |
showcase.src |
string (href) | yes | Entry file of the interactive package on the content origin. max length 2048 |
showcase.title |
string | yes | Title of the frame. max length 160 |
showcase.steps |
array of objects | yes | Steps with their text alternatives and posters. min 1 items, max 200 items, default [] |
showcase.steps[].id |
string | yes | Step id. max length 64 |
showcase.steps[].title |
string | yes | Step title. max length 255 |
showcase.steps[].text |
string | yes | Text alternative of the step. max length 4000 |
showcase.steps[].poster |
string (href) | Poster image of the step. max length 2048 | |
showcase.showcase |
object | yes | The self-running loop: no step text and no controls, a still first, and a static frame under reduced motion |
showcase.showcase.steps |
array of string | yes | Steps the hero loops through, slowly, in order. min 1 items, max 12 items, default [] |
showcase.showcase.poster |
string (href) | Still shown until the frame runs, and under reduced motion. max length 2048 | |
showcase.href |
string (href) | Where the small link goes (the lesson). max length 2048 | |
showcase.tryLabel |
string | Label of the small link. max length 40, default "Try it" |
|
showcase.locale |
string | Language of the step texts. max length 16, default "en" |
|
showcase.requires |
array of string | Capabilities the package needs. max 5 items, default [] |
|
showcase.reducedMotionSupported |
boolean | The package handles reduced motion itself. default false |
|
showcase.licence |
string | SPDX licence id. max length 64 | |
showcase.attribution |
string | Attribution line. max length 1000 | |
showcase.sourceUrl |
string (href) | Source code or origin of the package. max length 2048 | |
diff |
object | Update-proposal card for the product variant | |
diff.title |
string | Card title, e.g. the lesson being updated. max length 80 | |
diff.source |
string | Source the change comes from, e.g. docs/slo.md. max length 80 | |
diff.note |
string | Small note under the card. max length 160 | |
diff.lines |
array of objects | yes | Diff lines. max 8 items, default [] |
diff.lines[].op |
"add" | "del" | "ctx" |
Diff line kind. default "ctx" |
|
diff.lines[].text |
string | yes | Line. max length 160 |
diff.citations |
array of string | Citations. max 4 items, default [] |
|
diff.action |
string | Label of the approve button. max length 30 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Letter
Section titled “Letter”Personal letter from the tutors with portraits, paragraphs and a pull quote (editorial).
static (no JS) · no children
| 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, default [] |
quote |
string | Pull quote. max length 400 | |
people |
array of objects | Signatories. max 3 items, default [] |
|
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 |
People
Section titled “People”Instructor cards with portrait, role and a short bio.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
people |
array of objects | yes | People. min 1 items, max 8 items, default [] |
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 |
FormatGrid
Section titled “FormatGrid”Grid of the learning formats inside the course, one card per format with a short example.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
items |
array of objects | yes | Cards. max 12 items, default [] |
items[].format |
"video" | "audio" | "reading" | "image" | "pdf" | "embed" | "interactive" | "scorm" | "tracked" | "quiz" | "project" |
yes | Learning format of a topic |
items[].tag |
string | Card label. max length 30 | |
items[].name |
string | yes | Example title. max length 80 |
items[].text |
string | One sentence. max length 240 | |
items[].foot |
string | Small footer. max length 60 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Quotes
Section titled “Quotes”Testimonials. Only quote people from the data model or source material, never invent them. pull = large serif quote; log = timestamped log lines; bubbles = playful cards.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"pull" | "log" | "bubbles" |
Layout. default "pull" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
items |
array of objects | yes | Quotes. max 8 items, default [] |
items[].quote |
string | yes | Quote. max length 400 |
items[].author |
string | yes | Who said it. max length 120 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Events
Section titled “Events”Upcoming live sessions (webinars) and in-person events. Dates come from the data model.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"feature" | "cards" |
feature = one large event with an image; cards = a row of cards. default "cards" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
image |
object | An image with explicit size (prevents layout shift) | |
image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
caption |
string | Image caption. max length 160 | |
items |
array of objects | yes | Events. max 4 items, default [] |
items[].kind |
"webinar" | "in-person" | "consultation" |
Kind of event. default "webinar" |
|
items[].title |
string | yes | Event title. max length 120 |
items[].date |
string (date-time) | ISO 8601 start. max length 40 | |
items[].place |
string | Place (in-person). max length 120 | |
items[].text |
string | One or two sentences. max length 400 | |
items[].cta |
object | A link or call to action | |
items[].cta.label |
string | yes | Visible text. max length 80 |
items[].cta.href |
string (href) | yes | Target URL. max length 2048 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Pricing
Section titled “Pricing”Plans side by side. Prices come preformatted from the data model (products); never invent a price.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "pricing" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
plans |
array of objects | yes | Plans. min 1 items, max 4 items, default [] |
plans[].name |
string | yes | Plan name. max length 80 |
plans[].label |
string | Small label above the name. max length 40 | |
plans[].price |
string | Formatted price, e.g. €89. max length 20 | |
plans[].period |
string | e.g. one-off, per month. max length 30 | |
plans[].description |
string | One sentence. max length 300 | |
plans[].items |
array of string | What is included. max 10 items, default [] |
|
plans[].cta |
object | A link or call to action | |
plans[].cta.label |
string | yes | Visible text. max length 80 |
plans[].cta.href |
string (href) | yes | Target URL. max length 2048 |
plans[].highlighted |
boolean | Visually recommended plan. default false |
|
note |
string | Small print under the plans. max length 200 |
FeatureList
Section titled “FeatureList”A short list of benefits or facts with icons (e.g. ‘For parents’, ‘For teams’).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"tiles" | "checks" | "grid" |
tiles = icon cards; checks = compact checklist; grid = 3-column feature grid with glow. default "tiles" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
items |
array of objects | yes | Items. max 8 items, default [] |
items[].icon |
"check" | "arrow" | "play" | "clock" | "calendar" | "pin" | "users" | "mail" | "shield" | "star" | "moon" | "planet" | "telescope" | "rocket" | "medal" | "book" | "terminal" | "compass" | "sigma" | "pager" | "chart" | "print" | "lock" | "sync" | "quote" | "layers" | "server" | "puzzle" | "cart" | "code" | "sparkle" | "eye" | "chat" |
Icon from the catalogue’s icon set | |
items[].title |
string | yes | Title. max length 80 |
items[].text |
string | Sentence. max length 240 | |
items[].status |
"available" | "coming" |
Shipped today or on the roadmap (say so honestly). default "available" |
|
cta |
object | A link or call to action | |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Badges
Section titled “Badges”Rewards the learner earns (gamified courses).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
items |
array of objects | yes | Badges. max 8 items, default [] |
items[].name |
string | yes | Badge. max length 60 |
items[].text |
string | How to earn it. max length 160 | |
items[].icon |
"check" | "arrow" | "play" | "clock" | "calendar" | "pin" | "users" | "mail" | "shield" | "star" | "moon" | "planet" | "telescope" | "rocket" | "medal" | "book" | "terminal" | "compass" | "sigma" | "pager" | "chart" | "print" | "lock" | "sync" | "quote" | "layers" | "server" | "puzzle" | "cart" | "code" | "sparkle" | "eye" | "chat" |
Icon from the catalogue’s icon set | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Questions and answers as an accessible disclosure list (no JavaScript).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "faq" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
items |
array of objects | yes | Questions. min 1 items, max 12 items, default [] |
items[].q |
string | yes | Question. max length 200 |
items[].a |
string | yes | Answer. max length 1000 |
FeatureIndex
Section titled “FeatureIndex”Everything the product does, grouped and collapsed by default: one native disclosure per group with short feature lines, status badges and links to the package docs (no JavaScript, content stays in the HTML for search engines). Emits ItemList JSON-LD. Use it for a long, honest capability list, not for the three-to-six headline benefits (FeatureList).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "features" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
docsBase |
string (href) | Docs site root; a package name links to |
|
jsonLd |
boolean | Emit schema.org ItemList JSON-LD of the groups and features. default true |
|
groups |
array of objects | yes | Groups. min 1 items, max 16 items, default [] |
groups[].id |
string | yes | Group anchor id. max length 40 |
groups[].title |
string | yes | Group title. max length 80 |
groups[].summary |
string | One sentence under the title when the group is open. max length 300 | |
groups[].items |
array of objects | Features. max 14 items, default [] |
|
groups[].items[].title |
string | yes | Feature. max length 80 |
groups[].items[].text |
string | What it does, in one or two sentences. max length 320 | |
groups[].items[].packages |
array of string | Packages that implement it. max 6 items, default [] |
|
groups[].items[].href |
string (href) | Docs page for the feature. max length 2048 | |
groups[].items[].status |
"available" | "coming" | "preview" |
Shipped today, on the roadmap or off by default (say so honestly). default "available" |
|
groups[].tags |
array of string | Short names shown as a tag cloud (for example the content types of a standard). max 80 items, default [] |
CtaBand
Section titled “CtaBand”Closing call to action: a banner or a newsletter-style band.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"banner" | "newsletter" | "terminal" |
Style; terminal shows code lines in a terminal window. default "banner" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | yes | Section title. max length 160 |
text |
string | One or two sentences under the title. max length 600 | |
code |
array of string | Terminal lines (terminal variant); lines starting with $ are commands. max 10 items, default [] |
|
cta |
object | yes | A link or call to action |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
secondary |
object | A link or call to action | |
secondary.label |
string | yes | Visible text. max length 80 |
secondary.href |
string (href) | yes | Target URL. max length 2048 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
A numbered process in 3–5 steps with a connector line (how something works).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
status |
"available" | "coming" |
Whether the whole process ships today. default "available" |
|
items |
array of objects | yes | Steps. min 2 items, max 5 items, default [] |
items[].icon |
"check" | "arrow" | "play" | "clock" | "calendar" | "pin" | "users" | "mail" | "shield" | "star" | "moon" | "planet" | "telescope" | "rocket" | "medal" | "book" | "terminal" | "compass" | "sigma" | "pager" | "chart" | "print" | "lock" | "sync" | "quote" | "layers" | "server" | "puzzle" | "cart" | "code" | "sparkle" | "eye" | "chat" |
Icon from the catalogue’s icon set | |
items[].title |
string | yes | Step. max length 80 |
items[].text |
string | Sentence. max length 260 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Showcase
Section titled “Showcase”Cards that each open something live (demo sites), with a colour swatch, facts and two buttons.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
note |
string | Small note under the cards. max length 200 | |
items |
array of objects | yes | Cards. min 1 items, max 6 items, default [] |
items[].title |
string | yes | Card title. max length 80 |
items[].text |
string | Sentence. max length 300 | |
items[].theme |
"coffee" | "oncall" | "nightsky" | "gravity" | "poland" | "ulam" | "platform" |
Colour swatch of the card | |
items[].facts |
array of objects | Facts. max 4 items, default [] |
|
items[].facts[].label |
string | yes | Label. max length 30 |
items[].facts[].value |
string | yes | Value. max length 40 |
items[].image |
object | An image with explicit size (prevents layout shift) | |
items[].image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
items[].image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
items[].image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
items[].image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
items[].primary |
object | yes | A link or call to action |
items[].primary.label |
string | yes | Visible text. max length 80 |
items[].primary.href |
string (href) | yes | Target URL. max length 2048 |
items[].secondary |
object | A link or call to action | |
items[].secondary.label |
string | yes | Visible text. max length 80 |
items[].secondary.href |
string (href) | yes | Target URL. max length 2048 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
WorkflowShowcase
Section titled “WorkflowShowcase”Tabs of realistic windows (a terminal, an agent session, a chat with tool calls, an API call, the studio) whose commands and answers are typed line by line, to show that the product can be run from agents and the command line as well as the UI. Each tab may carry a status badge; unbuilt interfaces must be labelled.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
valueLine |
string | One line of value copy under the tabs. max length 200 | |
description |
string | Text alternative of the whole animation for screen readers. max length 600 | |
footnote |
string | Small print under the tabs, e.g. that some commands are the planned interface. max length 300 | |
legal |
string | Trademark line, e.g. that product names belong to their owners and are not endorsements. max length 300 | |
tabs |
array of objects | yes | Tabs. min 1 items, max 6 items, default [] |
tabs[].key |
string | yes | Stable key (letters, digits, dashes). max length 24 |
tabs[].label |
string | yes | Tab label. max length 24 |
tabs[].status |
"available" | "preview" | "coming" |
Status badge; omit when everything shown exists | |
tabs[].window |
"terminal" | "chat" | "studio" |
Look of the window frame. default "terminal" |
|
tabs[].title |
string | yes | Window title. max length 60 |
tabs[].caption |
string | One line under the window. max length 200 | |
tabs[].note |
string | Honest note under the caption, e.g. what the example depends on. max length 200 | |
tabs[].lines |
array of objects | yes | Lines, in order. min 1 items, max 30 items, default [] |
tabs[].lines[].kind |
"prompt" | "cmd" | "cont" | "agent" | "out" | "spin" | "tool" | "add" | "del" | "ctx" | "note" | "user" | "assistant" | "card" |
yes | Line type: typed (prompt, cmd, cont, agent, user, assistant) or shown whole |
tabs[].lines[].text |
string | yes | The line. max length 400 |
tabs[].lines[].args |
string | Tool arguments, or the buttons of a card separated by |. max length 200 | |
tabs[].lines[].result |
string | Short tool result shown after the call. max length 120 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
LivingCourseStory
Section titled “LivingCourseStory”A looping three-beat animation: a source document changes, ulams finds every lesson and quiz question that cites it, and an approved proposal updates the lesson while learner progress is kept. Example values only.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
status |
"available" | "coming" |
Roadmap label under the heading; omit when the feature exists | |
valueLine |
string | One line of value copy under the animation. max length 200 | |
description |
string | yes | Text alternative of the whole animation for screen readers. max length 600 |
beats |
array of objects | yes | Exactly three beats. min 3 items, max 3 items, default [] |
beats[].title |
string | yes | Beat title. max length 60 |
beats[].text |
string | yes | One-line caption. max length 140 |
source |
object | yes | |
source.file |
string | yes | Source file name. max length 60 |
source.heading |
string | Heading line of the source. max length 80 | |
source.context |
string | An unchanged line. max length 120 | |
source.lead |
string | yes | Text of the edited line before the value. max length 80 |
source.before |
string | yes | Old value. max length 24 |
source.after |
string | yes | New value. max length 24 |
source.added |
string | yes | A new line typed after the edit. max length 120 |
lesson |
object | yes | |
lesson.title |
string | yes | Lesson title. max length 80 |
lesson.lead |
string | yes | Lesson sentence before the value. max length 120 |
lesson.citation |
string | yes | Citation chip of the sentence. max length 40 |
lesson.question |
string | yes | Quiz question. max length 160 |
lesson.questionCite |
string | yes | Citation chip of the question. max length 40 |
proposal |
object | yes | |
proposal.title |
string | yes | Proposal card title. max length 80 |
proposal.approve |
string | yes | Approve button. max length 24 |
proposal.done |
string | yes | Badge after approval. max length 60 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
BuilderStory
Section titled “BuilderStory”A looping animation of the studio course builder: a document drops in, interview answers appear, an outline grows with a source chip per lesson, a lesson streams in with citations, a quiz question cites its source, a running cost ticks (example values) and Apply publishes the course.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
valueLine |
string | One line of value copy under the animation. max length 200 | |
description |
string | yes | Text alternative of the whole animation for screen readers. max length 600 |
windowTitle |
string | Window title. max length 60 | |
file |
object | yes | |
file.name |
string | yes | File name. max length 60 |
file.label |
string | Small label. max length 30 | |
interview |
array of objects | yes | Interview answers. min 1 items, max 4 items, default [] |
interview[].question |
string | yes | Question. max length 30 |
interview[].answer |
string | yes | Answer. max length 30 |
outline |
array of objects | yes | Modules. min 1 items, max 4 items, default [] |
outline[].title |
string | yes | Module title. max length 60 |
outline[].lessons |
array of objects | yes | Lessons. min 1 items, max 4 items, default [] |
outline[].lessons[].title |
string | yes | Lesson title. max length 60 |
outline[].lessons[].source |
string | yes | Source chip. max length 30 |
lesson |
object | yes | |
lesson.title |
string | yes | Lesson shown streaming in. max length 60 |
lesson.text |
string | yes | Its text. max length 240 |
lesson.citations |
array of string | Citation chips. max 3 items, default [] |
|
quiz |
object | yes | |
quiz.question |
string | yes | Quiz question. max length 120 |
quiz.source |
string | yes | Source chip. max length 30 |
cost |
object | yes | |
cost.label |
string | yes | Counter label. max length 30 |
cost.amount |
number | yes | Final amount shown (an example). ≥ 0 |
cost.note |
string | Note, e.g. ‘example run’. max length 60 | |
apply |
object | yes | |
apply.label |
string | yes | Apply button. max length 24 |
apply.publishedTitle |
string | yes | Published course title. max length 60 |
apply.publishedMeta |
string | yes | Facts after the title. max length 80 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
WhiteLabelStory
Section titled “WhiteLabelStory”The white-label story of the product landing in four animated steps (an agent with the ulams CLI and a design tool’s MCP reads a brand and applies its tokens, or builds a custom front on the headless API; get a themed site on its own subdomain, bring content and get one course per source, see per-course learner analytics), with a short numbered list under the stage. Every name, colour and bar in the stage is an example. Mark steps and sources that are not shipped with status ‘coming’.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id for in-page links. max length 40, default "white-label" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
valueLine |
string | One line of value copy under the list. max length 200 | |
description |
string | yes | Text alternative of the whole animation for screen readers. max length 1400 |
exampleNote |
string | Small label on the dashboard, e.g. ‘Example data’. max length 40 | |
primaryCta |
object | A link or call to action | |
primaryCta.label |
string | yes | Visible text. max length 80 |
primaryCta.href |
string (href) | yes | Target URL. max length 2048 |
secondaryCta |
object | A link or call to action | |
secondaryCta.label |
string | yes | Visible text. max length 80 |
secondaryCta.href |
string (href) | yes | Target URL. max length 2048 |
steps |
array of objects | yes | The four steps, in order. min 4 items, max 4 items, default [] |
steps[].title |
string | yes | Step title. max length 40 |
steps[].text |
string | yes | One or two sentences. max length 240 |
steps[].points |
array of string | Up to four short points. max 4 items, default [] |
|
steps[].status |
"available" | "coming" |
Shipped today or on the roadmap; shown as Coming only in actual mode. default "available" |
|
steps[].today |
string | What exists today; shown only in actual mode. max length 200 | |
brand |
object | yes | |
brand.sources |
array of objects | yes | Sources dropped in (1 to 4). min 1 items, max 4 items, default [] |
brand.sources[].kind |
"figma" | "stitch" | "pdf" | "logo" |
yes | Kind of brand source |
brand.sources[].label |
string | yes | What it is, e.g. ‘Figma file’. max length 40 |
brand.sources[].file |
string | yes | Example file name. max length 40 |
brand.sources[].status |
"available" | "coming" |
Shipped today or on the roadmap. default "available" |
|
brand.agentLabel |
string | yes | Window title of the agent session, e.g. ‘Claude Code · ulams CLI · Figma MCP’. max length 60 |
brand.sourcesLabel |
string | yes | Caption over the sources. max length 40 |
brand.alternative |
object | yes | |
brand.alternative.label |
string | yes | The alternative, e.g. ‘Your own front’. max length 40 |
brand.alternative.text |
string | yes | One line. max length 100 |
brand.commands |
array of string | yes | One to three commands. min 1 items, max 3 items, default [] |
brand.tokensLabel |
string | yes | Caption over the extracted tokens. max length 40 |
brand.colors |
array of objects | yes | Five colours in the order primary, secondary, accent, surface, text. min 5 items, max 5 items, default [] |
brand.colors[].name |
string | yes | Role, e.g. Primary. max length 24 |
brand.colors[].value |
string | yes | Hex colour, #RRGGBB. min length 7, max length 7 |
brand.fonts |
array of objects | yes | Two fonts: headings, body. min 2 items, max 2 items, default [] |
brand.fonts[].role |
string | yes | Role, e.g. Headings. max length 24 |
brand.fonts[].name |
string | yes | Font name. max length 40 |
brand.logo |
string | yes | Placeholder wordmark of the example brand. max length 16 |
brand.radius |
integer | yes | Corner radius in px. ≥ 0, ≤ 32 |
site |
object | yes | |
site.host |
string | yes | Example subdomain, e.g. acme.ulams.app. max length 60 |
site.pages |
array of string | yes | Landing, catalogue, admin. min 3 items, max 3 items, default [] |
site.headline |
string | yes | Headline on the example landing. max length 60 |
site.action |
string | yes | Button on the example landing. max length 24 |
content |
object | yes | |
content.sources |
array of objects | yes | Sources, each becomes its own course (1 to 4). min 1 items, max 4 items, default [] |
content.sources[].kind |
"doc" | "pdf" | "git" | "url" |
yes | Kind of content source |
content.sources[].label |
string | yes | Source, e.g. ‘handbook.pdf’. max length 40 |
content.sources[].course |
string | yes | The course built from it. max length 40 |
content.sources[].status |
"available" | "coming" |
Shipped today or on the roadmap. default "available" |
|
content.builderLabel |
string | yes | Caption over the courses. max length 40 |
content.citedLabel |
string | yes | Chip on every course, e.g. ‘cited’. max length 24 |
content.syncLabel |
string | yes | Line about keeping courses in sync. max length 80 |
content.syncStatus |
"available" | "coming" |
Shipped today or on the roadmap. default "available" |
|
dashboard |
object | yes | |
dashboard.kpis |
array of objects | yes | Up to three measures. min 1 items, max 3 items, default [] |
dashboard.kpis[].label |
string | yes | Measure, e.g. Progress. max length 30 |
dashboard.kpis[].value |
integer | yes | Bar fill, 0 to 100 (illustrative). ≥ 0, ≤ 100 |
dashboard.quiz |
object | yes | |
dashboard.quiz.label |
string | yes | Panel title. max length 40 |
dashboard.quiz.bars |
array of objects | yes | Up to four bars. min 1 items, max 4 items, default [] |
dashboard.quiz.bars[].label |
string | yes | Quiz or module. max length 30 |
dashboard.quiz.bars[].value |
integer | yes | Bar fill, 0 to 100. ≥ 0, ≤ 100 |
dashboard.atRisk |
object | yes | |
dashboard.atRisk.label |
string | yes | Panel title. max length 40 |
dashboard.atRisk.learners |
array of objects | yes | Up to three learners. min 1 items, max 3 items, default [] |
dashboard.atRisk.learners[].name |
string | yes | Anonymous label, e.g. ‘Learner A’. max length 24 |
dashboard.atRisk.learners[].reason |
string | yes | Why, in a few words. max length 60 |
dashboard.confusing |
object | yes | |
dashboard.confusing.label |
string | yes | Panel title. max length 40 |
dashboard.confusing.sections |
array of objects | yes | Up to three sections. min 1 items, max 3 items, default [] |
dashboard.confusing.sections[].title |
string | yes | Section. max length 40 |
dashboard.confusing.sections[].level |
integer | yes | How confusing, 1 to 5. ≥ 1, ≤ 5 |
ComparisonTable
Section titled “ComparisonTable”Feature comparison of products in columns, features in rows. Every competitor cell must come from a sourced data file (value, note, source URL, checked date); list the sources and the ‘as of’ date under the table. Neutral values only.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
caption |
string | yes | Table caption read by screen readers (what is compared). max length 160 |
asOf |
string | When the facts were checked, e.g. ‘October 2026’. max length 40 | |
columns |
array of objects | Products, in column order (omit when groups is set). min 0 items, max 8 items, default [] |
|
columns[].label |
string | yes | Product name, plain text (no logos). max length 40 |
columns[].note |
string | Small line under the name, e.g. ‘hosted SaaS’. max length 40 | |
columns[].highlight |
boolean | The column of our own product. default false |
|
rows |
array of objects | Features (omit when groups is set). min 0 items, max 24 items, default [] |
|
rows[].label |
string | yes | Feature. max length 60 |
rows[].help |
string | What the row means. max length 160 | |
rows[].cells |
array of objects | yes | One cell per column, same order. max 8 items, default [] |
rows[].cells[].value |
string | yes | Yes, No, Partial, Via plugin, Paid add-on, Not documented, Coming, or a short phrase. max length 60 |
rows[].cells[].note |
string | Short neutral note. max length 120 | |
rows[].cells[].kind |
string | Value kind of a translated cell: yes, no, partial, plugin, paid, unknown or coming. max length 16 | |
groups |
array of objects | Several tables behind a CSS-only segmented control (no JavaScript); each group lists its own products and features. Omit for a single table (columns and rows). min 0 items, max 4 items, default [] |
|
groups[].label |
string | yes | Name of the group, shown on the segmented control. max length 40 |
groups[].caption |
string | Table caption for this group. max length 160 | |
groups[].columns |
array of objects | yes | Products, in column order. min 2 items, max 8 items, default [] |
groups[].columns[].label |
string | yes | Product name, plain text (no logos). max length 40 |
groups[].columns[].note |
string | Small line under the name, e.g. ‘hosted SaaS’. max length 40 | |
groups[].columns[].highlight |
boolean | The column of our own product. default false |
|
groups[].rows |
array of objects | Features (omit when sections is set). min 0 items, max 40 items, default [] |
|
groups[].rows[].label |
string | yes | Feature. max length 60 |
groups[].rows[].help |
string | What the row means. max length 160 | |
groups[].rows[].cells |
array of objects | yes | One cell per column, same order. max 8 items, default [] |
groups[].rows[].cells[].value |
string | yes | Yes, No, Partial, Via plugin, Paid add-on, Not documented, Coming, or a short phrase. max length 60 |
groups[].rows[].cells[].note |
string | Short neutral note. max length 120 | |
groups[].rows[].cells[].kind |
string | Value kind of a translated cell: yes, no, partial, plugin, paid, unknown or coming. max length 16 | |
groups[].sections |
array of objects | Rows grouped under header rows (each section is its own tbody with a rowgroup header). min 0 items, max 8 items, default [] |
|
groups[].sections[].label |
string | yes | Section heading shown as a header row, e.g. ‘Developer & headless’. max length 60 |
groups[].sections[].rows |
array of objects | yes | Features in this section. min 1 items, max 24 items, default [] |
groups[].sections[].rows[].label |
string | yes | Feature. max length 60 |
groups[].sections[].rows[].help |
string | What the row means. max length 160 | |
groups[].sections[].rows[].cells |
array of objects | yes | One cell per column, same order. max 8 items, default [] |
groups[].sections[].rows[].cells[].value |
string | yes | Yes, No, Partial, Via plugin, Paid add-on, Not documented, Coming, or a short phrase. max length 60 |
groups[].sections[].rows[].cells[].note |
string | Short neutral note. max length 120 | |
groups[].sections[].rows[].cells[].kind |
string | Value kind of a translated cell: yes, no, partial, plugin, paid, unknown or coming. max length 16 | |
sources |
array of objects | Sources for the cells. max 400 items, default [] |
|
sources[].label |
string | yes | What the source supports, e.g. ‘Moodle: SCORM, H5P’. max length 300 |
sources[].href |
string (href) | yes | Source URL. max length 2048 |
sources[].checked |
string | Date checked. max length 20 | |
note |
string | Small print under the table. max length 300 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
A strip of short labels (standards, integrations); each marked available or coming.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
items |
array of objects | yes | Chips. min 1 items, max 16 items, default [] |
items[].label |
string | yes | Label. max length 40 |
items[].note |
string | Small note. max length 60 | |
items[].status |
"available" | "coming" |
Shipped today or on the roadmap. default "available" |
|
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Course components
Section titled “Course components”Syllabus
Section titled “Syllabus”Course program, laid out as a contents page, a timeline, a mission path, orbits or an atlas. folio = magazine table of contents with roman numerals; timeline = horizontal modules with week labels; missions = winding adventure path; orbits = modules on concentric rings (a list on phones); atlas = atlas table of contents with chapter numbers.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"folio" | "timeline" | "missions" | "orbits" | "atlas" |
Layout. default "folio" |
|
id |
string | Anchor id for in-page links. max length 40, default "syllabus" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
lessons |
array of objects | yes | Lessons in order. min 1 items, max 60 items, default [] |
lessons[].id |
integer | Lesson id from the API. ≥ 0 | |
lessons[].title |
string | yes | Lesson / chapter / mission title. max length 160 |
lessons[].kicker |
string | Short label above the title. max length 80 | |
lessons[].summary |
string | One sentence. max length 400 | |
lessons[].minutes |
integer | Total duration in minutes. ≥ 0 | |
lessons[].formats |
array of string | Formats inside, in order of first appearance. max 60 items, default [] |
|
lessons[].topics |
array of objects | Topics. max 60 items, default [] |
|
lessons[].topics[].id |
integer | Topic id from the API. ≥ 0 | |
lessons[].topics[].title |
string | yes | Topic title. max length 160 |
lessons[].topics[].format |
"video" | "audio" | "reading" | "image" | "pdf" | "embed" | "interactive" | "scorm" | "tracked" | "quiz" | "project" |
Learning format of a topic | |
lessons[].topics[].minutes |
integer | Duration in minutes. ≥ 0 | |
lessons[].topics[].preview |
boolean | Free preview without an account. default false |
|
lessons[].topics[].href |
string (href) | Topic link (lesson player). max length 2048 | |
lessons[].topics[].status |
"open" | "done" | "current" | "locked" |
Learner status. default "open" |
|
lessons[].href |
string (href) | Link to the lesson. max length 2048 | |
showTopics |
boolean | List topics under each lesson. default true |
|
totalLabel |
string | Summary label, e.g. ‘6 chapters · 18 topics’. max length 80 | |
cta |
object | A link or call to action | |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
CourseHeader
Section titled “CourseHeader”Top of a course page: title, subtitle, facts, tutors, poster and the start button.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
variant |
"editorial" | "console" | "adventure" |
Layout. default "editorial" |
|
eyebrow |
string | Small label above the title. max length 80 | |
title |
string | yes | Course title. max length 160 |
subtitle |
string | Subtitle. max length 200 | |
summary |
string | Summary. max length 600 | |
facts |
array of objects | Facts (level, length, language…). max 6 items, default [] |
|
facts[].label |
string | yes | Label. max length 40 |
facts[].value |
string | yes | Value. max length 60 |
facts[].note |
string | Small note. max length 80 | |
image |
object | An image with explicit size (prevents layout shift) | |
image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
tutors |
array of objects | Tutors. max 4 items, default [] |
|
tutors[].name |
string | yes | Full name. max length 80 |
tutors[].role |
string | Role or title. max length 80 | |
tutors[].place |
string | Place. max length 80 | |
tutors[].bio |
string | Short bio. max length 600 | |
tutors[].image |
object | An image with explicit size (prevents layout shift) | |
tutors[].image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
tutors[].image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
tutors[].image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
tutors[].image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
primaryCta |
object | A link or call to action | |
primaryCta.label |
string | yes | Visible text. max length 80 |
primaryCta.href |
string (href) | yes | Target URL. max length 2048 |
secondaryCta |
object | A link or call to action | |
secondaryCta.label |
string | yes | Visible text. max length 80 |
secondaryCta.href |
string (href) | yes | Target URL. max length 2048 |
progress |
integer | Learner completion 0–100; omit when unknown. ≥ 0, ≤ 100 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
PurchaseCard
Section titled “PurchaseCard”Sticky side card with the price, what is included and the start button.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
price |
string | Formatted price. max length 20 | |
priceNote |
string | e.g. one-off payment. max length 60 | |
title |
string | Card title. max length 80 | |
items |
array of string | What is included. max 8 items, default [] |
|
cta |
object | yes | A link or call to action |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
note |
string | Small print. max length 200 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Learning components
Section titled “Learning components”Long-form Markdown (GFM tables, block quotes, $$ math $$). Raw HTML is escaped. Use for articles, briefs and descriptions.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
markdown |
string | yes | Markdown source. max length 60000 |
dropCap |
boolean | Editorial drop cap on the first paragraph. default false |
|
size |
"sm" | "md" | "lg" |
Text size. default "md" |
|
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Callout
Section titled “Callout”Highlighted note inside a lesson: a tip, a warning or a key idea.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
tone |
"tip" | "warning" | "key" |
Kind of note. default "tip" |
|
title |
string | Title. max length 120 | |
text |
string | yes | Text. max length 1000 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
Timeline
Section titled “Timeline”Ordered sequence of events or stages (history, a process over time, a project plan). Use for anything where the order or the dates matter; use Steps for a short how-to on a landing page.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "timeline" |
|
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
items |
array of objects | yes | Entries in order, earliest first. min 2 items, max 20 items, default [] |
items[].label |
string | yes | When: a date, period or stage name. max length 40 |
items[].title |
string | yes | What happened or happens. max length 100 |
items[].text |
string | One or two sentences of detail. max length 400 | |
items[].status |
"done" | "current" | "upcoming" |
Where the learner is on the line; omit for a purely historical timeline |
FlipCards
Section titled “FlipCards”Self-test cards: the learner reads the front (a term or question), thinks, then reveals the back (the definition or answer). Use for vocabulary, definitions and quick recall; not for graded questions.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "cards" |
|
title |
string | Section title. max length 160 | |
intro |
string | One or two sentences under the title. max length 600 | |
cards |
array of objects | yes | Cards. min 1 items, max 24 items, default [] |
cards[].front |
string | yes | Term or question. max length 200 |
cards[].back |
string | yes | Definition or answer. max length 600 |
CodeBlock
Section titled “CodeBlock”A code or command listing with a copy button. Plain text with the language named; no syntax colouring and no execution. Put prose around it, not inside it.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "code" |
|
title |
string | File name or short title shown above the code. max length 120 | |
language |
string | Language name, e.g. sql, python, bash, json. max length 24, default "text" |
|
code |
string | yes | The code, exactly as it is to be copied. max length 8000 |
caption |
string | One sentence under the listing. max length 300 | |
lineNumbers |
boolean | Show line numbers. default false |
PracticeActivity
Section titled “PracticeActivity”Scaffolded practice container (required for any practice in a layout): an intro, a toolbox of allowed resources, and 1-6 challenges of rising level (1 guided, 2 supported, 3 independent). Each challenge may offer hints in tiers (nudge, then pointer, then near_solution), answer options that each explain why, and a worked solution that stays hidden until the learner has made an attempt.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
id |
string | Anchor id. max length 40, default "practice" |
|
title |
string | Section title. max length 160 | |
intro |
string | yes | What the learner will practise and why, in one or two sentences. max length 800 |
toolbox |
array of objects | yes | Resources the learner may use (formulas, glossary, earlier lesson); at least one. min 1 items, max 8 items, default [] |
toolbox[].label |
string | yes | Resource or tool. max length 80 |
toolbox[].text |
string | When and how to use it. max length 300 | |
challenges |
array of objects | yes | Challenges in rising level. min 1 items, max 6 items, default [] |
challenges[].id |
string | yes | Stable challenge id, unique in this activity. max length 40 |
challenges[].level |
integer | yes | 1 = guided, 2 = supported, 3 = independent. ≥ 1, ≤ 3 |
challenges[].prompt |
string | yes | The task. max length 800 |
challenges[].hints |
array of objects | Hints, revealed one at a time in tier order. max 3 items, default [] |
|
challenges[].hints[].tier |
"nudge" | "pointer" | "near_solution" |
yes | nudge = a question to think about; pointer = where to look; near_solution = almost the answer |
challenges[].hints[].text |
string | yes | The hint. max length 400 |
challenges[].options |
array of objects | Answer options; leave empty for an open task the learner marks as tried. max 6 items, default [] |
|
challenges[].options[].label |
string | yes | Answer option. max length 300 |
challenges[].options[].correct |
boolean | Whether this option is right. default false |
|
challenges[].options[].feedback |
string | yes | Why this option is right or wrong. max length 500 |
challenges[].workedSolution |
string | yes | Full worked solution; shown only after the learner has made an attempt. max length 2000 |
Figure
Section titled “Figure”Image with caption, click to zoom.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
image |
object | yes | An image with explicit size (prevents layout shift) |
image.src |
string (href) | yes | Image URL (local /images/… or the tenant storage). max length 2048 |
image.alt |
string | yes | Text alternative; empty string only for decorative images. max length 300 |
image.width |
integer | yes | Intrinsic width in px. ≥ 1 |
image.height |
integer | yes | Intrinsic height in px. ≥ 1 |
caption |
string | Caption. max length 300 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
VideoPlayer
Section titled “VideoPlayer”Video with poster, chapters and transcript. HLS streams load a player only when played.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | Video URL (.mp4 or .m3u8). max length 2048 |
poster |
string (href) | Poster image URL. max length 2048 | |
width |
integer | Width in px. ≥ 1, default 1280 |
|
height |
integer | Height in px. ≥ 1, default 720 |
|
title |
string | yes | Accessible title. max length 160 |
chapters |
array of objects | Chapters. max 40 items, default [] |
|
chapters[].time |
integer | yes | Start in seconds. ≥ 0 |
chapters[].title |
string | yes | Chapter. max length 120 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
AudioPlayer
Section titled “AudioPlayer”Audio (podcast, recording) with an accessible native player.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | Audio URL. max length 2048 |
title |
string | yes | Title. max length 160 |
seconds |
integer | Length in seconds. ≥ 0 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
PdfViewer
Section titled “PdfViewer”Embedded PDF with open and download links.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | PDF URL. max length 2048 |
title |
string | yes | Title. max length 160 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
External media by URL (YouTube, Vimeo); other URLs become a link card.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
url |
string (href) | yes | Media URL. max length 2048 |
title |
string | yes | Title. max length 160 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
H5PFrame
Section titled “H5PFrame”Interactive H5P content from the H5P service, framed. Reports completion to progress.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
apiUrl |
string (href) | yes | Tenant API origin (the H5P service is under /h5p). max length 2048 |
contentId |
integer | yes | H5P content id. ≥ 0 |
title |
string | yes | Title. max length 160 |
topicId |
integer | Topic id for progress. ≥ 0 | |
courseId |
integer | Course id for progress. ≥ 0 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
PackageFrame
Section titled “PackageFrame”A packaged activity (SCORM) in a frame, with a link to open it full screen.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | Player URL. max length 2048 |
title |
string | yes | Title. max length 160 |
height |
integer | Frame height px. ≥ 0, default 640 |
|
isolated |
boolean | Third-party package on the tenant content origin: sandboxed frame, no full-screen link (the URL carries a one-off token). default false |
|
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
LiaScriptLesson
Section titled “LiaScriptLesson”A LiaScript course (Markdown with quizzes, code and slides) played in a sandboxed frame on the tenant content origin; it completes itself at the last section.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | Player URL on the content origin (from POST /api/liascript/launches/{topic}). max length 2048 |
title |
string | yes | Title. max length 160 |
sections |
integer | Number of sections. ≥ 1 | |
height |
integer | Frame height px. ≥ 0, default 720 |
|
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
InteractiveLesson
Section titled “InteractiveLesson”An author-uploaded interactive package (3D scene, map, simulation) in a sandboxed frame on the tenant content origin, inline or as the background of the page, with steps, a text version and the licence. Progress goes through the learner session.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
src |
string (href) | yes | Entry file on the content origin (from POST /api/interactive/launches/{topic}). max length 2048 |
title |
string | yes | Title. max length 160 |
topicId |
integer | Topic id for the events call (omitted in a preview: nothing is tracked). ≥ 0 | |
courseId |
integer | Course id. ≥ 0 | |
display |
"inline" | "background" |
Inline in the page, or the background of the page with the text over it. default "inline" |
|
height |
integer | Frame height px (inline only). ≥ 240, ≤ 2000, default 640 |
|
startStep |
string | First step of the range this topic plays. max length 64 | |
endStep |
string | Last step of the range this topic plays. max length 64 | |
steps |
array of objects | yes | Steps with their text alternatives and posters. min 1 items, max 200 items, default [] |
steps[].id |
string | yes | Step id. max length 64 |
steps[].title |
string | yes | Step title. max length 255 |
steps[].text |
string | yes | Text alternative of the step. max length 4000 |
steps[].poster |
string (href) | Poster image of the step. max length 2048 | |
text |
string | The lesson’s own explanation (Markdown). max length 20000 | |
requires |
array of string | Capabilities the package needs. max 5 items, default [] |
|
reducedMotionSupported |
boolean | The package handles reduced motion itself. default false |
|
locale |
string | Language of the texts. max length 16, default "en" |
|
licence |
string | SPDX licence id. max length 64 | |
attribution |
string | Attribution line. max length 1000 | |
sourceUrl |
string (href) | Source code or origin of the package. max length 2048 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
ActivityCard
Section titled “ActivityCard”Launch card for an activity that runs outside the page (cmi5 tracked activity, project hand-in).
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
kind |
"tracked" | "project" | "locked" |
Kind of activity. default "tracked" |
|
title |
string | yes | Title. max length 160 |
text |
string | What happens. max length 600 | |
steps |
array of string | Checklist. max 8 items, default [] |
|
cta |
object | A link or call to action | |
cta.label |
string | yes | Visible text. max length 80 |
cta.href |
string (href) | yes | Target URL. max length 2048 |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
QuizRunner
Section titled “QuizRunner”GIFT quiz through the quiz-attempts API: one question at a time (8 question types), timer, score and review.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
quizId |
integer | yes | topic_gift_quiz id. ≥ 1 |
title |
string | yes | Quiz title. max length 160 |
intro |
string | Intro text. max length 1000 | |
maxAttempts |
integer | Attempts allowed (0 = unlimited). ≥ 0 | |
minutes |
integer | Time limit in minutes (0 = none). ≥ 0 | |
passScore |
integer | Points needed to pass. ≥ 0 | |
courseId |
integer | Course id for progress. ≥ 0 | |
topicId |
integer | Topic id for progress. ≥ 0 | |
finishHref |
string (href) | Where ‘Continue’ goes after the result. max length 2048 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
UpdateNotice
Section titled “UpdateNotice”Notice on a lesson that changed after the learner completed or started it: the date, what changed (the author’s note) and a ‘Mark as reviewed’ button. Filled by the app from the learner’s own notices; it never changes progress. Authors do not place it.
interactive (ships a web component) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
noticeId |
integer | Id of the learner notice; without it there is no ‘Mark as reviewed’ button. ≥ 1 | |
started |
boolean | The learner started the lesson but had not completed it. default false |
|
date |
string (date-time) | ISO 8601 date of the update. max length 40 | |
message |
string | What changed (plain text, written by the course author). max length 500 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
ReattemptNotice
Section titled “ReattemptNotice”Notice on a quiz where one question was corrected: the previous score stays on record and the learner may retake the quiz once more. It stays until the quiz is retaken. Filled by the app; authors do not place it.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
quizHref |
string (href) | Where the quiz is: an in-page anchor on the quiz topic, or the topic link elsewhere. max length 2048 | |
linkLabel |
string | Label of the link to the quiz. max length 80, default "Go to the quiz" |
|
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
PendingUpdateNotice
Section titled “PendingUpdateNotice”Opt-in marker on a lesson whose source changed and whose update is under review (‘The source of this lesson changed on {date}; an update is under review’). Shown only when the course turned it on. Filled by the app; authors do not place it.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
since |
string (date-time) | ISO 8601 date the source changed. max length 40 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |
CourseUpdates
Section titled “CourseUpdates”Summary on the course page of what changed for a returning learner: lessons updated since they completed them, retired lessons, new lessons since they finished, and lessons whose update is under review. Each entry names its status in words. Filled by the app; authors do not place it.
static (no JS) · no children
| Prop | Type | Required | Notes |
|---|---|---|---|
title |
string | Heading. max length 120, default "What changed in this course" |
|
updated |
array of objects | Lessons updated since the learner completed them. max 60 items, default [] |
|
updated[].title |
string | yes | Lesson title. max length 200 |
updated[].href |
string (href) | yes | Lesson link. max length 2048 |
updated[].date |
string (date-time) | ISO 8601 date. max length 40 | |
retired |
array of objects | Lessons removed from the course that the learner had completed. max 60 items, default [] |
|
retired[].title |
string | yes | Lesson title. max length 200 |
retired[].date |
string (date-time) | ISO 8601 date. max length 40 | |
extended |
array of objects | Lessons added after the learner finished the course. max 60 items, default [] |
|
extended[].title |
string | yes | Lesson title. max length 200 |
extended[].href |
string (href) | yes | Lesson link. max length 2048 |
pending |
array of objects | Lessons whose source changed and whose update is under review. max 60 items, default [] |
|
pending[].title |
string | yes | Lesson title. max length 200 |
pending[].href |
string (href) | yes | Lesson link. max length 2048 |
pending[].since |
string (date-time) | ISO 8601 date. max length 40 | |
id |
string | Anchor id for in-page links (letters, digits, dashes). max length 40 |