Lumen's markup is a fixed tag vocabulary; its CSS is a narrow subset that maps one-to-one onto the same attributes; its scripting is Rhai plus a fixed set of host builtins. These tables condense the reference — jump to tags, CSS, or Rhai.
Unknown tags are a parse error. Every visible tag also accepts the shared layout and visual attributes below.
| Tag | What it is | Notable attributes |
|---|---|---|
<root> | The single document root; vertical flex filling the window. | skin, frameless, class |
<column> / <row> | Flex containers — stack children vertically / horizontally. | gap, align, justify |
<spacer> | Empty grow box; pushes siblings apart. Defaults to grow="1". | — |
<tile> | Generic styled box leaf — a paint target for backgrounds, gradients, shadows. | bg, radius, shadow |
<div> | Block leaf with no default decoration; a class-styled box. | class |
<scroll> | Clipped scrolling container with layout isolation. | scroll, sensitivity, inertia |
<overlay> | Floats out of flow; covers its positioned ancestor. Modals, dropdowns, tooltips. | position, inset |
<title-bar> | Draggable region for frameless windows. | drag |
| Tag | What it is | Notable attributes |
|---|---|---|
<label> | Text leaf, fully shaped and BiDi-aware. | text, font-size, wrap, max-lines, bind-text |
<input> / <textarea> | Editable text field — single-line / multiline. | placeholder, bind-text, required, pattern |
<button> | Focusable tile with click dispatch. Inner text is the label. | id, text, class |
<toggle> | Boolean two-state control. | bind-checked, checked |
<slider> | Drag value across a range (default 0..1). | min, max, value, bind-value |
<image> | Raster or SVG image; loaded once and cached. | src, fit, opacity |
<dropdown> + <option> | Select widget: header button + options panel. | bind-value, placeholder / value, label |
<date-picker> / <time-picker> | Validated text inputs with format hints. | bind-value, placeholder |
| Tag | What it is | Notable attributes |
|---|---|---|
<for> | Reactive iteration over a signal-backed array; {field} placeholders fill per item. | each, key, virtualized, row-height |
<if> | Conditional subtree — mounts when a signal is truthy. | signal, mode, eq |
<dialog> | Modal overlay with focus trap and Esc-to-close. | open |
<tabs> + <tab> | Tabbed container; switching preserves each tab's descendant state. | bind-value / name, label |
<tooltip> | Hover-delay popup wrapping exactly one child. | text, delay |
<menu> / <menubar> + <menuitem> | Popup, context, and native OS menu bars. | id / label, accel |
<template> + <slot> | Reusable markup body with default attributes and id namespacing. | name, custom defaults |
<script> | Attaches Rhai — inline, or src="…rhai". Not a layout node. | src |
| Family | Attributes |
|---|---|
| Layout box | width height min-* max-* aspect-ratio padding margin gap grow align justify position inset overflow |
| Visuals | bg radius shadow opacity |
| Text | text text-color font-size text-align wrap max-lines |
| Interaction | hover-bg press-bg focus-outline tab-index draggable drop |
| Bindings | bind-text bind-checked bind-value |
24), or use 24px / 50%. Edges (padding, margin, inset) take 1, 2, or 4 numbers, CSS-shorthand style. Colors are #rrggbb or #rrggbbaa. A bg value may also be a linear-gradient, radial-gradient, or conic-gradient.Most properties share a name with their markup attribute. There is no specificity beyond source order, inline attributes always win, and a handful of properties are CSS-only.
| Property | Group | Value |
|---|---|---|
width height min/max-* | Layout | Length (24, 50%). |
aspect-ratio | Layout | Number (w/h ratio). |
padding margin inset | Layout | Edges (1, 2, or 4 numbers). |
gap grow | Layout | Number. |
align | Layout | start · end · center · stretch. |
justify | Layout | start · end · center · between · around · evenly. |
position | Layout | relative · absolute. |
overflow overflow-x/y | Layout | visible · hidden · scroll. |
bg | Visuals | Color or gradient. |
radius | Visuals | Number (px). |
text-color | Visuals | Color. |
opacity | Visuals | 0..1. |
shadow | Visuals | Single shadow: [inset] ox oy blur #color. |
box-shadow | Visuals · CSS-only | Comma-separated shadow stack. |
font-size | Text | Number (px). |
wrap | Text | none · word · glyph. |
max-lines | Text | Integer ≥ 0 (ellipsis truncation). |
text-align | Text | start · center · end. |
hover-bg press-bg | Interaction | Color. Same as :hover / :active { bg: … }. |
focus-outline | Interaction | <width-px> <#color>. |
fit | Image | fill · cover · contain · none · scale-down. |
transition | Animation · CSS-only | <property> <duration> [easing], comma-separated. |
:root { --bg: #0d0d14; --fg: #e6e6e6; --accent: #7aa2f7; } .theme-light { --bg: #f6f6f9; --fg: #0d0d14; } root { bg: var(--bg); text-color: var(--fg); }
.card { opacity: 0.5; transition: opacity 200ms ease-out; } .card.visible { opacity: 1.0; } /* a class flip tweens the value */ /* over the declared duration */
tile.card.primary) are supported, along with descendant and child combinators, structural pseudos, and :hover / :focus / :active. A @media (prefers-color-scheme) query switches token blocks for dark and light mode. Rules resolve by source order with later declarations winning at equal weight. Transitions currently animate opacity; other property names parse but are dropped for now.Scripts get Rhai's standard library plus a fixed set of host builtins — the bridge to the running app. Lifecycle callbacks are functions you write that the runtime calls by convention.
| Function | Group | Effect |
|---|---|---|
signal(name, default) | State | Handle to a scalar signal with .get() / .set(v) / .value. |
signal_array(name) | State | Reactive array backing <for> — .set .push .len .get(i). |
derive(name, deps, fn) | State | Computed signal; re-runs when any dep changes. |
set_text(id, text) | Mutate | Replace an element's text content. |
set_class(id, classes) | Mutate | Replace an element's classes; re-applies CSS. |
set_root_class(classes) | Mutate | Same, targeting <root> — drives theme switches. |
set_src(id, path) | Mutate | Swap an <image>'s asset at runtime. |
on(event, id, fn) | Routing | Per-id handler; skips the global dispatcher for that pair. |
local_id(source, suffix) | Routing | Sibling id within the same template instance. |
set_timeout(name, ms) | Timers | One-shot; fires on_timer(name). |
set_interval(name, ms) · cancel_timer(name) | Timers | Repeating timer and its cancel. |
fetch(url, tag) | HTTP | Off-thread GET; result lands in on_fetch(tag, body). |
parse_json(body) | HTTP | JSON string → Rhai map / array / scalar. |
pick_file(tag) · pick_files · pick_folder · save_file | Dialogs | Native file dialogs; results arrive via callbacks. |
notify(title, body) | Shell | OS notification (fire-and-forget). |
register_hotkey(name, accel) | Shell | Global accelerator; fires on_hotkey(name). |
tray_icon(id, path, tooltip) | Shell | System tray icon (macOS / Windows). |
open_menu(id) · close_menu(id) | Shell | Flip a <menu> popup open / closed. |
print(...) | Debug | Captured into the lumenc diagnostic stream. |
| Callback | When |
|---|---|
on_start() | Once, after the layout tree spawns. Register handlers and seed signals. |
on_tick(dt) | Every frame; dt is seconds since the last tick. |
on_click(id) · on_double_click · on_long_press | Global pointer dispatch (per-id on(...) handlers take priority). |
on_text_input(id, text) | Text committed on an input or textarea. |
on_toggle(id, checked) · on_slider(id, value) | Control state changes. |
on_file_dropped(id, path) | File dropped on a drop="true" target. |
on_fetch(tag, body) · on_fetch_error(tag, msg) | Result of a fetch(...) call. |
on_file_picked · on_files_picked · on_folder_picked | File-dialog results (empty path = cancelled). |
on_timer(name) · on_hotkey(name) · on_menu(id) · on_tray(id) | Timer, hotkey, menu, and tray events. |