From bc7326942a762af778bb0c85ea5b0e96abed6d45 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 11:12:13 -0400 Subject: [PATCH 01/20] =?UTF-8?q?feat(amicode):=20light-mode=20brand=20yel?= =?UTF-8?q?low=20=E2=80=94=20fill=20+=20edge,=20not=20a=20muddy=20gold=20i?= =?UTF-8?q?nk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default theme's light accent used a dimmed gold (`#857A00`/`#6B6200`) for `text-accent`/`icon-accent` because raw `#FFF676` is unreadable on a light bg (1.1:1). But that made every accent text/icon/border read muddy on light and lost the brand. This mirrors the amicode webview fix (harmoniqs/amicode#140): yellow is a FILL, never an ink. - oc-2.json (LIGHT v2Overrides only; dark untouched): text/icon-accent gold → neutral dark ink (grey-1000 / grey-900). This turns `icon-accent` into the "edge" role — dark on light, lemon on dark — for free. - amicode.css: the solid brand dots (.amc-livedot, anchored timeline node) now fill with `bg-accent` (true lemon) and take `icon-accent` as a 1px edge — a dark hairline on light, invisible (lemon-on-lemon) on dark. Dark render is byte-for-byte unchanged. oc-2.json's v2Overrides is hand-maintained for the brand (theme.css is still upstream blue); do NOT run `generate:v2-oc2` — it would revert every brand accent to blue. Patch map (AMICODE-PATCHES.md #12) updated. Co-Authored-By: Claude Opus 4.8 (1M context) --- AMICODE-PATCHES.md | 2 +- packages/ui/src/amicode/amicode.css | 11 +++++++++-- packages/ui/src/theme/themes/oc-2.json | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/AMICODE-PATCHES.md b/AMICODE-PATCHES.md index e5eba9e0fb..fd38436f25 100644 --- a/AMICODE-PATCHES.md +++ b/AMICODE-PATCHES.md @@ -106,7 +106,7 @@ Format: file:line — string/asset — replacement. [desktop] = ships only in th | 10 | packages/app/src/desktop-menu.ts:75 [desktop] | menu label "OpenCode" | "Amicode" | | 11 | packages/app/src/wsl/settings-model.ts:17-18 [desktop, Windows/WSL] | "Install OpenCode"/"Update OpenCode" | "Install/Update Amicode" | | 13 | packages/ui/src/components/logo.css | `[data-component="logo-mark"]` aspect-ratio 4/5 (old 16x20 viewBox) | aspect-ratio 1/1 (new square amico mark) | -| 12 | packages/ui/src/theme/themes/oc-2.json (default theme) | accent tokens `v2-{background,text,icon}-*accent*` = blue-600/700 (light), blue-400/300 (dark) | Harmoniqs accent `#FFF676` (brand.css `--color-accent`): dark text/icon/bg-accent → `#FFF676`, hover `#FFFA9E`; light bg-accent → `#FFF676`, light text/icon-accent → derived dark shades `#857A00` / hover `#6B6200` (raw `#FFF676` is unreadable on light bg) | +| 12 | packages/ui/src/theme/themes/oc-2.json (default theme) | accent tokens `v2-{background,text,icon}-*accent*` = blue-600/700 (light), blue-400/300 (dark) | Harmoniqs accent `#FFF676` (brand.css `--color-accent`): dark text/icon/bg-accent → `#FFF676`, hover `#FFFA9E`; light bg-accent → `#FFF676` (fill; dark text sits on it), light text/icon-accent → neutral dark ink `grey-1000` / hover `grey-900` (yellow is a FILL, never an ink — raw `#FFF676` is unreadable on light bg, so brand shows as lemon fills with a 1px dark hairline edge, e.g. `.amc-livedot`; matches the webview treatment in harmoniqs/amicode#140) | Deliberately left stock (and why): diff --git a/packages/ui/src/amicode/amicode.css b/packages/ui/src/amicode/amicode.css index 0c50206d84..1da9cd1444 100644 --- a/packages/ui/src/amicode/amicode.css +++ b/packages/ui/src/amicode/amicode.css @@ -235,8 +235,13 @@ [data-component="amicode-card"] .amc-livedot { width: 6px; height: 6px; + box-sizing: border-box; border-radius: 50%; - background: var(--v2-icon-icon-accent); + /* Brand fill + edge: lemon on both themes. The edge is a 1px dark hairline on + light (icon-accent resolves to a neutral dark there) and lemon-on-lemon — + invisible — on dark. Yellow stays a fill, never an ink. */ + background: var(--v2-background-bg-accent); + border: 1px solid var(--v2-icon-icon-accent); } @media (prefers-reduced-motion: no-preference) { [data-component="amicode-card"][data-state="running"] .amc-livedot { animation: amc-blip 1.2s ease-in-out infinite; } @@ -479,7 +484,9 @@ background: color-mix(in srgb, var(--v2-icon-icon-accent) 9%, transparent); } [data-component="amicode-entity-view"] .amc-event[data-anchored]::before { - background: var(--v2-icon-icon-accent); + /* Lemon fill + edge (see .amc-livedot): the anchored timeline node keeps the + brand lemon on both themes, gaining a dark hairline on light. */ + background: var(--v2-background-bg-accent); border-color: var(--v2-icon-icon-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--v2-icon-icon-accent) 18%, transparent); } diff --git a/packages/ui/src/theme/themes/oc-2.json b/packages/ui/src/theme/themes/oc-2.json index 2325a14272..bd248a7bb8 100644 --- a/packages/ui/src/theme/themes/oc-2.json +++ b/packages/ui/src/theme/themes/oc-2.json @@ -167,14 +167,14 @@ "v2-text-text-faint": "var(--v2-grey-600)", "v2-text-text-inverse": "var(--v2-grey-100)", "v2-text-text-contrast": "var(--v2-grey-100)", - "v2-text-text-accent": "#857A00", - "v2-text-text-accent-hover": "#6B6200", + "v2-text-text-accent": "var(--v2-grey-1000)", + "v2-text-text-accent-hover": "var(--v2-grey-900)", "v2-icon-icon-base": "var(--v2-grey-800)", "v2-icon-icon-muted": "var(--v2-grey-600)", "v2-icon-icon-inverse": "var(--v2-grey-100)", "v2-icon-icon-contrast": "var(--v2-grey-200)", - "v2-icon-icon-accent": "#857A00", - "v2-icon-icon-accent-hover": "#6B6200", + "v2-icon-icon-accent": "var(--v2-grey-1000)", + "v2-icon-icon-accent-hover": "var(--v2-grey-900)", "v2-border-border-muted": "var(--v2-alpha-dark-8)", "v2-border-border-base": "var(--v2-alpha-dark-10)", "v2-border-border-strong": "var(--v2-alpha-dark-20)", From 822ccbf1045a2a21baf399de6b989ff7ee80a4c8 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 12:10:01 -0400 Subject: [PATCH 02/20] =?UTF-8?q?fix(amicode):=20shrink=20the=20Amico=20fa?= =?UTF-8?q?ce=20in=20the=20Meet=20Amico=20card=20(w-12=20=E2=86=92=20w-10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MarkDetailed glyph read oversized next to the two-line identity block; drop it from 48px to 40px so the mark supports the name rather than competing with it. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/ui/src/amicode/home-cards.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/amicode/home-cards.tsx b/packages/ui/src/amicode/home-cards.tsx index 36f564d551..b6dc25827f 100644 --- a/packages/ui/src/amicode/home-cards.tsx +++ b/packages/ui/src/amicode/home-cards.tsx @@ -245,7 +245,7 @@ function MeetAmicoCard(props: { onStart: (prompt: string) => void }) { data-slot="amicode-meet-identity" style={{ display: "flex", gap: "12px", "align-items": "center", "margin-top": "10px" }} > - +
Amico
From 32c63fea50cc30bbf796b8cef68a2d9a2631401a Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 13:17:16 -0400 Subject: [PATCH 03/20] =?UTF-8?q?fix(amicode):=20light-mode=20chat=20?= =?UTF-8?q?=E2=80=94=20bright-lemon=20FILLS=20for=20brand=20CTAs=20+=20sma?= =?UTF-8?q?ller=20face?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Open-chat CTA, the profile badge, and the save button used `icon-accent` as their background. On light, PR2 neutralizes that token (yellow-is-never-ink), so those FILLS went monochrome black — the brand yellow vanished. A fill should ride `bg-accent` (#FFF676, both themes), not the ink token. Point all three at `bg-accent` with fixed dark text (#000) and a 1px `icon-accent` edge — a dark hairline on light, invisible (lemon-on-lemon) on dark. Dark render is unchanged; light now shows the real Harmoniqs yellow as bordered fills. Also: Amico face on the Meet Amico card w-10 → w-8 (48→32px, noticeably smaller). Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/ui/src/amicode/home-cards.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/ui/src/amicode/home-cards.tsx b/packages/ui/src/amicode/home-cards.tsx index b6dc25827f..e186c0d013 100644 --- a/packages/ui/src/amicode/home-cards.tsx +++ b/packages/ui/src/amicode/home-cards.tsx @@ -245,7 +245,7 @@ function MeetAmicoCard(props: { onStart: (prompt: string) => void }) { data-slot="amicode-meet-identity" style={{ display: "flex", gap: "12px", "align-items": "center", "margin-top": "10px" }} > - +
Amico
@@ -285,14 +285,15 @@ function MeetAmicoCard(props: { onStart: (prompt: string) => void }) { gap: "10px", "margin-top": "4px", padding: "12px 22px", - border: "none", + border: "1px solid var(--v2-icon-icon-accent)", + "box-sizing": "border-box", "border-radius": "10px", cursor: "pointer", - background: "var(--v2-icon-icon-accent)", - color: "var(--v2-background-bg-base, #000)", + background: "var(--v2-background-bg-accent)", + color: "#000", "font-size": "15px", "font-weight": "650", - "box-shadow": "0 2px 10px color-mix(in srgb, var(--v2-icon-icon-accent) 35%, transparent)", + "box-shadow": "0 2px 10px color-mix(in srgb, var(--v2-background-bg-accent) 30%, transparent)", }} > Open chat @@ -596,8 +597,10 @@ function AboutYouCard(props: { height: "44px", "border-radius": "8px", flex: "none", - background: "var(--v2-icon-icon-accent)", - color: "var(--v2-background-bg-base, #000)", + background: "var(--v2-background-bg-accent)", + color: "#000", + border: "1px solid var(--v2-icon-icon-accent)", + "box-sizing": "border-box", "font-size": "15px", "font-weight": "700", "letter-spacing": "0.5px", @@ -837,9 +840,10 @@ function AboutYouCard(props: { disabled={saving() || resolvingLogo() > 0} onClick={() => void save()} style={{ - background: "var(--v2-icon-icon-accent)", - color: "var(--v2-background-bg-base, #000)", - border: "none", + background: "var(--v2-background-bg-accent)", + color: "#000", + border: "1px solid var(--v2-icon-icon-accent)", + "box-sizing": "border-box", "border-radius": "6px", padding: "4px 10px", "font-size": "12px", From c3498221653984d3c5f9362a66b5be4fe2820183 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:21:55 -0400 Subject: [PATCH 04/20] =?UTF-8?q?fix(amicode):=20brand=20fill=20crosses=20?= =?UTF-8?q?the=20widget-iframe=20seam=20=E2=80=94=20lemon=20CTA=20+=20half?= =?UTF-8?q?-size=20face?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dashboard cards are sandboxed widget iframes, and the token seam (widget-tokens.ts) forwarded exactly ONE accent: --amc-accent ← icon-accent. The light-mode neutral-ink change therefore turned every in-widget accent near-black — including the Meet Amico "Open chat" CTA, which used the accent as a solid BACKGROUND. Net effect on light: a black button and zero yellow anywhere (the "black and white" dashboard). - widget-tokens.ts: add --amc-accent-fill ← --v2-background-bg-accent (fallback #FFF676) — the brand fill, lemon on every theme. --amc-accent doubles as its 1px edge: dark hairline on light, invisible on dark. - meet-amico.ts: the CTA rides the fill (lemon bg, #000 text, 1px accent edge) instead of accent-as-background. Sole fill misuse across the seven builtin widgets; all other accent uses are ink and stay correct. - meet-amico.ts: face SVG was hardcoded 89x40 (why earlier host-side size changes had no effect) → 44x20. - widget-tokens.test.ts: cover the new token; count 15 → 16. widget-tokens: 5/5 pass. amicode-widgets-src: 15 pre-existing temp-dir import failures identical with and without this change (env-only). Co-Authored-By: Claude Fable 5 --- .../opencode/src/server/amicode/widgets-src/meet-amico.ts | 4 ++-- packages/ui/src/amicode/widget-tokens.test.ts | 3 ++- packages/ui/src/amicode/widget-tokens.ts | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/server/amicode/widgets-src/meet-amico.ts b/packages/opencode/src/server/amicode/widgets-src/meet-amico.ts index ba878d027c..ea766dd619 100644 --- a/packages/opencode/src/server/amicode/widgets-src/meet-amico.ts +++ b/packages/opencode/src/server/amicode/widgets-src/meet-amico.ts @@ -26,7 +26,7 @@ var CAN = [ // native ~2:1 proportions. Keep these element strings in sync with MarkDetailed // by hand if the mark changes. var FACE = - '
' + '
I can help you
' + '
' + bullets + '
' + - '' + + '' + '
' on('[data-cta]', function (e) { e.stopPropagation() diff --git a/packages/ui/src/amicode/widget-tokens.test.ts b/packages/ui/src/amicode/widget-tokens.test.ts index 9e2954fa7d..aaf8097a19 100644 --- a/packages/ui/src/amicode/widget-tokens.test.ts +++ b/packages/ui/src/amicode/widget-tokens.test.ts @@ -31,8 +31,9 @@ describe("resolveTokens", () => { expect(tokens["--amc-text"]).toBe("#fff") expect(tokens["--amc-bg"]).toBe("#0B0E15") // fallback expect(tokens["--amc-accent"]).toBe("#F2C94C") + expect(tokens["--amc-accent-fill"]).toBe("#FFF676") // brand fill fallback expect(tokens["--amc-font-mono"]).toContain("monospace") - expect(Object.keys(tokens)).toHaveLength(15) // 11 colors + 2 fonts + 2 pads + expect(Object.keys(tokens)).toHaveLength(16) // 12 colors + 2 fonts + 2 pads }) test("padding tokens follow density", () => { expect(resolveTokens(() => "", "normal")["--amc-pad"]).toBe("14px 16px") diff --git a/packages/ui/src/amicode/widget-tokens.ts b/packages/ui/src/amicode/widget-tokens.ts index 6602651c13..b8608c557a 100644 --- a/packages/ui/src/amicode/widget-tokens.ts +++ b/packages/ui/src/amicode/widget-tokens.ts @@ -39,6 +39,10 @@ const SOURCES: [amc: string, v2: string, fallback: string][] = [ ["--amc-text-muted", "--v2-text-text-muted", "#8B94A9"], ["--amc-text-faint", "--v2-text-text-faint", "#6A7286"], ["--amc-accent", "--v2-icon-icon-accent", "#F2C94C"], + // The brand FILL — true lemon on every theme (yellow is a fill, never an + // ink). Widgets pair it with black text and a 1px var(--amc-accent) edge: + // a dark hairline on light themes, invisible lemon-on-lemon on dark. + ["--amc-accent-fill", "--v2-background-bg-accent", "#FFF676"], ["--amc-success", "--v2-state-fg-success", "#5BC873"], ["--amc-warning", "--v2-state-fg-warning", "#E5B454"], ["--amc-danger", "--v2-state-fg-danger", "#E56A6A"], From 37c7283d6a765ea16df11f7153f73dee7aa58560 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:34:42 -0400 Subject: [PATCH 05/20] =?UTF-8?q?fix(amicode):=20purge=20the=20retired=20g?= =?UTF-8?q?old=20=E2=80=94=20brain=20ink,=20seam=20fallbacks,=20lemon=20sp?= =?UTF-8?q?lash=20mark?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three places still carried the old dimmed-gold light treatment, and the new-session splash had no brand yellow at all: - brain.html (both light palette blocks): --thought #8f8000 / --thought-text #7a6e00 → neutral ink (#22221f / #52524b). Live-signal strokes are an INK role — yellow is a fill, never an ink; the lemon stays in the brain's bordered --accent node fills, which light mode inherits unchanged. - widget seam boot golds: widget-tokens.ts fallback and widget-frame-html.ts BAKED_TOKENS --amc-accent #F2C94C → #FFF676 (the real dark value — no more gold flash before amc:init lands); bake --amc-accent-fill too. - run-card.tsx: the share PNG is fixed-dark, where the true lemon sings — GOLD #F2C94C → #FFF676. - logo.tsx: MarkDetailed gains a `brand` variant — the H tile becomes a lemon FILL with a 1px icon-accent edge (dark hairline on light, invisible on dark); the face stays currentColor. Both new-session splash views use it, so the splash carries the brand yellow in both themes. widget-tokens + run-card: 12/12 pass. Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 5 +++-- .../components/session/session-new-design-view.tsx | 2 +- .../src/components/session/session-new-view.tsx | 2 +- .../src/server/amicode/widget-frame-html.ts | 3 ++- packages/ui/src/amicode/run-card.test.ts | 2 +- packages/ui/src/amicode/run-card.tsx | 2 +- packages/ui/src/amicode/widget-tokens.test.ts | 2 +- packages/ui/src/amicode/widget-tokens.ts | 2 +- packages/ui/src/components/logo.tsx | 14 ++++++++++++-- 9 files changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index cf933a6ef0..710ec6a09d 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -68,8 +68,9 @@ --edge-rest: rgba(0, 0, 0, 0.15); --node-rest-fill: #eae7dd; --node-rest-border: rgba(0, 0, 0, 0.26); - --thought: #8f8000; - --thought-text: #7a6e00; + --thought: #22221f; /* light: live-signal is neutral INK — the retired gold read muddy; + yellow is a fill, never an ink (lemon stays in --accent node fills) */ + --thought-text: #52524b; --cat-knowledge: #1866c9; --cat-results: #8f5800; --cat-skills: #7b4fa8; diff --git a/packages/app/src/components/session/session-new-design-view.tsx b/packages/app/src/components/session/session-new-design-view.tsx index aa9bbb621c..e156fa4e82 100644 --- a/packages/app/src/components/session/session-new-design-view.tsx +++ b/packages/app/src/components/session/session-new-design-view.tsx @@ -12,7 +12,7 @@ export function NewSessionDesignView(props: { children: JSX.Element; gettingStar
- +
{props.gettingStarted}
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx index f3c7d40812..b0eaed22ac 100644 --- a/packages/app/src/components/session/session-new-view.tsx +++ b/packages/app/src/components/session/session-new-view.tsx @@ -78,7 +78,7 @@ export function NewSessionView(props: NewSessionViewProps) {
- + {/* amicode: brand wordmark in the brand typeface (Racing Sans One — restored per review); MarkDetailed is the redesign's detailed mark (kept from trunk) */} diff --git a/packages/opencode/src/server/amicode/widget-frame-html.ts b/packages/opencode/src/server/amicode/widget-frame-html.ts index 1e27a641ae..2107620c59 100644 --- a/packages/opencode/src/server/amicode/widget-frame-html.ts +++ b/packages/opencode/src/server/amicode/widget-frame-html.ts @@ -22,7 +22,8 @@ const BAKED_TOKENS: Record = { "--amc-text": "#E9ECF4", "--amc-text-muted": "#8B94A9", "--amc-text-faint": "#6A7286", - "--amc-accent": "#F2C94C", + "--amc-accent": "#FFF676", + "--amc-accent-fill": "#FFF676", "--amc-success": "#5BC873", "--amc-warning": "#E5B454", "--amc-danger": "#E56A6A", diff --git a/packages/ui/src/amicode/run-card.test.ts b/packages/ui/src/amicode/run-card.test.ts index ff5c973756..63a80afb3a 100644 --- a/packages/ui/src/amicode/run-card.test.ts +++ b/packages/ui/src/amicode/run-card.test.ts @@ -36,7 +36,7 @@ describe("renderRunCardSvg", () => { expect(svg).toContain("harmoniqs.ai") expect(svg).toContain("AMICODE") // 2 drives → 2 pulse paths (second at companion opacity) - expect(svg.match(/stroke="#F2C94C" stroke-width="2\.5"/g)?.length).toBe(2) + expect(svg.match(/stroke="#FFF676" stroke-width="2\.5"/g)?.length).toBe(2) expect(svg).toContain('opacity="0.55"') }) test("pulse panel reads first (left column), convergence second", () => { diff --git a/packages/ui/src/amicode/run-card.tsx b/packages/ui/src/amicode/run-card.tsx index 50d5a58fa5..86057952b8 100644 --- a/packages/ui/src/amicode/run-card.tsx +++ b/packages/ui/src/amicode/run-card.tsx @@ -66,7 +66,7 @@ const PANEL = "#111624" const LINE = "#2A3245" const TEXT = "#E9ECF4" const MUTED = "#8B94A9" -const GOLD = "#F2C94C" +const GOLD = "#FFF676" // the brand lemon — card bg is fixed-dark, where the true accent sings const CURVE = "#7FD1FF" const W = 1200 diff --git a/packages/ui/src/amicode/widget-tokens.test.ts b/packages/ui/src/amicode/widget-tokens.test.ts index aaf8097a19..295a239dca 100644 --- a/packages/ui/src/amicode/widget-tokens.test.ts +++ b/packages/ui/src/amicode/widget-tokens.test.ts @@ -30,7 +30,7 @@ describe("resolveTokens", () => { const tokens = resolveTokens((name) => (name === "--v2-text-text-base" ? " #fff " : ""), "normal") expect(tokens["--amc-text"]).toBe("#fff") expect(tokens["--amc-bg"]).toBe("#0B0E15") // fallback - expect(tokens["--amc-accent"]).toBe("#F2C94C") + expect(tokens["--amc-accent"]).toBe("#FFF676") expect(tokens["--amc-accent-fill"]).toBe("#FFF676") // brand fill fallback expect(tokens["--amc-font-mono"]).toContain("monospace") expect(Object.keys(tokens)).toHaveLength(16) // 12 colors + 2 fonts + 2 pads diff --git a/packages/ui/src/amicode/widget-tokens.ts b/packages/ui/src/amicode/widget-tokens.ts index b8608c557a..a168f440d8 100644 --- a/packages/ui/src/amicode/widget-tokens.ts +++ b/packages/ui/src/amicode/widget-tokens.ts @@ -38,7 +38,7 @@ const SOURCES: [amc: string, v2: string, fallback: string][] = [ ["--amc-text", "--v2-text-text-base", "#E9ECF4"], ["--amc-text-muted", "--v2-text-text-muted", "#8B94A9"], ["--amc-text-faint", "--v2-text-text-faint", "#6A7286"], - ["--amc-accent", "--v2-icon-icon-accent", "#F2C94C"], + ["--amc-accent", "--v2-icon-icon-accent", "#FFF676"], // The brand FILL — true lemon on every theme (yellow is a fill, never an // ink). Widgets pair it with black text and a 1px var(--amc-accent) edge: // a dark hairline on light themes, invisible lemon-on-lemon on dark. diff --git a/packages/ui/src/components/logo.tsx b/packages/ui/src/components/logo.tsx index 0caebb4900..c0d67d477a 100644 --- a/packages/ui/src/components/logo.tsx +++ b/packages/ui/src/components/logo.tsx @@ -61,7 +61,7 @@ export const Splash = (props: Pick, "ref" | "class">) => { // files because a native tab icon has no live CSS context for currentColor. // Geometry mirrors amicode:packages/extension/media/amico.svg (viewBox // 0 0 3600 3600); keep in sync by hand if that mark changes. -export const MarkDetailed = (props: { class?: string }) => { +export const MarkDetailed = (props: { class?: string; brand?: boolean }) => { return ( { style={{ color: "var(--icon-strong-base)" }} fill="currentColor" > - + {/* brand: the H tile is a lemon FILL with a 1px edge (yellow is a fill, + never an ink). The edge rides icon-accent — a dark hairline on light + themes, invisible lemon-on-lemon on dark. The face stays currentColor: + it sits on the page background through the tile's window. */} + From d6028eb64e1a02d11a037230514abafb081536e4 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:36:30 -0400 Subject: [PATCH 06/20] =?UTF-8?q?fix(amicode):=20the=20@media=20light=20bl?= =?UTF-8?q?ock=20in=20brain.html=20kept=20the=20gold=20=E2=80=94=20same=20?= =?UTF-8?q?ink=20swap=20as=20the=20data-theme=20block?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index 710ec6a09d..117c67fd58 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -47,8 +47,9 @@ --edge-rest: rgba(0, 0, 0, 0.15); --node-rest-fill: #eae7dd; --node-rest-border: rgba(0, 0, 0, 0.26); - --thought: #8f8000; - --thought-text: #7a6e00; + --thought: #22221f; /* light: live-signal is neutral INK — the retired gold read muddy; + yellow is a fill, never an ink (lemon stays in --accent node fills) */ + --thought-text: #52524b; --cat-knowledge: #1866c9; --cat-results: #8f5800; --cat-skills: #7b4fa8; From 84d32a2e59bef308fc74e52e280237f74e5e93ea Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:45:59 -0400 Subject: [PATCH 07/20] =?UTF-8?q?fix(amicode):=20yellow=20goes=20to=20the?= =?UTF-8?q?=20starter=20chips=20and=20the=20brain=20signal=20=E2=80=94=20n?= =?UTF-8?q?ot=20the=20mark?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correcting the previous pass per Kate's direction: - REVERT the lemon splash mark (logo.tsx brand variant + both session-new views) — the amico.svg mark was not supposed to be colored; it returns to currentColor exactly as before. - Starter-prompt chips (getting-started.tsx, both the starters and Resume): lemon fill (#FFF676 via bg-accent) + black text + the existing 1px icon-accent edge — the bordered-fill treatment, both themes. - The thinking brain gets its yellow BACK, legibly: --thought returns to the true brand lemon on light, paired with a new light-only --thought-edge (#22221f). brain.js draws every thought element two-pass — dark under-stroke/hairline ring beneath the lemon core — for the survey lines, pulse dots, node flash fills, claimed-node borders, survey rings, and the where-we-are cursor. Dark themes skip the edge pass entirely (var unset) and render byte-identically to before. Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 14 ++++--- packages/app/public/brain.js | 38 ++++++++++++++++++- .../session/session-new-design-view.tsx | 2 +- .../components/session/session-new-view.tsx | 2 +- packages/ui/src/amicode/getting-started.tsx | 8 ++-- packages/ui/src/components/logo.tsx | 14 +------ 6 files changed, 53 insertions(+), 25 deletions(-) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index 117c67fd58..dabebe6f35 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -47,9 +47,10 @@ --edge-rest: rgba(0, 0, 0, 0.15); --node-rest-fill: #eae7dd; --node-rest-border: rgba(0, 0, 0, 0.26); - --thought: #22221f; /* light: live-signal is neutral INK — the retired gold read muddy; - yellow is a fill, never an ink (lemon stays in --accent node fills) */ - --thought-text: #52524b; + --thought: #fff676; /* the TRUE brand lemon — brain.js pairs every thought stroke/fill + with a --thought-edge under-stroke so it reads on paper */ + --thought-edge: #22221f; /* light-only: the dark hairline that bounds the lemon signal */ + --thought-text: #52524b; /* signal TEXT stays ink — yellow is never text */ --cat-knowledge: #1866c9; --cat-results: #8f5800; --cat-skills: #7b4fa8; @@ -69,9 +70,10 @@ --edge-rest: rgba(0, 0, 0, 0.15); --node-rest-fill: #eae7dd; --node-rest-border: rgba(0, 0, 0, 0.26); - --thought: #22221f; /* light: live-signal is neutral INK — the retired gold read muddy; - yellow is a fill, never an ink (lemon stays in --accent node fills) */ - --thought-text: #52524b; + --thought: #fff676; /* the TRUE brand lemon — brain.js pairs every thought stroke/fill + with a --thought-edge under-stroke so it reads on paper */ + --thought-edge: #22221f; /* light-only: the dark hairline that bounds the lemon signal */ + --thought-text: #52524b; /* signal TEXT stays ink — yellow is never text */ --cat-knowledge: #1866c9; --cat-results: #8f5800; --cat-skills: #7b4fa8; diff --git a/packages/app/public/brain.js b/packages/app/public/brain.js index e0029cc018..0276e68457 100644 --- a/packages/app/public/brain.js +++ b/packages/app/public/brain.js @@ -49,6 +49,9 @@ function readTokens() { css.surface = g("--surface"); css.fg = g("--fg"); css.muted = g("--muted"); css.edgeRest = g("--edge-rest"); css.nodeFill = g("--node-rest-fill"); css.nodeBorder = g("--node-rest-border"); css.thought = g("--thought"); + // Light-only (unset on dark → ""): the dark hairline that bounds the lemon + // signal — yellow is a fill, never a bare line on paper. + css.thoughtEdge = g("--thought-edge"); css.ember = g("--ember"); css.vignette = g("--vignette"); css.labelHalo = g("--label-halo"); css.accent = g("--accent") || "#fff676"; css.cat = { @@ -624,6 +627,14 @@ function draw(nowMs) { ctx.beginPath(); ctx.moveTo(nx(a), ny(a)); ctx.lineTo(nx(a) + (nx(b) - nx(a)) * segT, ny(a) + (ny(b) - ny(a)) * segT); + if (drain > 0 && css.thoughtEdge) { + // two-pass: dark under-stroke, lemon core (the fill+edge model as a line) + ctx.strokeStyle = rgba(css.thoughtEdge, (0.25 + drain * 0.5) * con.alpha); + ctx.lineWidth = 2.5; + ctx.stroke(); + ctx.lineWidth = 1; + ctx.strokeStyle = rgba(css.thought, (0.2 + drain * 0.5) * con.alpha); + } ctx.stroke(); } } @@ -686,6 +697,12 @@ function draw(nowMs) { } ctx.fillStyle = rgba(css.thought, Math.min(dim + 0.15, 1)); ctx.beginPath(); ctx.arc(pos.x, pos.y, size / 2, 0, Math.PI * 2); ctx.fill(); + if (css.thoughtEdge) { + // the lemon pulse gets a hairline ring so it reads on paper + ctx.strokeStyle = rgba(css.thoughtEdge, Math.min(dim + 0.15, 1)); + ctx.lineWidth = 1; + ctx.stroke(); + } } // ---- nodes @@ -720,11 +737,18 @@ function draw(nowMs) { if (n.flash > 0.55) { ctx.fillStyle = css.thought; // all-or-nothing: the attack is pure accent ctx.fill(); + if (css.thoughtEdge) { + // bounded lemon: the flash fill takes the light-mode hairline + ctx.strokeStyle = rgba(css.thoughtEdge, 0.9); + ctx.lineWidth = 1; + ctx.stroke(); + } } else if (n.claimed) { const sustain = n.atlasKeep && !player.running ? 0.55 : 0.85; ctx.fillStyle = rgba(catColor, sustain * (n.flash > 0 ? 1 : 0.9) + coreBr); ctx.fill(); - ctx.strokeStyle = rgba(catColor, 0.9); + // light: a lemon node can't bound itself — the edge goes dark (hairline) + ctx.strokeStyle = css.thoughtEdge ? rgba(css.thoughtEdge, 0.9) : rgba(catColor, 0.9); ctx.lineWidth = 1; ctx.stroke(); } else { @@ -756,6 +780,12 @@ function draw(nowMs) { const rh = half + rt * half * 2.6; ctx.beginPath(); ctx.arc(x, y, rh, 0, Math.PI * 2); + if (css.thoughtEdge) { + // two-pass ring: dark under-stroke keeps the lemon visible on paper + ctx.strokeStyle = rgba(css.thoughtEdge, (1 - rt) * 0.85); + ctx.lineWidth = 2.5; + ctx.stroke(); + } ctx.strokeStyle = rgba(css.thought, (1 - rt) * 0.8); ctx.lineWidth = 1; ctx.stroke(); @@ -787,6 +817,12 @@ function draw(nowMs) { const rr = curNode.half + 5 + (reduceMotion ? 0 : Math.sin(nowMs / 600) * 1.5); ctx.beginPath(); ctx.arc(cxp, cyp, rr, 0, Math.PI * 2); + if (css.thoughtEdge) { + // the position marker must actually be legible on paper: dark under-ring + ctx.strokeStyle = rgba(css.thoughtEdge, 0.9); + ctx.lineWidth = 3; + ctx.stroke(); + } ctx.strokeStyle = rgba(css.thought, 0.85); ctx.lineWidth = 1.5; ctx.stroke(); diff --git a/packages/app/src/components/session/session-new-design-view.tsx b/packages/app/src/components/session/session-new-design-view.tsx index e156fa4e82..aa9bbb621c 100644 --- a/packages/app/src/components/session/session-new-design-view.tsx +++ b/packages/app/src/components/session/session-new-design-view.tsx @@ -12,7 +12,7 @@ export function NewSessionDesignView(props: { children: JSX.Element; gettingStar
- +
{props.gettingStarted}
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx index b0eaed22ac..f3c7d40812 100644 --- a/packages/app/src/components/session/session-new-view.tsx +++ b/packages/app/src/components/session/session-new-view.tsx @@ -78,7 +78,7 @@ export function NewSessionView(props: NewSessionViewProps) {
- + {/* amicode: brand wordmark in the brand typeface (Racing Sans One — restored per review); MarkDetailed is the redesign's detailed mark (kept from trunk) */} diff --git a/packages/ui/src/amicode/getting-started.tsx b/packages/ui/src/amicode/getting-started.tsx index 086a354ee2..e53653dcff 100644 --- a/packages/ui/src/amicode/getting-started.tsx +++ b/packages/ui/src/amicode/getting-started.tsx @@ -110,8 +110,8 @@ export function AmicodeGettingStarted(props: { style={{ border: "1px solid var(--v2-icon-icon-accent)", "border-radius": "6px", - background: "var(--v2-background-bg-layer-02)", - color: "var(--v2-text-text-base)", + background: "var(--v2-background-bg-accent, #FFF676)", + color: "#000", padding: "4px 12px", "font-size": "12px", "line-height": "16px", @@ -130,8 +130,8 @@ export function AmicodeGettingStarted(props: { style={{ border: "1px solid var(--v2-icon-icon-accent)", "border-radius": "6px", - background: "var(--v2-background-bg-layer-02)", - color: "var(--v2-text-text-base)", + background: "var(--v2-background-bg-accent, #FFF676)", + color: "#000", padding: "4px 12px", "font-size": "12px", "line-height": "16px", diff --git a/packages/ui/src/components/logo.tsx b/packages/ui/src/components/logo.tsx index c0d67d477a..0caebb4900 100644 --- a/packages/ui/src/components/logo.tsx +++ b/packages/ui/src/components/logo.tsx @@ -61,7 +61,7 @@ export const Splash = (props: Pick, "ref" | "class">) => { // files because a native tab icon has no live CSS context for currentColor. // Geometry mirrors amicode:packages/extension/media/amico.svg (viewBox // 0 0 3600 3600); keep in sync by hand if that mark changes. -export const MarkDetailed = (props: { class?: string; brand?: boolean }) => { +export const MarkDetailed = (props: { class?: string }) => { return ( { style={{ color: "var(--icon-strong-base)" }} fill="currentColor" > - {/* brand: the H tile is a lemon FILL with a 1px edge (yellow is a fill, - never an ink). The edge rides icon-accent — a dark hairline on light - themes, invisible lemon-on-lemon on dark. The face stays currentColor: - it sits on the page background through the tile's window. */} - + From f4748fb0faf139c610643164dde078130dcd4d44 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:49:55 -0400 Subject: [PATCH 08/20] =?UTF-8?q?style(amicode):=20brain=20signal=20edge?= =?UTF-8?q?=20softens=20=E2=80=94=20darker=20lemon=20instead=20of=20ink=20?= =?UTF-8?q?(Kate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dark under-strokes read too heavy on light. The edge keeps the exact brand hue/chroma with lightness stepped 0.956→0.87 (OKLCH → #e3d958): a lemon core with a slightly-darker-lemon halo, no black outlines. Same two-pass mechanism in brain.js, dark themes still untouched. Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index dabebe6f35..19261295de 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -49,7 +49,8 @@ --node-rest-border: rgba(0, 0, 0, 0.26); --thought: #fff676; /* the TRUE brand lemon — brain.js pairs every thought stroke/fill with a --thought-edge under-stroke so it reads on paper */ - --thought-edge: #22221f; /* light-only: the dark hairline that bounds the lemon signal */ + --thought-edge: #e3d958; /* light-only halo: the SAME hue/chroma as the lemon, lightness + stepped 0.956→0.87 (OKLCH) — a soft darker-lemon edge, not ink */ --thought-text: #52524b; /* signal TEXT stays ink — yellow is never text */ --cat-knowledge: #1866c9; --cat-results: #8f5800; @@ -72,7 +73,8 @@ --node-rest-border: rgba(0, 0, 0, 0.26); --thought: #fff676; /* the TRUE brand lemon — brain.js pairs every thought stroke/fill with a --thought-edge under-stroke so it reads on paper */ - --thought-edge: #22221f; /* light-only: the dark hairline that bounds the lemon signal */ + --thought-edge: #e3d958; /* light-only halo: the SAME hue/chroma as the lemon, lightness + stepped 0.956→0.87 (OKLCH) — a soft darker-lemon edge, not ink */ --thought-text: #52524b; /* signal TEXT stays ink — yellow is never text */ --cat-knowledge: #1866c9; --cat-results: #8f5800; From db7293ce172db104f6101d018cd40316864493cd Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 14:53:02 -0400 Subject: [PATCH 09/20] =?UTF-8?q?style(amicode):=20starter=20chips=20?= =?UTF-8?q?=E2=80=94=20lemon=20icon=20tile,=20neutral=20body=20(Kate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full-lemon chips read as too much. The brand moment shrinks to a 20px lemon tile leading each chip: bg-accent fill, 1px icon-accent edge (dark hairline on light, invisible on dark), and a per-action stroke glyph in ink — pulse trace, target, restart arc, bolt, question, play. One icon family (24-grid, 1.75px round strokes, SVG only), per the ui-ux-pro icon rules. The chip body returns to neutral layer-02 + text-base. Co-Authored-By: Claude Fable 5 --- packages/ui/src/amicode/getting-started.tsx | 69 ++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/packages/ui/src/amicode/getting-started.tsx b/packages/ui/src/amicode/getting-started.tsx index e53653dcff..0c81dfc9a2 100644 --- a/packages/ui/src/amicode/getting-started.tsx +++ b/packages/ui/src/amicode/getting-started.tsx @@ -13,14 +13,19 @@ import { AmicodeTagline } from "./tagline" // The set spans the lifetime: onboard (first run routes any chip into the // overture) → design with memory/recommendations → warm-start from the pulse // bank → go fast with Veloce. -export const AMICODE_STARTERS: readonly { label: string; prompt: string }[] = [ +// Each starter carries a stroke-icon path (24-grid, one family: 1.75px round +// strokes) suggesting its action — rendered on a small lemon tile so the chip +// reads branded without the whole component going yellow (Kate). +export const AMICODE_STARTERS: readonly { label: string; prompt: string; icon: string }[] = [ { label: "Design a pulse — walk me through it", prompt: "walk me through designing a pulse", + icon: "M2 12h4l3-7 4 14 3-7h6", // a pulse trace }, { label: "Optimize an X gate on my transmon", prompt: "optimize an X gate on my transmon — use what you know from my history", + icon: "M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16M12 10.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3", // a target }, // NOTE(spec B): the static "Resume my pulse design" chip was replaced by the // conditional resumeName-driven chip below — Resume renders only when a @@ -28,17 +33,59 @@ export const AMICODE_STARTERS: readonly { label: string; prompt: string }[] = [ { label: "Warm-start from my pulse bank", prompt: "warm-start a new solve from my pulse bank", + icon: "M20 12a8 8 0 1 1-2.3-5.7M20 3v4h-4", // restart arc }, { label: "Go fast with Veloce", prompt: "turn on Veloce — auto-accept your high-confidence recommendations, and still confirm before any solve", + icon: "M13 3 5 14h5l-1 7 8-11h-5l1-7Z", // a bolt }, { label: "What can Amico do?", prompt: "what can Amico do?", + icon: "M9.3 9.3a2.8 2.8 0 1 1 3.9 2.6c-.9.4-1.2.9-1.2 1.9M12 17.2v.1", // a question }, ] +// Resume is play-shaped. +const RESUME_ICON = "M8 5.5v13l10.5-6.5Z" + +// The one place the chip carries the brand: a small lemon tile (fill + 1px +// icon-accent edge — dark hairline on light, invisible on dark) holding the +// action glyph in ink. SVG only, never emoji; 12px glyph on a 20px tile. +const GLYPH_TILE: Record = { + display: "inline-flex", + "align-items": "center", + "justify-content": "center", + width: "20px", + height: "20px", + "box-sizing": "border-box", + "flex-shrink": "0", + "border-radius": "5px", + background: "var(--v2-background-bg-accent, #FFF676)", + border: "1px solid var(--v2-icon-icon-accent)", + color: "#000", +} + +function StarterGlyph(props: { d: string }) { + return ( + + ) +} + // The three-beat arc of a pulse-design session, from setup to hardware. const STEPS = ["① Define your system and problem", "② Optimize and iterate", "③ Execute and tune on hardware"] @@ -108,16 +155,20 @@ export function AmicodeGettingStarted(props: { data-slot="amicode-gs-starter" onClick={() => props.onStart(starter.prompt)} style={{ + display: "inline-flex", + "align-items": "center", + gap: "7px", border: "1px solid var(--v2-icon-icon-accent)", "border-radius": "6px", - background: "var(--v2-background-bg-accent, #FFF676)", - color: "#000", - padding: "4px 12px", + background: "var(--v2-background-bg-layer-02)", + color: "var(--v2-text-text-base)", + padding: "4px 12px 4px 5px", "font-size": "12px", "line-height": "16px", cursor: "pointer", }} > + {starter.label} )} @@ -128,16 +179,20 @@ export function AmicodeGettingStarted(props: { data-slot="amicode-gs-resume" onClick={() => props.onResume?.()} style={{ + display: "inline-flex", + "align-items": "center", + gap: "7px", border: "1px solid var(--v2-icon-icon-accent)", "border-radius": "6px", - background: "var(--v2-background-bg-accent, #FFF676)", - color: "#000", - padding: "4px 12px", + background: "var(--v2-background-bg-layer-02)", + color: "var(--v2-text-text-base)", + padding: "4px 12px 4px 5px", "font-size": "12px", "line-height": "16px", cursor: "pointer", }} > + Resume “{props.resumeName}” )} From 99718fd0007fad5503bc36edbbbb78a7c06f7f63 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 15:00:08 -0400 Subject: [PATCH 10/20] =?UTF-8?q?style(amicode):=20starter=20chips=20?= =?UTF-8?q?=E2=80=94=20two-column=20grid,=20softer=20chip=20border=20(Kate?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The centered flex-wrap rows become a 2-column grid (equal-width cells, 540px max, labels ellipsize instead of overflowing). The chip outline drops from icon-accent (near-black on light) to the theme's border-strong token; the lemon glyph tile keeps its crisp icon-accent hairline — that edge IS the brand treatment. Co-Authored-By: Claude Fable 5 --- packages/ui/src/amicode/getting-started.tsx | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/ui/src/amicode/getting-started.tsx b/packages/ui/src/amicode/getting-started.tsx index 0c81dfc9a2..81ace1a5ca 100644 --- a/packages/ui/src/amicode/getting-started.tsx +++ b/packages/ui/src/amicode/getting-started.tsx @@ -142,10 +142,11 @@ export function AmicodeGettingStarted(props: {
@@ -158,7 +159,8 @@ export function AmicodeGettingStarted(props: { display: "inline-flex", "align-items": "center", gap: "7px", - border: "1px solid var(--v2-icon-icon-accent)", + "min-width": "0", + border: "1px solid var(--v2-border-border-strong)", "border-radius": "6px", background: "var(--v2-background-bg-layer-02)", color: "var(--v2-text-text-base)", @@ -169,7 +171,9 @@ export function AmicodeGettingStarted(props: { }} > - {starter.label} + + {starter.label} + )} @@ -182,7 +186,8 @@ export function AmicodeGettingStarted(props: { display: "inline-flex", "align-items": "center", gap: "7px", - border: "1px solid var(--v2-icon-icon-accent)", + "min-width": "0", + border: "1px solid var(--v2-border-border-strong)", "border-radius": "6px", background: "var(--v2-background-bg-layer-02)", color: "var(--v2-text-text-base)", @@ -193,7 +198,9 @@ export function AmicodeGettingStarted(props: { }} > - Resume “{props.resumeName}” + + Resume “{props.resumeName}” + )}
From 57a779ccbf1caaf0e053c0c18470c58df4478d82 Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 15:06:17 -0400 Subject: [PATCH 11/20] =?UTF-8?q?style(amicode):=20brain=20nodes=20?= =?UTF-8?q?=E2=80=94=20lemon=20base=20with=20mode-adaptive=20halo=20(Kate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The node/signal base is always the brand lemon (#fff676); the edge now adapts per mode instead of being light-only: darker lemon (#e3d958) on light, LIGHTER lemon (#fffa9e — the established brand hover step) on dark. Same two-pass mechanism in brain.js; dark simply gains its pale halo. Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index 19261295de..720783c5d1 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -27,6 +27,8 @@ --accent: #fff676; --on-accent: #000000; --thought: #fff676; /* live-signal color: pulses, flares, live survey lines */ + --thought-edge: #fffa9e; /* dark: the halo is a LIGHTER lemon (the brand hover step) — + light mode flips it darker; the node base is always #fff676 */ --thought-text: #d8cf6a; /* accent-adjacent, legible as text on this surface */ --cat-knowledge: #3794ff; /* series-1 — notes, insights, charter, strategy */ --cat-results: #c17800; /* series-2 — experiments, catalog pulses */ @@ -96,6 +98,7 @@ --node-rest-border: rgba(255, 255, 255, 0.24); --accent: #fff676; --thought: #fff676; + --thought-edge: #fffa9e; --thought-text: #d8cf6a; --cat-knowledge: #3794ff; --cat-results: #c17800; From c8c9a706e19509b6a5c871aaa3254694fbf3058d Mon Sep 17 00:00:00 2001 From: kate bonner Date: Wed, 15 Jul 2026 19:08:48 -0400 Subject: [PATCH 12/20] =?UTF-8?q?fix(amicode):=20brain=20embeds=20?= =?UTF-8?q?=E2=80=94=20pre-paint=20chrome=20gate=20kills=20the=20demo-UI?= =?UTF-8?q?=20flash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The brain page's demo chrome (mast "amico is thinking" + transport controls + legend + colophon) is static HTML that embeds hide from brain.js — which runs after first paint, so the chat's thinking strip flashed the whole demo panel for a beat before the animation appeared (Kate: remove it). An inline head script stamps the ?mode= on before first paint and a tiny stylesheet hides the chrome instantly (live/inline: all chrome + transparent ground; loader: controls/legend/colophon). brain.js keeps its idempotent post-boot hiding. NOTE: brain.{html,js} are marked GENERATED from amicode packages/extension/media/brain/ — this and the palette/edge commits need a port-back to that source when the split is next regenerated. Co-Authored-By: Claude Fable 5 --- packages/app/public/brain.html | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/app/public/brain.html b/packages/app/public/brain.html index 720783c5d1..fede32b028 100644 --- a/packages/app/public/brain.html +++ b/packages/app/public/brain.html @@ -3,6 +3,22 @@ Re-split to update; do not hand-edit. --> amico is thinking + + -