List and detail pages, block sugar, and pinned block ids.

Pages

A page is list, detail or custom. Blocks have a short form for the common cases and a generic form for everything else:

app projects "Projects" {}

entity Project {
  name:           text
  client:         text
  due:            date
  status:         text
  contract_value: money USD
  margin:         number
}

query projects_by_status() = select status, count (*) from Project by status

page projects "Projects" list Project {
  board Project summary [name, client, due] label "In flight" layout board
  list Project columns [name, client, due, status] size 25 search on
  stat "Overdue" = count(Project where due < today)
  chart "By status" from projects_by_status() kind bar
}

page project-detail "Project" detail Project {
  jobs label "Workflow" summary [name, client] updated on
  section "Commercials" {
    field contract_value
    field margin
  }
  related Invoice where project = this columns [number, total, status]
  action "Close out" event close confirm "Close this project?"
  block entity_notes #notes {}
}

The sugar heads are board, list, section, field, related, jobs, action, stat and chart. When a block needs a setting the sugar does not know, write it generically as block <type> #<id> { … } — the two forms compile to the same thing.

Block ids are derived from the page and the block's position, so you do not write them. Pin one with #id when an operator's customisations must survive a reorder.