…
- Declare a relationship on one side only; the inverse is inferred. After saving, check `domain/overview` for `errors` and `warnings`.
- Objects can be declared in a Story (or Spec) topic with `$object Class:key (field = value, …)`, or written through the API. Writes are checked against the class, and a failed write returns `E_VALIDATION` with a `problems` list naming each bad field.
+- **Computed fields:** `@calc(expr) name: Type` works a field out from the others each time the object is read: `@calc(shares * avgCost) cost: Number`, `@calc(shares * company.price) value: Number` (through a reference), `@calc(if cost > 0 then pl / cost * 100 else 0) plPct: Number`. One expression, no loops; it's never stored and never written (a write that includes it just drops it). A formula that fails (a missing reference, a division by zero) gives `null`. Use them for anything the user would otherwise compute by hand: totals per row, P/L, days since, a status from a date.
- `query` takes an expression over an object's fields: `stage is "Producer" and marketCap > 100000000`, or `"prop-frost" in (properties ?? [])` for a reference list.
…
A card is `icon | title | link | text`: the link is a `/path`, a URL or a `[[Topic]]`; `soon` makes a card that isn't live yet. Save `Home` like any topic (read it first, change only the card block, keep the rest as the user wrote it). With a drafts token the change is a draft like any other.
+## Tables: show data on any page
+
+A ```` ```table ```` fence puts a live table of a class's objects in any topic: a home page, a notes page, a report. Use it whenever the user wants to *see* their data; it's the usual way to give an app its page. One `key: value` per line:
+
+````
+```table
+class: Holding
+columns: company, shares, company.price as Price, value, pl as P/L, plPct as P/L %
+totals: value, pl
+sort: value desc
+color: pl, plPct
+```
+````
+
+- `class` is required. `columns` are fields, or paths through a single reference (`company.price`), each optionally `as` a label; without it, every plain field shows.
+- `totals` adds a sum row under those columns (a total for a field that isn't a column shows as a line under the table). `sort` is a column, `asc` or `desc`. `filter` is an expression, as in `query` (`account is "TFSA"`). `color` makes numbers green above zero and red below. `add: no` hides the **+ Add** button; `title` and `limit` do what they say.
+- The first cell of each row opens the object's edit form and **+ Add** the new-object form; both come back to the page after saving. On a phone each row becomes a card.
+- A mistake (a class or field that doesn't exist) shows as a red note in place of the table: read the page after saving it and fix what it says.
+- For an app: put its table (or tables) at the top of the app's page, then a line on what it is. Use computed fields for the numbers and the table for the view: don't compute in the page.
+
## Files
…