Kampa page format 0.5

Status: 0.5, pre-release. The shape may change before a stable release. page.schema.json beside this file is the shape; this file is what the shape means and what the Kampa check enforces.

A page is a tree of two node kinds: an instance of a component this repository holds (under components/ in the token folder), and a layout node that places its children. There is no free geometry: no coordinates, no sizes in pixels, no colours outside a box.

Kampa writes three files per page in the token folder: pages/<name>.page.json (the document, the one to review), pages/<name>/index.html and pages/<name>/page.css (generated, overwritten on every push). Edit pages in Kampa or in the document, never in the generated files.

1. The document

{ "format": "0.5", "name": "sign-in", "title": "Sign in", "root": { … } }

name is lowercase letters and digits joined by hyphens: the page's directory. title defaults to the name, title-cased. lang is the page's language as a language tag (en, cs, pt-BR), written as <html lang>; it defaults to en, and anything that is not a language tag is E014. Unknown keys are E014.

Every node has an id of the same shape, unique in the page (E014). The id is what the canvas, the code panel and the tools address a node by, and what page.css selects it by ([data-kampa-node="<id>"]).

2. Instances (ruling 2)

{ "id": "submit", "component": "./button.json", "variant": { "variant": "primary" },
  "state": "rest", "slots": { "label": "Sign in" }, "overrides": { "bg": "{color.brand.emphasis}" } }
Key Rule Code
component a component file's $ref as the project stores it E011 when the project holds none
variant non-theme modifier → one of its contexts; a missing axis takes its default; the theme is the page's E015
state rest (the default), or a state the component shows by an attribute (disabled, invalid, checked) on a single-element component. Interaction states are the reader's to cause, never a static page's E015
slots content slot → text. A single-element component has label; a component with parts has one slot per text-bearing leaf part, named for the part. A slot inside a repeated part takes a list, one text per instance E015, E014
overrides a painted, unconditioned slot (bg, title.fg) → a token reference of the slot's type. The override is pinned in every state: page.css writes it in the kampa.page layer, after kampa.components E015; a literal is E009; a wrong type E013

3. Layout nodes (ruling 3)

Kind Keys Tokens
stack direction (column default, row), gap, align, justify, wrap gap: dimension
grid columns: a count 1 to 12, or a list of 1 to 12 whole fractions ([1, 2] → 1fr 2fr), gap gap: dimension
box padding, width, maxWidth, background, border ({ "color", "width" }), radius colour: background, border.color; the rest dimension

Every layout node holds children (it may be empty). Every token key holds a reference {group.token}; a literal is E009, and a reference that does not resolve to a token of the key's type in every mode is E013.

box is the only node that carries a colour, and its background is the background of everything inside it for the gate (§6).

4. Breakpoints (ruling 4)

Breakpoints are the dimension tokens of the breakpoints group. A layout node may carry at: { "md": { … } }: the keys of its kind that change from that width up. at names a breakpoint the group holds, or E012. Colours do not change at a breakpoint (E014), so every instance has one background.

The page root is a size container (kampa-page); each at is emitted as @container kampa-page (min-width: <value>), ascending, so the widest breakpoint that applies wins. A container condition cannot read a custom property, so the condition carries the breakpoint token's resolved value.

5. Emit (ruling 5)

A page emits pages/<name>/index.html and pages/<name>/page.css beside the token folder's tokens.css, base.css and components.css, which index.html links; nothing is inlined, no script, no style attribute. An instance's HTML is what the component emitter writes for that variant and state, with the page's slot text and data-kampa-node. A layout node is a div. page.css holds layout and overrides only, every value a var() of a token tokens.css declares (a miss refuses the push).

6. The gate (ruling 6)

Every pair the component gate grades is graded per instance and theme on the instance's effective background: the innermost box above it whose background paints (alpha exactly 0 is skipped, between 0 and 1 cannot be measured). Outside every box it is the body, which base.css paints color.background.default; without base.css, the component gate's general surfaces, every one. Overrides are applied before grading.

A page passes when it has no format error, no failing pair and no pair nobody could measure. Failures are listed by page path (sign-in/frame/panel/form/submit). A failing page blocks a Kampa push like a failing component, and fails the check in CI.

7. The repository

The page document is the review surface; index.html and page.css are marked generated. A page document changed in the repository since Kampa last agreed with it is drift, read the way a changed component is: Kampa names it before it pushes, and taking the repository's version takes the page. A page removed in Kampa is removed from the repository by the next push, with its two generated files.

8. Codes

Code Meaning
E009 a literal where a token reference belongs (the token check's own code)
E011 an instance names no component the project holds
E012 at names no breakpoint
E013 a reference that does not resolve, in every mode, to a token of the right type
E014 the document's shape: unknown key, wrong kind, duplicate id, bad name
E015 an axis, context, state, slot or override the component does not have