npm package: @skirbi/pinta
Description: Skirbi's theme song
Author: Wesley Schwengle
Latest version: 0.0.2

<!--
SPDX-FileCopyrightText: 2026 Wesley Schwengle <wesleys@opperschaap.net>

SPDX-License-Identifier: MIT
-->

# @skirbi/pinta

> Skirbi's theme song

Pinta is the **token + primitive theme layer** for **semtic**.

- **semtic** gives you structure (custom elements + layout primitives)
- **pinta** gives you design tokens + universal attribute primitives (CSS only)

Pinta follows the **80% rule**:
- The README covers the common path and the primitives most people need.
- The remaining 20% is intentionally not documented here — read `pinta.css`
  (and any generated docs site) if you need edge cases or internals.

Everything is CSS. No runtime. No JS required.

---

## Opt-in

Pinta is **explicit opt-in**. If `[semtic-theme]` is not present, `pinta.css` does nothing.

Apply to the whole page:

    <html semtic-theme>
      ...
    </html>

Or scope it to a subtree:

    <div semtic-theme>
      ...
    </div>

Named themes are allowed:

    <div semtic-theme="foo">
      ...
    </div>

Contract:
- `[semtic-theme]` enables the engine and applies the default theme (pinta).
- `[semtic-theme="name"]` is the same engine + theme overrides (in `@layer pinta-theme`).

## Cascade layers

Pinta fixes layer order so theme authors and downstream consumers can override safely:

    @layer pinta-base, pinta-theme, pinta-components;

Meaning:

- **base**: engine (tokens + primitives + interactions), opt-in gated
- **theme**: pinta defaults + theme author overrides (palette, pointers, knobs)
- **components**: light defaults for semtic elements (`semtic-panel`, `semtic-tile`, layout tags)

Theme authors override knobs in `@layer pinta-theme`.

## Theme mode

Pinta supports:

- `semtic-theme-mode="light"` (default)
- `semtic-theme-mode="dark"`

Example:

    <html semtic-theme semtic-theme-mode="dark">
      ...
    </html>

Mode selects environment defaults (page wash, surface lift, shadows). Palette colors may also be theme-dependent.

---

## Tokens

### Brand palette (BASE slots)

Override these freely:

- `--semtic-primary-base`
- `--semtic-secondary-base`
- `--semtic-tertiary-base`
- `--semtic-quaternary-base`

Pinta derives light/dark variants from these base colors internally.

### Pointers (what drives what)

Pointers decide how the palette influences the overall look:

- `--semtic-page-tone-base` (drives the page wash)
- `--semtic-surface-tone-base` (drives surfaces and borders)

Example: make the page follow your primary color:

    @layer pinta-theme {
      [semtic-theme] {
        --semtic-page-tone-base: var(--semtic-primary-base);
      }
    }

### Status colors (important)

Status colors are semantic defaults:

- `--semtic-info-base`
- `--semtic-success-base` (teal, avoids neon green)
- `--semtic-warn-base` (orange, avoids pale yellow)
- `--semtic-error-base` (deep red)

They are chosen for clarity and colorblind resilience.

You *can* override them, but don’t do it casually.
If you change them: test contrast and colorblind simulations.

---

## Primitives (attributes)

Primitives work on **any element** inside a themed subtree.

Common ones:

- `semtic-pad="0..6"`
- `semtic-gap="0..6"`
- `semtic-border="0..5"`
- `semtic-radius="0..6"`
- `semtic-shadow="1..5"`
- `semtic-shadow-border="1..5"`
- `semtic-bg` (surface background that can tint on hover/selected)
- `semtic-hover`, `semtic-selected`, `semtic-press`, `semtic-disabled`

Example card:

    <article semtic-bg semtic-pad="3" semtic-radius="4" semtic-shadow="2" semtic-hover semtic-press>
      ...
    </article>

### Interaction knobs

Override these in `@layer pinta-theme`:

- `--semtic-hover-ring-size`
- `--semtic-selected-ring-size`
- `--semtic-press-ring-size`
- `--semtic-focus-ring-size`
- `--semtic-transition-duration`
- `--semtic-transform-duration`
- `--semtic-hover-shadow`
- `--semtic-press-shadow`

### Tone and variants

Use:

- `semtic-theme-tone="primary|secondary|tertiary|quaternary|info|success|warn|error"`
- `semtic-theme-variant="solid|outline|gradient"`

Example:

    <button semtic-theme-tone="info" semtic-theme-variant="solid">Info</button>

---

## Typography

Typography is opt-in and driven by knobs:

- `--semtic-font-scale`
- `--semtic-line-height`
- heading scales (`--semtic-h1-scale`, `--semtic-h2-scale`, …)
- `--semtic-prose-gap`

Optional presets exist:

    <div semtic-theme semtic-font-profile="editorial">
      ...
    </div>

Presets are sugar; the variables are the real API.

---

## Layout tags

Pinta ships simple layout tags:

- `<semtic-grid semtic-columns="1..10" semtic-columns-md="..." semtic-gap="...">`
- `<semtic-flex ...>`
- `<semtic-stack ...>`

They’re meant to be boring, predictable, and easy to override.