Reference

Layout components

section, columns, grid, box, connector, divider, timeline, steps, progress_bar, empty_state

section

Grouping with a heading

A titled block of nested components. Use it to organize long pages into scannable chunks. eyebrow + heading optional. Nested components: can hold any components. Add align: center | right to align the eyebrow, heading, and text content within the section.

Anchors. When heading is set, the rendered <section> gets an auto-slugged id (lowercase, hyphens, punctuation and emoji stripped), so deep-links like /guide.html#platform-health just work. Set id: stable-name to lock the anchor even if the heading wording changes. Same behavior applies to header.

Example section

Platform health

Uptime
99.9%
Errors
0.02%
Latency p95
140ms

Everything above lives inside this section.

- type: section
  eyebrow: Example section
  heading: Platform health
  components:
    - type: stat_grid
      stats: [...]
    - type: markdown
      body: "Everything above lives inside this section."
columns

Multi-column row

Distribute components into equal-width columns. Each column is itself a list of components.

Default - columns stretch at the grid level, contents sit at natural height:

Left

Arbitrary components live inside each column.

Center

Even widths, responsive collapse on narrow screens. One more line here so heights diverge.

Right

Great for comparison layouts. Extra line here. And another.

equal_heights: true - children grow to fill their column so all three look balanced:

Left

Arbitrary components live inside each column.

Center

Even widths, responsive collapse on narrow screens. One more line here so heights diverge.

Right

Great for comparison layouts. Extra line here. And another.

- type: columns
  equal_heights: true    # default false
  columns:
    - - type: callout
        variant: info
        title: Left
        body: Left content
    - - type: callout
        variant: success
        title: Center
        body: Center content
grid

Explicit-placement grid

A CSS grid where each child says where it sits. columns is required, rows and gap optional. Children are { col, row, colspan, rowspan, component } with 1-based col/row. Leave col/row off to auto-flow in order. Cells size from the container, so a wide grid never pushes text off the page.

Validation errors on two children claiming the same cell, on a child placed past columns/rows, and on grids nested more than 3 deep. Any component can be a child, including another grid or a box.

Spans all three columns

col: 1, colspan: 3

Auto

First free cell.

Auto

Next free cell.

Auto

Last one.

- type: grid
  columns: 3
  gap: 12
  children:
    - col: 1
      colspan: 3
      component: { type: box, title: Spans all three, body: "..." }
    - component: { type: box, title: Auto, body: First free cell. }
box

Bordered panel with a title row

title on the left, uppercase tag on the right, markdown body below, and optional nested components. Needs at least one of body or components. color picks a semantic accent, hex overrides it with an exact color, border: dashed marks a grouping band. Nest a grid inside a box to get a bordered band of cells.

Semantic accentRepeatable

color: teal. Bold and italic render, so a dimmer trailing note is one underscore away.

Exact accentModel-driven

hex: "#7a3f8a". Border, tag, and fill tint all derive from the one hex.

A bandNested
One

Inner cell.

Two

Inner cell.

Three

Inner cell.

- type: box
  title: A band
  tag: Nested
  hex: "#7a3f8a"
  border: dashed
  components:
    - type: grid
      columns: 3
      children:
        - component: { type: box, title: One, body: Inner cell. }
connector

Arrow between grid rows

A cell, not an edge. Fills whatever grid cell it sits in with a line and an arrowhead, direction: down (default) or right. An optional label sits on the line with the page background behind it. color or hex recolor the line. Give it its own short grid row between two boxes.

Scanner

Finds candidates.

candidate findings
Investigation

Decides what is real.

- type: grid
  columns: 1
  children:
    - component: { type: box, title: Scanner, body: Finds candidates. }
    - component: { type: connector, label: candidate findings }
    - component: { type: box, title: Investigation, body: Decides what is real. }
timeline

Horizontal phase tracker

A horizontal row of phases with status indicators. Each item is completed, active, or upcoming. No interaction - purely visual progress.

Planning
Configuration
Optimization
Ongoing
- type: timeline
  items:
    - name: Planning
      status: completed    # completed | active | upcoming
    - name: Configuration
      status: completed
    - name: Optimization
      status: active
    - name: Ongoing
      status: upcoming
event_timeline

Vertical event history with severity filter

Vertical chronology with date, severity badge, and optional source/link per event. Each event collapses into a <details> body when a summary is provided. With show_filter_toggle: true a Major-only / All toggle appears at the top - useful for noisy histories where the reader wants the big picture first.

  1. majorgranola
    Weekly sync - Jira asset model confirmed

    Working session booked Tuesday 3 PM CT. Two automation rules: create-new + append-to-existing.

  2. minorlinear
    ANSYS-322 → Done
  3. majorportal
    First production run - 76.5% noise reduction

    2,316 investigations across the EKS cluster. High-severity findings dropped from 3,000 to 222.

  4. infocalendar
    Cadence moved to Thursdays at 1 PM CT
  5. minorslack
    GitHub app installed for the org
- type: event_timeline
  default_filter: major     # major | all (default: all)
  show_filter_toggle: true  # default: false
  events:
    - date: 2026-04-27
      severity: major       # major | minor | info (default: minor)
      title: "Weekly sync - Jira asset model confirmed"
      summary: |
        Working session booked Tuesday 3 PM CT.
      source: granola
      link: https://example.com/notes
    - date: 2026-04-27
      severity: minor
      title: "ANSYS-322 → Done"
      source: linear
      link: https://example.com/issue
