Color
Color, theme, or theory.
SKILL.md.agents/skills/thorbis-color/
Follow the skill selection policy and shared Linear baseline. For mobile-app work, the Native contract (D-025) is required.
Scope and required context
Linear baseline: This skill specializes one part of Thorbis; it does not introduce another product grammar. Preserve quiet chrome, one dominant work region, structured density, stable action neighborhoods, contextual surfaces, visible keyboard paths, durable state, and role-adaptive mobile. Use the Thorbis × Linear pattern matrix only when the owning pattern is ambiguous.
Mobile platform gate (D-025): Every mobile-app task requires the Native contract, HIG-001–HIG-022, and relevant live Apple Human Interface Guidelines (opens in a new tab). Apple HIG governs iOS/iPadOS behavior over conflicting web/Linear rules. Cite rule IDs and topic URLs in specifications, component contracts, PRs, and release evidence. Android retains host conventions. Normative requirements and exceptions have one owner: Native.
Dark greys and cream type. Electric blue is the brand. Status is ours. Extras are guests.
This is its own skill. Drop it at .agents/skills/color.md. Pick this file. Do not average it with the others.
Live: https://design.thorbis.com/skills/color
Rules is what we ship. Research is the homework. `DESIGN.md` is the constitution. `AGENTS.md` is the contract.
This skill holds: D-003 (no hex in product code), D-015 (theme is a preference, not a hue picker), D-018 (a fill is one mix; no solid colored side rail), D-020 (outline at rest, fill when this is the place), APCA verification, OKLCH, light as a retune.
Homework: Andrew Somers / APCA, perceptual contrast; WCAG 2 is an independent floor. Kaelig Deloumeau-Prigent, a token is a decision, not a hex. Paco Coursey, the theme is a class on the root; one hatch; no flash. Grammar, not a second palette.
thorbis-color-SKILL.md
First
- Name the token. If you cannot, you are sneaking a value.
- Name the job: surface, type, pointer, status, or guest.
- APCA on this theme, then the other theme.
- If it is Showcase, watch it in motion. A still that works can fail when the object moves onto a hotter field.
Do not invent a grey because you did not open this file.
Tokens
DESIGN.md, Surfaces owns the palette and its roles. src/styles.css implements the shared tokens. Use those tokens instead of copying another value table into a feature or skill.
Body is reading text. Marker is a short secondary label, not a paragraph, field explanation, or recovery sentence. Status words can use fg; their mark or surface carries the reserved status hue. Check the resulting pair on its actual surface in both themes.
Light is a retune. Do not invert the dark palette. The sheet still lifts off the canvas, and the well is darker than the sheet. Accent stays.
No hex in JSX. No text-white. If the token is missing, add it at the owner. D-003.
Use
| Token | Use | Never |
|---|---|---|
| accent | Brand, focus ring, the live row | Every heading, a wash, a second blue |
| cream / grey | Type and surfaces | Recolored per page |
| success / danger / info | Copied, failed, info | Olive as success. Accent as info. |
| warning | Alert | Pumpkin as alert |
| extras | Quiet marks: menu icons, places, a bit of fun | A second brand. A status system. Candy. |
A live job can stay grey plus a word. Status is not a rainbow. Overdue and the amount due have to hold |Lc| on a bright windshield, not just in Figma.
Chrome likes soft color. A place mark, a menu icon, a command glyph may carry olive, forest, pumpkin, burnt, or accent mixed down until it sits with those. Phosphor Regular, 16px. The word stays fg or body. Only the mark is tinted. Selected lifts the word, not a wash behind the row. Outline at rest. Fill when this is the place. D-020.
You notice the hue after you read the word. If the icon shouts first, drop chroma. Mix with marker until it recedes.
A fill is one mix. Never a gradient unless someone asked for that wash by name. Never a solid colored border on the leading or trailing edge to mean selected, live, or status. Live is a word, a mark, or accent on the thing. D-018.
Do not grey every icon to look serious. That is a costume of restraint. Do not paint six loud glyphs in a sidebar. That is a costume of delight.
Theme
Default is System. If the OS will not say, fall back to Light.
- Persist the choice (
localStorage). Do not reset it on navigation or a view transition. - Paint
data-themeanddata-resolvedon the root before first paint. theme-colorfollows the resolved canvas.- One hatch on the root. No flash.
- Theme control is an icon. Sun, moon, desktop. Not a segmented “Light Dark System” pill.
- Theme is the color preference they get. Not a hue picker. Not a second brand. D-015.
- A customer portal and an invoice do not wear one person’s theme.
Contrast
DESIGN.md, Color owns the contrast floors and correction rule. Name the actual role: a secondary sentence is still body text. Check the foreground against every surface it can occupy, including tinted status states, hover, and initial paint.
Prefer APCA for perceptual readability, using the actual font size and weight. Verify WCAG text contrast (opens in a new tab) independently; an APCA value alone does not establish WCAG conformance. Keep the word readable when the hue is unavailable. Do not fix a failing pair with saturation, an outline, or a heavier font.
Flip the theme and check the same pair again. Light cream-on-paper and dark cream-on-void are not mirrors. Accent on cream is a different pair than accent on void.
Theory
We work in OKLCH. Lightness, chroma, hue. Not HSL. Not a mood board.
| Axis | Means | In Thorbis |
|---|---|---|
| Lightness | How close to white | Canvas is dark. Sheet is a step up. Type is cream. |
| Chroma | How much color | Greys are near zero. Accent has chroma. Status has chroma. |
| Hue | Which color | Accent is ~264 (electric blue). Cream is ~84 (warm). Body is ~260 (cool). |
Fix contrast on lightness. Never on chroma.
Hue is identity. Chroma is how loud. Lightness is whether you can read it.
Temperature
The product is a warm object on a cool void.
- Cream type (
hue 84.6) is warm. Paper, ink, the sheet in light. - Body grey (
hue 259.8) is cool. Sentences sit off the cream so they recede. - Accent (
hue 264.4) is cool blue. It points. It does not warm the room. - Canvas and panel are achromatic. No hue. The void is not blue.
Warm type on a cool field is the whole trick. Do not warm the canvas to “match” the cream. Do not cool the type to “match” the blue.
Light theme keeps the same story: cream canvas, warm ink, the same blue. It is a retune of lightness, not an invert, not a complementary swap.
Harmony
One family of greys. One accent. Status hues are reserved words, not a rainbow.
| School | What it means | What we do |
|---|---|---|
| Achromatic | Greys only | Canvas, panel, field, marker. The work lives here. |
| Complementary | Opposite hues | Cream (~85) against blue (~264). Type vs pointer. Not a split-complementary kit. |
| Analogous | Neighbors | Do not. We do not add indigo, cyan, and violet next to accent. |
| Triadic | Three equal hues | Do not. Status is not a triad. Success, danger, warning are words with a color, not a scheme. |
| Monochrome | Tints of one hue | The greys. Accent is the exception, used sparingly. |
60 / 30 / 10 is a painting rule. Map it, then go quieter.
| Share | Role | Token |
|---|---|---|
| ~60% | Field they live in | bg |
| ~30% | The work | panel, type, body |
| ~10% or less | The pointer | accent on the live thing only |
If accent is 10% of the screen, nothing is live. A wash is a fail. A blue rail is a fail.
Simultaneous contrast
A color looks different against its neighbor.
- Cream on void reads brighter than cream on panel. Titles sit on the sheet.
- Accent on void shouts. Accent on panel points. Use the second.
- Danger on a red-tinted panel disappears. Keep the panel grey.
- Body grey on cream (light theme) is a different pair than body grey on void. Check both.
Do not “fix” a pair by outlining it. Change lightness.
Meaning
Color is a pointer, then a reserved word, then never decoration.
| Job | Color | Rule |
|---|---|---|
| Brand, focus, selected, the live row | accent | One blue. Not every heading. |
| Copied, ok | success | With the word. |
| Failed, destructive | danger | With the word. The commit stays our shape. |
| Info | info | Not brand. Do not use accent for “FYI.” |
| Alert | warning | Not pumpkin. |
| Fun | olive, forest, pumpkin, burnt | Guests. Quiet marks. Not jobs. Not node types. Not a legend. |
Status is a word first. Open. En route. On site. Color sits with the word. A green blob is not a status.
A live job can stay grey plus a word. That is legal. That is preferred.
Quiet marks
The interface is not monochrome. It is grey, with soft color on the things you scan for.
Places, menus, and command rows: Phosphor Regular, 16px. The mark may carry a hue. The word does not.
| Place | Mark may be | Never |
|---|---|---|
| Jobs | olive, or accent mixed with marker | A blue row |
| Schedule | pumpkin, at extra chroma, 16px only | A calendar fill |
| Inbox | forest | A green blob for unread |
| Books | burnt | A red bookshelves |
| Workflow / Brain | accent mixed down to extra chroma | Neon nodes in the sidebar |
Mix: color-mix(in oklab, var(--color-accent) 45%, var(--color-marker)). If it still shouts, mix more marker.
Lightness sits near marker. Chroma sits with olive (~0.05), not with accent (~0.19). Pumpkin and burnt are the loudest extras; they are legal on a 16px mark and illegal as a row fill.
Selected: the word becomes fg. The mark may stay its hue. Hover is color on the word, gated. No wash.
Do not tint fields, commits, list identity, or body copy. Soft color is chrome, not content.
If you cannot tell Jobs from Schedule without the hue, the words failed. The hue is a courtesy.
Video and Showcase
Same palette. Darker patience.
- The void is
bg. One light on the object. A rim so the sheet reads as a thing. - The product in the shot is the product we ship. Cream type, grey sheet, one blue pointer.
- Do not grade the reel toward teal-and-orange. Do not add a marketing purple.
- Skin, a truck, a shop: keep them honest. Do not cast a blue wash over a crawlspace.
- Cuts stay in the same world. Do not jump from a cream void to a black void between chapters.
- Reduced motion stills use the same crop and the same palette.
A color script is three beats: void, object, pointer. If a fourth hue appears, delete it.
Never
- Blue as every heading
- A third green
- Contrast fixed by saturating
- Theme forgotten when the page changes
- A purple or “Linear indigo” anywhere
- Candy icons. An all-grey menu as a virtue
- A gradient, mesh, aurora, or fade, unless the brief names that exact wash
- A solid colored border on the leading or trailing edge of a row, a card, a quote, a callout, or a sheet
- A second blue
- Complementary orange “to balance the blue”
- Teal-and-orange grade on a product video
- Warming the void
- Status as a rainbow of node types
- A hex picker, a theme store
Audit
- Token named. No hex in product code. D-003
- APCA |Lc| holds on this theme and the other
- Accent is a pointer, not 10% of the screen
- Status is a word plus a reserved hue
- Fill is one mix. No solid colored side rail. D-018
- Marks: outline at rest, fill when current. D-020
- Theme persists. No flash. D-015
- Extras are guests, not a legend
Two failures: do not ship.
Done
Name the token, the pair you checked, and the theme. Name anything you refused: a second blue, a wash, a solid colored side rail.
Applied bookmark research
Reviewed 2026-09-06. These are Thorbis applications and review exercises, not replacements for DESIGN.md, COMPONENTS.md, or the owning skill. Linear remains the operational baseline. External advice that conflicts with the constitution stays out.
These worked examples are not a claim that the product behaviors have been implemented or verified.
Use color to clarify state, not replace it
Owning skill: color.
A borrowed visual trick can weaken contrast or make a state readable only by its color.
Keep semantic roles and Thorbis tokens in charge. Inspect state words, marks, and control edges together in both themes. External suggestions for shadows, smoothing, and image outlines are evidence to evaluate, not a new palette.
Thorbis example: A failed invoice action has an understandable error and a recovery action; it is not merely a red icon. A rounded input retains the real rim required by D-017 rather than losing its boundary on a similar-toned surface.
Verify: Review focus, selected, disabled, pending, and error states in light, dark, and forced-colors conditions. Check contrast and meaning separately from whether the screenshot feels subtle.
Do not import: No second accent, literal source colors, missing control rim, or ornamental gradient and blur imported from a reference.
Evidence: Web Interface Guidelines (opens in a new tab); Details that make interfaces feel better (opens in a new tab); components.build (opens in a new tab). Source access limits.
All skills
The bundle includes every skill. Use Resources to choose the smallest context for a task.