Element Contract v1 — themes are UI kits

A Mozaik theme is three things (ADR 0031): its own TSX implementation of this contract (a *kit*), its variables, and its page skeletons. Sections are platform-owned and compose only these elements, so content never lives in a theme and every extension works with every theme. FULL kits implement the 24 required elements in TSX (export const kit = {…} satisfies Kit); SKIN themes ship CSS + variables + skeletons over a parent kit (extends). All theme CSS targets the DOM anatomy below with attribute selectors only — classes are never a contract.

Machine-readable: /schemas/kit-contract.json · theme manifest schema /schemas/theme.schema.json · fingerprint kitContractHash in GET /v1/meta.

DOM anatomy

Root: data-mz-el="<element>", one data-<axis> per variant axis (responsive values add data-<axis>-md / -lg), data-state="a b". Parts: data-mz-part="<part>". Sections: data-mz-section, data-mz-slot. Island hooks (data-mz-*) pass through untouched and are never selectable in theme CSS.

elementdata-mz-elpartsaxesstates
Sectionsectionhead bodydata-surface = background surface surface-alt primary accent inverse<br>data-spacing = none compact normal spacious<br>data-width = narrow normal fullbleed
Containercontainerdata-width = narrow normal full
Stackstackdata-direction = column row<br>data-gap = none xs s m l xl<br>data-align = start center end stretch<br>data-justify = start center end betweenwrap
Gridgriddata-cols = 1 2 3 4 5 6<br>data-gap = none xs s m l xl
Boxboxdata-surface = background surface surface-alt primary accent inverse<br>data-padding = none xs s m l xl<br>data-radius = none control card media pillborder shadow
Headingheadingdata-size = xs s m l xl 2xl<br>data-tone = default muted inverse<br>data-align = start center end
Texttextdata-size = xs s m l<br>data-weight = normal medium bold<br>data-tone = default brand accent neutral danger success sale muted inverse<br>data-align = start center end<br>data-lines = 1 2 3
Proseprosedata-width = narrow normal<br>data-align = start center end
Buttonbuttonlabel icondata-variant = primary secondary ghost link<br>data-tone = brand accent neutral danger<br>data-size = s m ldisabled loading full pressed
IconButtonicon-buttonicondata-size = s m l<br>data-tone = brand accent neutral dangerdisabled expanded
Linklinkdata-tone = default muted inverse<br>data-underline = always hover noneexternal current
Iconicondata-size = s m l
NavMenunav-menulist item link sub toggledata-orientation = horizontal verticalcurrent open
Imageimagedata-fit = cover contain<br>data-ratio = auto 1:1 4:5 4:3 3:2 16:9<br>data-radius = none mediapriority
Gallerygallerymain thumbs thumb dotsdata-layout = thumbs-below thumbs-side stacked carousel
Pricepricenow comparedata-size = s m l<br>data-align = start center endsale
Badgebadgedata-tone = neutral sale new info success danger
ProductCardproduct-cardmedia badges body title price soldoutdata-layout = vertical horizontal<br>data-title = below overlayunavailable
Quantityquantitydec input incdata-size = s m ldisabled
ChoiceGroupchoice-grouplegend option labeldata-variant = chips list
Drawerdrawerscrim panel head close body titledata-side = start end bottomopen closed
Fieldfieldlabel control hint errorinvalid required
Inputinputdata-size = s m linvalid disabled
Selectselectdata-size = s m linvalid disabled
Split *(optional)*splita bdata-ratio = 1:1 1:2 2:1<br>data-align-y = start center end<br>data-gap = none xs s m l xlreverse
Placeholder *(optional)*placeholderdata-ratio = auto 1:1 4:5 4:3 3:2 16:9
CollectionCard *(optional)*collection-cardmedia title countdata-variant = card tile circle
Breadcrumbs *(optional)*breadcrumbsitem link current
Textarea *(optional)*textareainvalid disabled
Checkbox *(optional)*checkboxbox labelchecked invalid disabled
Accordion *(optional)*accordionitem trigger panelopen
KeyValueList *(optional)*key-value-listrow key valueemphasis
Divider *(optional)*dividerdata-spacing = none xs s m l xl
Logo *(optional)*logotext imagedata-size = s m l
Notice *(optional)*noticeicon title body dismissdata-tone = info success warning dangerdismissible
Tabs *(optional)*tabslist tab panelselected
Dialog *(optional)*dialogscrim panel head close body titleopen closed
Pagination *(optional)*paginationprev next pagecurrent disabled
Table *(optional)*tablehead row cell
Video *(optional)*videoposter play
Marquee *(optional)*marqueetrack itemdata-speed = slow normal
Countdown *(optional)*countdownunit value labeldone

Icons (29, every FULL kit ships all): cart menu close search chevron-down chevron-up chevron-left chevron-right arrow-right user check star truck shield return whatsapp phone mail pin heart minus plus info warning error external card box headset.

Breakpoints

min-width only: sm = 480 px · md = 768 px · lg = 1024 px. Theme CSS may use no other widths.

Protected chrome

Platform-composed, never kit-implemented, pinned in base.css with !important (which no theme/skin/owner CSS may use): consent-banner consent-text consent-accept consent-reject identity-block identity-row identity-key identity-value builder-overlay. The KVKK consent banner and the 6563 identity block cannot be hidden or weakened by CSS.

Core tokens (Layer 0)

Platform ids every theme resolves; the owner floor is always editable in the builder: color.primary color.accent color.background color.text font.heading font.body font.baseSize radius.control radius.card radius.media shadow layout.sectionSpacing layout.containerMax. All ids: color.background color.surface color.surfaceAlt color.text color.textMuted color.primary color.onPrimary color.accent color.onAccent color.border color.sale color.success color.danger color.ring color.overlay font.heading font.body font.baseSize font.scale layout.containerMax layout.sectionSpacing layout.gutter radius.control radius.card radius.media shadow button.style button.radius motion. Theme variables (Layer 1, variables.json, ≤40) are emitted as --mzt-*.

Storefront zones

Extensions contribute kit-trees (JSON element trees) into closed zones rendered by platform sections, placed by the store owner: header.utility header.below home.top home.bottom product.gallery.after product.below-buybox product.after-description product.bottom collection.before-grid collection.after-grid cart.top cart.bottom footer.above page.top page.bottom.

Limits

Generated from the live platform registries at build time — reference pages cannot go stale. Markdown variant: /reference/kit-contract.md