Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7823560
feat(design-system): add selectable plugin color families
tellaho Oct 18, 2026
981b07f
refactor(design-system): align artwork studies with buzz palette
tellaho Oct 18, 2026
b477966
refactor(design-system): align plugin gradients with accent colorways
tellaho Oct 19, 2026
2e1a727
fix(design-system): preserve cross-color gradient transitions
tellaho Oct 19, 2026
b6b987e
fix(design-system): register proposed artwork and reuse accent metadata
tellaho Oct 19, 2026
2217125
Merge origin/main into tho/design-color-families
tellaho Oct 19, 2026
26c9bc5
refactor(design-system): map plugin artwork to existing palette steps
tellaho Oct 19, 2026
f8da596
fix(design-system): place lighter blue above violet in agent artwork
tellaho Oct 19, 2026
56b7f95
fix(design-system): restore distinct colors across plugin gradients
tellaho Oct 19, 2026
58341dd
refactor(design-system): share appearance fills with plugin artwork
tellaho Oct 19, 2026
df7cfc0
refactor(design-system): extract complete appearance palettes
tellaho Oct 19, 2026
a9da486
Merge main into shared appearance palette work
tellaho Oct 19, 2026
c8ea813
test(design-system): retarget contrast mutations to palette owners
tellaho Oct 19, 2026
287c6a7
fix(design-system): guard direct Appearance palette usage
tellaho Oct 19, 2026
10ccbc9
test(design-system): read iris endpoint in the matching mode
tellaho Oct 19, 2026
9a5d288
docs(design-system): explain chartreuse light link owners
tellaho Oct 19, 2026
d1ed53c
Merge main into tho/design-color-families
tellaho Oct 20, 2026
06728e7
refactor(design-system): remove duplicate Appearance ramp viewer
tellaho Oct 20, 2026
253b822
fix(design-system): guard auxiliary palette owners
tellaho Oct 20, 2026
52de5f3
docs(design-system): describe current palette and artwork ownership
tellaho Oct 20, 2026
7fcf9ca
fix(settings): neutralize stale category glyph tints
tellaho Oct 20, 2026
12ff3ff
refactor(design-system): remove unused ramp viewer styles
tellaho Oct 20, 2026
8044bc9
fix(ci): preserve runtime Vitest locations in flake filters
tellaho Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,33 @@ icons, subtitles, disabled states, and required-status text.

Standard Button sizes use the 14px `text-label-sm` role while retaining their
existing minimum heights. The extra-small capsule keeps its caption role.

## Colorways and plugin gradients

Plugin artwork uses existing palette colors, including the complete Appearance
ramps: Bee, Magenta, Iris, Cobalt, Citrus and Mono. Flame and Jade remain
independent artwork palettes. All twelve steps and
existing ink, pressed and link mappings reference explicit palette owners.
Values are extracted unchanged. Mode-specific owners (for example
`--jade-3-light`) remain available independently of the page mode; the resolved
`--jade-3` follows the nearest light/dark scope. This preserves mixed-mode
specimens as well as product Appearance choices. Registry and Color viewer
expose all twelve steps of every named family in Layer 0. No new colors are invented.
Artwork aliases resolve at the page root; their current step-9 endpoints are
identical in both themes. Nested opposite-mode artwork is not a supported preview.

| Category | Top → bottom | Identity |
| --- | --- | --- |
| Communication | cyan 9 → jade 9 | Teal/green, separate from Agents. |
| Agents | blue 9 → iris 9 | Lighter blue over existing violet. |
| Agent tools | purple 9 → magenta 9 | Violet to rose. |
| Developer tools & integrations | orange 9 → flame 9 | Warm ember. |
| People & communities | red 9 → magenta 9 | Scarlet to rose. |
| Productivity | amber 9 → green 9 | Approved yellow-to-green direction retained. |