tree

Nested status tree

Recursive nested list with per-node status (completed / active / blocked / upcoming / default). Each node renders a status glyph + label, an optional inline note, and any number of children. The optional filter toggle lets the reader cut the view to Incomplete only (hides completed nodes) or Blocked only (shows blocked nodes plus their ancestor chain so the path-to-root keeps context).

  • Phase 1 - Planning
    • Identify stakeholders
    • Determine deployment method (CFN or Terraform)
    • Identify scanner integrations
  • Phase 2 - Initial Configuration
    • Generate External ID
    • Deploy Maze stackWaiting on production change-window approval
    • Connect vulnerability scanner
    • Add initial admin users
  • Phase 3 - Review and Validate
- type: tree
  default_filter: all          # all (default) | incomplete | blocked
  show_filter_toggle: true     # default: false
  nodes:
    - label: "Phase 1 - Planning"
      status: completed       # default | completed | active | blocked | upcoming
      children:
        - label: Identify stakeholders
          status: completed
        - label: Deploy Maze stack
          status: blocked
          note: "Waiting on change-window approval"
priority_queue

Priority queue

Renders a grouped list of items sorted by urgency, horizon, owner, or status. Each item carries optional due and original_due dates. When a date slips (due after original_due), the row shows the original date as context.

group_by controls bucketing: urgency (default) splits into Overdue / This week / Next two weeks / Later / No date. horizon collapses to Now / Next / Later. none renders a flat list (agenda mode). owner and status group by those fields.

Items with status: completed are pulled out of their normal group and collected into a Done section at the bottom, collapsed by default. This keeps historical items visible without crowding active work.

Reuses TreeStatus for item status and SemColor for tag colors.

Deployment tracker
OVERDUE2
Deploy remaining stacksJonathan
Terraform approach agreed. Not started since.
CohereBlocks coverage
Jun 20
Finalize SSO configurationNathan
Forge
Jul 28
- type: priority_queue
  title: Deployment tracker
  group_by: urgency          # urgency | horizon | owner | status | none
  show_dates: true           # default true
  show_counts: true          # default true
  items:
    - label: Deploy remaining stacks
      detail: Terraform approach agreed.
      due: "2026-06-20"
      original_due: "2026-06-20"
      owner: Jonathan
      status: default          # reuses TreeStatus
      href: https://example.com/issue/123
      tags:
        - label: Cohere
          color: teal          # SemColor
        - label: Blocks coverage
          color: red
          emphasis: true
venn

Two- or three-set venn (inline SVG)

Native inline SVG - no charting library. One to three sets; per-set color flows through the same color: field as cards/badges. Optional overlaps: adds intersection labels at the centroid of the involved circles. Labels auto-shrink (13px down to 9px) and break onto up to three lines when they would overflow their region, so INSPECTOR (8,726) stays inside its circle. With two or more sets a toggle in the top-right flips between the diagram and a matrix table: sets as rows and columns, totals parsed from NAME (count) labels on the green diagonal, pairwise overlaps in yellow, and a teal All 3 row for the triple overlap. default_view: table opens on the matrix.

Two-set
FrontendBackendAPIs
Three-set
EngProductDesignSpecsUX bugsMockupsRoadmap
Scanner coverage (opens on the matrix)
INSPECTORWIZQUALYS
INSPECTOR8,7264121,893
WIZ412908203
QUALYS1,8932033,241
All 387
- type: venn
  title: "Scanner coverage"
  default_view: venn    # venn | table - toggle in the corner flips either way
  sets:
    - label: "INSPECTOR (8,726)"   # "NAME (count)" feeds the matrix diagonal
      color: teal       # default | green | yellow | red | teal
    - label: "WIZ (908)"
      color: green
  overlaps:
    - sets: [0, 1]      # indices into sets[]
      label: "412"
steps

Numbered or bulleted steps

Ordered list of cards with title + optional detail. Numbered by default; set numbered: false for bullets.

  1. 1
    Install the binary
    Build from source with cargo build --release.
  2. 2
    Create a site directory
    Any directory of .yaml files - kazam walks it recursively.
  3. 3
    Run dev mode
    kazam dev ./my-site watches and live-reloads at localhost:3000.
- type: steps
  numbered: true   # default; false for bullets
  items:
    - title: Install the binary
      detail: Build from source with cargo build --release.
    - title: Create a site directory
      detail: Any directory of .yaml files.
    - title: Run dev mode
      detail: kazam dev ./my-site
empty_state

Zero-data placeholder

For pages or sections that have nothing to show yet. Icon, title, description, optional CTA. Any bundled lucide icon name works in the icon: field.

No customers yet

Add your first customer to see them here with health badges, deployment guides, and meeting agendas.

Add customer

All caught up

Zero open issues in this portfolio.

- type: empty_state
  title: No customers yet
  body: Add your first customer to see them here.
  icon: inbox                 # any bundled lucide icon
  action:
    label: Add customer
    href: /customers/new
Next up

Navigation components thread pages together - breadcrumbs on deep pages, button groups for primary CTAs.