Language reference

The Mere spec.

Everything the format supports, nothing it doesn't. Version 0.1 — stable.

File structure

A Mere workbook is an HTML document saved with the .mp.html extension. The .mp conveys semantic identity (Mere package); the .html conveys technical format (HTML document). Both are required. The <workbook> element is the root content. Everything lives inside it.

<workbook theme="classic-light">
  <state>   …state declarations…   </state>
  <computed>…computed values…  </computed>
  <actions> …named action blocks… </actions>
  <screen name="home"> …elements… </screen>
  <screen name="detail">  </screen>
</workbook>

The theme attribute is optional (defaults to classic-light). Sections may appear in any order. Only <screen> elements are rendered.

Sigils

Sigils are attribute prefixes that wire elements to state and actions. They replace event handlers, data attributes, and binding frameworks.

Sigil Name Usage Description
@name read <heading @title /> One-way read binding. Element content is updated when state changes. Also works inline in text: <heading>Hello, @name</heading>.
@list list loop <card-list @items> Iterates a list state. Child elements may use @item.field for per-item access.
~name two-way <field ~email /> Bidirectional sync. Input value updates state; state changes update the input.
!name action <button !submit> Invokes a named action on click. Pass arguments with with: !delete with item.id.
? intent <screen ?"Show a summary"> AI compositor annotation. Ignored at runtime; used for generation.

State

Declared in the <state> block. Each value has a name, type, and optional default.

TypeExampleNotes
text <value name="title" type="text" value="Untitled" /> Any string value.
number <value name="count" type="number" value="0" /> Numeric. Compared numerically in where filters.
boolean <value name="active" type="boolean" value="false" /> Toggles. Used with <toggle>.
list <value name="items" type="list" value="[]" /> Array of records. JSON array literal as default.

Persistence

Add persist to save state across sessions using OPFS (localStorage fallback):

<value name="notes" type="list" value="[]" persist />

Computed values

Declared in <computed>. Derived from state. Read-only.

<computed>
  <value name="display-name" from="username" />
</computed>

Actions

Named blocks of statements declared in <actions>. Invoked by ! sigil elements.

Action bodies are plain text — one statement per line inside the <action> element.

StatementSyntaxDescription
set set tab to "inbox" Set a state value to a literal string or another state name.
clear clear draft Reset a state value to its declared default.
go-to go-to detail Navigate to a named screen.
add-to add-to items key1 val1 key2 val2 Append a new record to a list state. Key-value pairs follow the list name. Values may be state names or "quoted literals".
<action name="save-note">
  add-to notes body @draft date "today"
  clear draft
  go-to notes
</action>

<action name="open-message" takes="id">
  set selected-message to messages where id = id
  go-to message-detail
</action>

Use takes to declare parameters. Pass arguments with with: <button !open-message with item.id>.

Element vocabulary

26 semantic elements. No HTML passthrough. Every element has a specific role.

ElementSigilsDescription
screen?A full screen. Entry point for navigation.
header?Top zone of a screen or card.
footer?Bottom zone of a screen.
form?Structural grouping for inputs. No implicit submit.
heading@ ?Primary text — title or name.
subtitle@ ?Secondary text — description or metadata.
paragraph@ ?Body text. Supports multiline content.
timestamp@ ?Date/time display. Formatted relative to now.
badge@ ?Numeric indicator. Hidden when 0 or empty.
avatar@ ?Circular image or initials.
icon?Named icon glyph.
tab-bar~ ?Horizontal tab switcher. Binds to text state via ~.
tab?A tab inside tab-bar. First positional attr is its value.
navigation-bar?Bottom or top navigation bar.
nav-item! ?Navigation action. First positional attr is target screen.
message-list@ ?Renders a list of messages from list state.
card-list@ ?Renders a list of cards from list state.
list@ ?Generic list from list state.
message-card! ?Tappable message row. Use inside message-list.
card! ?Content container with border and padding.
field~ ?Text input. Binds two-way to state via ~.
button! ?Action trigger. Invokes an action via !.
toggle~ ?Boolean switch. Binds two-way via ~.
modal?Full-screen overlay dialog.
toast?Transient notification.
banner?Persistent inline notification strip.

Themes

Set with theme="..." on <workbook>. Themes are personalities, not palette swaps — each changes layout rhythm, typography, borders, and density.

classic-light

Neutral baseline. Clean cards, comfortable spacing, 16px body type. The default.

theme="classic-light"

proton-mail

Purple accent (#6D4AFF), underline tabs, card-per-item lists, 14px base type.

theme="proton-mail"

brutalist

Zero radius, 3px black borders, inverted header, red accent, 900 weight, all-caps labels.

theme="brutalist"

Diagnostic codes

Reported by mere check. All codes are stable — they will not be renumbered.

CodeCategoryDescription
MPD-001structuralWorkbook root element missing or invalid.
MPD-002unknown-elementTag not in the element registry.
MPD-003unknown-identifierSigil references undeclared state or action.
MPD-004syntaxMalformed sigil attribute (bare @ ~ ! with no identifier).
MPD-005type-mismatchBinding to incompatible state type.
MPD-006structuralAction invoked with wrong number of arguments.
MPD-007structuralTwo-way binding target is read-only (computed value).
MPD-008structuralCircular computed value dependency.