Theme specification

@skirbi/pinta

2 min

Please note that this spec defines the pinta-* namespace. The current implementation uses semtic-* in order to unify the concepts of <semtic-grid> and the likes. But with the introduction of dibuho it feels wrong. As everything is part of Skirbi, it will be renamed to skirbi-*. This shall be done in the next few weeks. Expect breakage at every call site that uses [semtic-theme].

The rename excludes helpers such as <semtic-grid>, <semtic-flex>, or <semtic-stack>. The reason being: these could become actual components, which means they belong in @skirbi/semtic and are currently elements, which makes them more natural fitting in the semtic- namespace.

Goals

  • Avoid collisions with HTML standard attributes and other libraries.
  • Keep markup readable and self-descriptive.
  • Make theming composable via CSS cascade (no JS required).
  • Keep the contract stable: attributes are API.

Namespace

All pinta “system” attributes MUST be prefixed with:

  • pinta-

Theming attributes

pinta-theme

Purpose: Select a brand/skin context.

Type: string (theme name)

Where: Any element; recommended on <html> or <body>.

Contract: A theme sets CSS variables (tokens) that cascade to descendants.

Example:

html
<html pinta-theme="client1">
css
[pinta-theme="client1"] {
  --brand-primary-base: #00d4ff;
  --page-bg: #0b0b0c;
}

pinta-theme-tone

Purpose: Select a color role (brand/accent/status) for a component.

Type: enum string

Where: Any element that wants a tone.

Required side effects (CSS variables it MUST define):

  • --tone-light
  • --tone-base
  • --tone-dark
  • --on-tone

Default tone values (v1):

Brand:

  • primary
  • secondary
  • tertiary
  • quaternary

Accents:

  • accent-primary
  • accent-secondary

Status:

  • info
  • success
  • warn
  • error

Optional:

  • neutral

pinta-theme-variant

Purpose: Select a presentation style (how the tone is rendered).

Type: enum string

Where: Any element that wants a themed presentation.

Consumes:

  • --tone-light
  • --tone-base
  • --tone-dark
  • --on-tone

Default variant values (v1):

  • solid
  • outline
  • gradient

Theme tokens

pinta themes MUST expose these foundational tokens at minimum:

Foundation:

  • --page-bg
  • --page-fg
  • --surface-bg
  • --surface-border
  • --text-muted
  • --on-dark
  • --on-light

Brand palette (4 × light/base/dark):

  • --brand-primary-light|base|dark
  • --brand-secondary-light|base|dark
  • --brand-tertiary-light|base|dark
  • --brand-quaternary-light|base|dark

Accent aliases (2 × light/base/dark):

  • --accent-primary-light|base|dark
  • --accent-secondary-light|base|dark

Status palette (4 × light/base/dark):

  • --status-info-light|base|dark
  • --status-success-light|base|dark
  • --status-warn-light|base|dark
  • --status-error-light|base|dark

Cascading rules

  1. Theme context cascades.
  2. Tone and variant are orthogonal.
  3. No JS required.

Forward compatibility

Future pinta system attributes MUST follow the same namespace rule, e.g.:

  • pinta-density="compact|comfortable"
  • pinta-radius="none|soft|round"
  • pinta-motion="reduced|full"

Layout primitives (shipped helpers)

The default theme also ships small, classless layout helpers. These are not required for theming, but are provided as a convenience.

Tags:

  • <semtic-grid> uses pinta-columns, pinta-columns-md, pinta-columns-lg
  • <semtic-flex> uses pinta-direction, pinta-justify, pinta-align, pinta-wrap, and pinta-gap
  • <semtic-stack> uses pinta-gap

Shared attribute:

  • pinta-gap="0..6" sets --pinta-gap used as the gap: value.

Breakpoints (default theme):

  • md: @media (min-width: 48rem)
  • lg: @media (min-width: 64rem)