The proposed registry entries are owned by Settings plugin catalog; their
complete gradients compose palette-backed endpoints. There is no artwork-literal
exception. Existing UI palettes, Appearance preference IDs and semantic roles
are unchanged. The mapping does not preserve the original fixed luminance,
chroma, contrast or 35-degree hue sweep. Inspect real catalog captures in both
themes; artwork and lighting also affect the resulting tiles.
2 changes: 1 addition & 1 deletion scripts/design-system/check-adoption.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const visualProperty =
const controlSelector =
/(?:^|[\s>+~])(?:button|input|textarea|select)(?:[.#][\w-]+|\[[^\]]*\]|:[\w-]+)*$|\.buzz-(?:button|input|textarea|radio|checkbox)\b/;
const palette =
/--(?:neutral|purple|red|green|amber|blue|cyan|orange)-(?:\d+|action-pressed)\b|\b(?:bg|text|border|outline|ring|fill|stroke|shadow|from|via|to)-(?:neutral|purple|red|green|amber|blue|cyan|orange)-\d+\b/g;
/--(?:neutral|purple|red|green|amber|blue|cyan|orange|gray|chartreuse|bee|citrus|mono|flame|magenta|iris|cobalt|jade)-(?:\d+|action-pressed|contrast|ink|pressed|link(?:-hover)?)\b|\b(?:bg|text|border|outline|ring|fill|stroke|shadow|from|via|to)-(?:neutral|purple|red|green|amber|blue|cyan|orange|gray|chartreuse|bee|citrus|mono|flame|magenta|iris|cobalt|jade)-\d+\b/g;

export function adoptionFindings(file, source) {
const code = source
Expand Down
60 changes: 60 additions & 0 deletions scripts/design-system/check-color.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,27 @@ auditLayers();
*/
function auditLayers() {
const css = readFileSync(TOKENS_FILE, "utf8");
// Artwork endpoints follow the same palette ownership as other aliases.
// Complete plugin gradients may compose their own two palette-backed endpoints.
for (const match of css.matchAll(/(--art-[a-z0-9-]+):\s*([^;]+);/g)) {
const [declaration, name, value] = match;
const alias =
/^var\(--(?:(?:amber|blue|cyan|green|orange|purple|red)-(?:[1-9]|1[0-2])|(?:bee|citrus|mono|flame|magenta|iris|cobalt|jade)-(?:[1-9]|1[0-2]))\)$/.test(
value.trim(),
);
const category = /^--art-plugin-(.+)-gradient$/.exec(name)?.[1];
const composition =
category &&
value.replace(/\s+/g, " ").trim() ===
`linear-gradient( to bottom in oklch, var(--art-plugin-${category}-start), var(--art-plugin-${category}-end) )`;
if (!alias && !composition)
failures.push({
at: "styles/tokens.css",
found: declaration,
why: "Artwork must reference an existing family step or compose its own palette-backed endpoints.",
});
}

const rel = "styles/tokens.css";

/** Every `:root` or `.dark` block, concatenated. One per layer, so several. */
Expand Down Expand Up @@ -303,6 +324,45 @@ function auditLayers() {
}
}

// Appearance palettes retain explicit mode owners and scoped ramp bindings.
for (const family of [
"bee",
"citrus",
"mono",
"flame",
"magenta",
"iris",
"cobalt",
"jade",
]) {
for (let step = 1; step <= 12; step += 1) {
for (const [mode, block] of Object.entries(modes)) {
const owner = `--${family}-${step}-${mode}`;
if (
!/^#[0-9a-f]{6}$/i.test(
read(css.slice(0, css.indexOf("LAYER 1 — FAMILIES")), owner) ?? "",
) ||
read(block, `--${family}-${step}`) !== `var(${owner})`
) {
failures.push({
at: `${rel} (${mode})`,
found: owner,
why: "Each Appearance step needs a literal mode owner and the matching scoped binding.",
});
}
}
}
}
for (const match of css.matchAll(
/--accent-[a-z0-9-]+:\s*(#[0-9a-f]{3,8})/g,
)) {
failures.push({
at: rel,
found: match[0],
why: "Accent mappings must reference named palette owners, not literals.",
});
}

// Semantic names describe purpose even when both themes choose the same step.
// Require every new semantic role to declare both modes and reference a token.
const roles = [
Expand Down
15 changes: 5 additions & 10 deletions scripts/flake-check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,10 @@ export function testBodies(source, lang, lines) {
return [...bodies.values()].sort((a, b) => a.start - b.start);
}

// Vitest `file:line` filters for the selected tests. Vitest lists an
// `it.each([…])(` at its second parenthesis but filters by the call's first
// line, so a listed line outside it finds no test.
export const vitestLines = (lines, bodies) =>
lines.map((line) => bodies.find((body) => body.line === line).start);
// Runtime collection and execution use the same Vitest call-site locations.
// Keep those locations: a parameterized call's AST start may not be runnable.
export const vitestFilters = (file, selection) =>
selection.whole ? [file] : selection.lines.map((line) => `${file}:${line}`);

// The calls owning every line of a range, or undefined once a line lies
// outside them all.
Expand Down Expand Up @@ -297,11 +296,7 @@ function select(base = "HEAD^1", head = "HEAD") {
let entries;
let note;
if (runner === "vitest") {
entries = selection.whole
? [file]
: vitestLines(selection.lines, bodies).map(
(line) => `${file}:${line}`,
);
entries = vitestFilters(file, selection);
note = selection.whole
? `whole file (${selection.reason})`
: `${selection.lines.length} changed test(s)`;
Expand Down
9 changes: 5 additions & 4 deletions src/app/Settings.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,14 @@
}
}

/* Shared category gradients preserve their original cross-color transitions. */
/* Category tiles use shared palette pairs. Neutral glyphs on the teal, ember
and yellow/green tiles avoid tints inherited from the former gradients. */
.pluginIcon[data-branded][data-category="communication"] {
--plugin-icon-gradient: var(--art-plugin-communication-gradient);
}

.pluginIcon[data-branded][data-category="communication"] img {
filter: hue-rotate(-12deg) saturate(0.8);
filter: grayscale(1);
}

.pluginIcon[data-branded][data-category="agents"] {
Expand All @@ -330,7 +331,7 @@

.pluginIcon[data-branded][data-category="developer-tools-and-integrations"]
img {
filter: hue-rotate(126deg) saturate(0.8);
filter: grayscale(1);
}

.pluginIcon[data-branded][data-category="people-and-communities"] {
Expand All @@ -346,7 +347,7 @@
}

.pluginIcon[data-branded][data-category="productivity"] img {
filter: hue-rotate(-169deg) saturate(0.8);
filter: grayscale(1);
}

:root[data-color-mode="dark"] .pluginIcon[data-branded] {
Expand Down
Loading
Loading