Kampa page format 0.5
Status: 0.5, pre-release. The shape may change before a stable release.
page.schema.jsonbeside 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 |