Toast
A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.
Kit part · Alerts · Notifications
A message let into the surface, with an annunciator: a small lit legend (Note, Done, Check, Fault) beside the words that say what happened.
Seats open in 11 days. Want one email that morning?
Backup failed. The disk is full.
Disk 82% full.
Backup finished at 02:14.
Backups run nightly at 02:00.
Smoke in the loft.
Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.
Aluminium
| Part | Note | Done | Check | Fault |
|---|---|---|---|---|
| Words | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
| Key and × | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
| Focus on × | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
Graphite
| Part | Note | Done | Check | Fault |
|---|---|---|---|---|
| Words | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
| Key and × | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
| Focus on × | Note Backup runs at 02:00. | Done Backup finished. | Check Disk 82% full. | Fault Backup failed. |
| Name | Kind | Values | What it does |
|---|---|---|---|
| .tui-alert | class | on <div> | The message window: a recess in the surface, 9px corners. |
| data-alert | attribute | "info" · "success" · "warning" · "error" | Lights the legend: display white, green, amber or red. Nothing else takes colour. |
| .tui-alert__legend | class | one word | The annunciator: dark glass, the word lit behind it. Note, Done, Check, Fault, or your own single word. |
| data-blink | attribute | on the legend | For a fault that needs someone now. Reduced motion holds it lit. |
| .tui-alert__text | class | on <p> | What happened, then what it means. Put the first sentence in <b>. |
| .tui-alert__actions | class | on <div> | One or two keys: the fix, and perhaps a flat key. |
| .tui-alert--stacked | class | Puts the keys on their own line under the words, for narrow places. | |
| .tui-alert__dismiss · data-alert-dismiss | class · attribute | on a flat icon key | The × key. Needs aria-label and data-tip. |
| role | attribute | "alert" · "status" | “alert” for a fault that appears while someone works; “status” for the rest. None for messages already there on load. |
| --lit | CSS property | set by data-alert | The legend’s light. Read it; data-alert writes it. |
| dismissAlert(alert) | function | kit.mjs | Lets a message go from a script: fade, hide, event, focus onward. |
| tui-alert-dismiss | event | bubbles | Fired on the alert once it is hidden. |
| Enter · Space | keyboard | on × | Dismisses; focus moves to the next focusable thing after the alert. |
<div class="tui-alert" data-alert="error" role="alert">
<span class="tui-alert__legend">Fault</span>
<p class="tui-alert__text"><b>The inverter stopped answering at 14:02.</b>
The house is on the grid until it restarts.</p>
<div class="tui-alert__actions">
<button class="tui-key tui-key--sm">Restart inverter</button>
</div>
<button class="tui-key tui-key--flat tui-key--icon tui-key--sm tui-alert__dismiss"
aria-label="Dismiss" data-tip="Dismiss" data-alert-dismiss>…×…</button>
</div>import '/kit/kit.mjs'; // wires every [data-alert-dismiss]
document.addEventListener('tui-alert-dismiss', (e) => remember(e.target.id));
// From a script:
import { dismissAlert } from '/kit/kit.mjs';
dismissAlert(document.querySelector('#inverter-fault'));Needs kit.css and kit.mjs. How to install the kit.
role="alert" only for a fault that appears while someone is working, so it interrupts; role="status" is read politely.aria-label; the tip repeats it for pointer and keyboard users.The window is the kit’s recess. The annunciator is a 24px strip of display glass (the VFD background, an inset shadow, a faint glare) with the word in Geist Mono lit by --lit and a two-step glow; a radial wash of the same light sits behind it, the way a lamp shows through printed film. data-alert only sets --lit. The dismiss is fifteen lines in alert.mjs, delegated from the document, so alerts added later work too.
The legend lights; the words carry the meaning. A fault says what to do about it, and an alert that needs action never leaves by itself.
5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.
A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.
The only colour in the kit: a lamp that is on. Green is on, amber is waiting, red is recording or failing, blue is linked, white is standing by. Always next to words.

A decision that must be made now: a native dialog with a question, one sentence of consequence, a way back and the act.