Colour
Four palettes that do four different jobs. A gem means a MEDIUM, an aura means a STATE, a TLD color means a DOMAIN, a body color means a BODY — and none of them is a site's accent.
Colour
The B-Gem palette
A colour here means a medium. Ruby is video; fire opal is voice. The order is the Metta Light descent — session start at ruby, session end at diamond.
This is a media-type map, not a site palette. Using a gem as a site accent is only correct where the gem is that product's medium.
There are four palettes, and the other three are below. A gem means a medium; an aura stop means a rate; a rainbow hue means a domain; a body color means a body. Seven, seven, six and five. The hues rhyme because a colour wheel is small — the meanings do not, and no two of them may ever be presented as one system.
Colour · in motion
The Metta Light
The gem order above is not a list — it is a
descent. A session starts at ruby and
ends at diamond, and the whole API is one number: the
app sets --t from 0 to 1, and everything
downstream reads --metta and never learns
there was a number.
No numerals, no totals, no streaks, no
ranks.
The light carries the whole signal.
--t is an input, never a readout —
rendering it as “42%” puts metering back
into a surface built to have none. The readout
beside the slider exists because this page documents
the mechanism; a product surface shows the light and
nothing else.
This is not an animated custom property, and
that is the point.
The obvious build — and the one the original
reference for this uses — registers
--metta with @property and
interpolates it with @keyframes. This
repo has already been burned by exactly that: Chrome
does not reliably re-rasterise an element for an
animated custom property it inherits, and
the failure is invisible to
getComputedStyle. Inheritance is not
incidental here — it is the design — so
that build is broken in the one configuration the
feature requires.
So the ramp computes a plain value instead of
animating one: six color-mix() steps,
each weighted by a clamp() window off
--t. No registration, no keyframes, no
animation engine, no JS ticker. There is no enforcer
to forget.
The chain lives on a class, not
:root.
Custom properties inherit their computed
value, so a chain declared on :root
resolves once against root's own --t
and every descendant inherits the finished colour —
the ramp goes dead and throws no error. The element
that sets --t must be the element that
carries the chain. Put .metta on the
session container.
Breath, not heartbeat. The lamp's swell
is a slow symmetrical breath with no claim attached. The
heartbeat in motion.css is a
Proof-of-Humanity signal with a placement rule. Never
give the lamp .beating, and never give a
mark the breath. Under reduced motion the breath stops
and the colour does not — the descent is the
session's real state, and freezing it would misreport
where the sitter actually is.
Colour · second palette
The aura ramp
A colour here means a position — how fast a person's gratitude is circulating, measured as crossings per month and bucketed server-side. Not a medium, not a domain. A rate.
Extracted, not invented. These seven were typed by hand in three files of the shipping Phase-1 app, and all three still agreed when they were lifted — the pre-drift state this package exists to end, caught before it diverged. Nothing here was chosen; it was moved.
Seven stops here and seven gems above are different sets. This ramp carries indigo and ends at violet; the gems carry no indigo and end at the unrefracted diamond. The shared count is a coincidence.
And this ramp is discrete. A person sits in exactly one stop and never between two, which is why seven flat tokens are the right shape. The Metta Light — the gem order named above — is the continuous one, driven by a single scalar. Do not build this one as a gradient.
Two of these hexes collide with tokens
declared elsewhere in the layer:
--color-aura-red is byte-identical to
--danger, and
--color-aura-violet to
--color-violet-sey. Coincidence, not
kinship — three names, three meanings. Do not alias
them, or re-tuning one will silently move the others.
Colour · third palette
The six-TLD rainbow
A colour here means a domain — one HeartBank® TLD, its product class, and the heart-idiom it was named for. The six were assigned one at a time, per domain; that they compose a complete rainbow was found afterwards, and that is the whole reason the allusion is earned rather than contrived.
| TLD | Hue | Product class | Heart-idiom |
|---|
No token is pinned, and none is faked. The corpus fixes six color words; no stylesheet fixes a hex. (Since v1.7.0 the candidate light values are the source hues of HeartBank's codes — see the body palette below — but a code is not a theme, and no token follows.) So the marks above are painted with the CSS keyword that spells the doctrine's word — a rendering of the name, never a value — which is why they look untuned beside the measured gems. They are supposed to.
Do not add six tokens to make that go
away.
Nothing consumes them: not one of the four sites
vendoring this layer is a
heartbank.{TLD}. Pin them when the
first one needs them, and measure contrast then.
Why marks and not chips. These six hues are one-for-one with the six saturated gems. Two chip grids of the same six hues on one page read as one system no matter what the caption says, so the carrier changes with the meaning: a medium is a chip, a domain is a mark. Colour is a property of the emblem here, which is also what the doctrine says an aura is.
This palette is body-scoped, in a way the other two are not — it belongs to HeartBank®, one body of five. It is documented here because this is where the four palettes are told apart, not because the institution's colour system is one body's domain map.
Color · fourth palette
The body palette
A color here means a body — which of the five owns a code or a seal. HeartBank® is the one body organized by domains, so its color is its domain's: an H3 code names its domain, never "H3". The others name themselves: Silicon Wat's orange robe, THonly's sky blue, Factory 333's crimson moon, and Miss Aquarius's clear sparkle.
These are the final printed colors. Every code below is drawn by the recipe with the owner a product passes, at the green's darkness, so all of them print and scan alike — and every ink printed under a code is read from the recipe, never typed. Scan any one: it opens this section.
| Body | Name | Color | Prints as | Why |
|---|
Codes and seals only. A body color is never a site's accent, never a theme, never a medium, a rate or a domain — except that HeartBank's body color is its domain's. A bank's code (KHQR) is never a B-QR and stays plain. Pink stays reserved.
Belonging, never authenticity. Anyone
can print any color; the scan is what authenticates.
Three pairs print alike and that was accepted —
.us and Factory 333,
.me and Silicon Wat,
.org and Silicon Wat — because
HeartBank's six hues span the wheel. A code's owner is
what it opens or who redeems it,
never the app that shows it.
A product cannot pick its color. It
passes an owner, and the recipe refuses
"H3" alone, an unknown owner, or an owner with a
hue.
The rule
A site's accent is derived, never picked
Each site takes the gem whose media type
is that product's medium. Everything else — the
whole alpha family — then falls out of one
color-mix() chain.
| Site | Accent | Because |
|---|
Two values cannot derive, and that is the
honest limit.
--accent-ink is decided by contrast:
Fire Opal on white is 3.4:1 and fails, Sapphire on
white is 7.0:1 and passes, so one site takes
near-black ink on its fill and another takes white.
No formula picks correctly. On a light ground
--accent-soft often needs pinning too.
The goal was "a fifth site is five declarations"; it
is nine.
Do not build a "pass a gem, get a theme" API. The true shape is a gem plus two measured overrides.