THE PAINTER MODEL (how color works)
Color is computed, not picked. You never write a hex value. Instead:
- --hue (0–360) sets the base hue for a subtree. --hue-shift nudges it relative to context; --hue-lock pins it absolutely regardless of what's inherited (used by components and graphs that must stay a fixed color).
- --bg is an ABSOLUTE surface position on a −1…+1 walk through three theme anchors: −1 = neutral floor, 0 = paper, +1 = full chroma. Setting --bg on any element repaints its surface (the universal :where(*) rule re-derives the internal --_bg from each element's own --bg).
- --lift is a RELATIVE surface: this element's surface, N above the host it sits on. Use --lift for "slightly raised card on whatever's behind it"; use --bg for an absolute surface.
- --fg is the INK. Sign selects neutral vs chromatic ink; magnitude sets intensity. --fg: -1 = full neutral ink (near-black on light). --fg: 0.85 = high-chroma ink toward the current hue (this is how colored numbers get their vivid green/red). Small negative values (−0.5…−0.6) = quiet/muted ink.
- --type is a size STEP on the type scale; it also drives weight — and it INHERITS (canon since gf-68): set it on a container and the subtree follows; the scale is absolute, so steps never compound. Type IS spacing (lh/em everywhere), so one step re-rhythms text AND gaps AND control heights (--_control-h is type-derived). COMPONENTS never re-type their own elements — only a USAGE site nudges, only through the knob.
Registered properties (@property — typed/animatable): --bg, --fg, --hue-shift, --lift, --gap, --type, --_sem-ink, --row-width. Everything else is a plain custom property.
- --focus and --border are the derived token PAIR every surface computes: --border is the quiet edge, --focus the vibrant one (focus rings, the .Card voice, active outlines). Read them (border: 1px solid var(--border)); never redefine them.
Publisher contract: a region or .bg element paints via background-color: var(--_bg); --surf: var(--_bg); --surf-bg: var(--bg). You rarely write this — regions and .card do it for you. If you set --bg on a custom element and want it painted, add .bg or let a pg-* region rule do it.