refactor(design): one colour system on the bot pages - #144
Merged
Conversation
app/globals.css defines the identity -- editorial ink, one ochre accent --
and says so in a comment: "No generic AI gradient blue/purple." The bot
pages ignored it and ran a parallel palette, so a single viewport of
/bots/legal-expert showed a blue logo, a blue nav button and an ochre CTA
at the same time.
There were four colour sources, not two:
lib/config/colors.ts 16-colour accent sets
lib/hooks/navigationConfig its own 5-colour NAV_COLOR_CLASSES
ACCENT_HERO_CLASSES a fifth set (whose green and indigo entries
both set chatBg to 'bg-blue-50' -- it was not
even self-consistent)
raw Tailwind greys text-gray-900 / bg-white / border-gray-200
The six professional bots are Botsmann, so they now wear the brand:
BRAND_ACCENT and BRAND_HERO, plus a single NAV_COLORS scheme. 113 raw
grey/white classes became semantic tokens (text-ink, text-ink-muted,
bg-surface, bg-paper, border-edge). The page ground is bg-paper, matching
the homepage instead of flat white.
The 'B' mark in BotNavigation was literally
`bg-gradient-to-r from-blue-600 to-purple-600` -- the exact thing globals.css
forbids by name. It now renders the shared <Logo>, so it cannot drift again.
Per-bot accentColor is gone from the first-party config and its plumbing.
The per-colour sets STAY for user-created bots: custom_bots.accent_color is
a real column with a CHECK constraint and the owner picks it. That is user
data, not a design token.
Also deleted components/shared/BotPageTemplate.tsx -- nothing imported it.
Not in this change: /try, /enterprise, /bots and /knowledge still carry
blue/purple gradients (72 files match the raw palette). Same class, separate
pass, so this one stays reviewable.
verify: format, lint, typecheck, 240 tests, build -- all green. Verified
visually against a local production build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG
github-actions Bot
pushed a commit
that referenced
this pull request
Aug 28, 2026
) #144 put the bot pages on the brand. This does the other 60 files, so the whole product reads as one thing, and adds the guard that keeps it that way. ~410 raw palette classes became semantic tokens across the public marketing surface (/try, /enterprise, /about, /knowledge, /personal, /professionals, /bots, blog, navigation) and the app internals (dashboard, documents, chat, conversations, onboarding, auth, settings, profile). Gradient text is gone. Fifteen headings were `bg-gradient-to-r from-X to-Y bg-clip-text text-transparent`; they are now solid text-ink or text-action. globals.css says the identity is carried by typography, and a serif display does not need a gradient to do that. The 'B' mark was still a blue/purple gradient in BotNavigation's MOBILE menu. #144 only fixed the desktop header. Both now render the shared <Logo>. Three defects introduced mid-sweep and corrected, all caught by reading the diff rather than trusting the regex: - degenerate gradients (`from-action-tint to-action-tint`) collapsed to solid - dead hovers (tint on tint) rebased to bg-surface + hover:bg-action-tint - `to-action\b` matched the prefix of `to-action-hover`, so a collapse left a stray `bg-action-hover` as a BASE background in 11 places -- those are the primary, not the hover shade Deliberately NOT changed: - components/knowledge/Callout.tsx -- its blue is the `info` half of an info/warning/error triad. Semantic status colour is a separate scale from the brand accent, and warning is amber, so ochre-ing info would make the two nearly indistinguishable. - the custom-bot surfaces -- custom_bots.accent_color is a real column with a CHECK constraint and the owner picks it. User data, not a design token. Never-twice: tests/__tests__/lib/design-tokens.test.ts refuses any raw brand-palette class, and any bg-clip-text, outside those two documented exceptions. Mutation-verified -- swap one token back to bg-blue-600 and it fails and names the file. No allowlist debt: every other file was swept rather than excused. verify: format, lint, typecheck, 256 tests, build -- all green. Twelve pages smoke-tested and checked visually against a local production build. Claude-Session: https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG Co-authored-by: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Aug 28, 2026
…ssed it (#149) #148 shipped with the guard passing and the homepage still emitting bg-blue-100, text-indigo-600, bg-purple-100. Both were true, because the guard only walked app/ and components/. The palette was in data/professionals.ts -- its own getAccentColorClasses, giving each of the six first-party professionals a colour (blue, green, indigo, red, amber, purple). Same mistake as the bots in #144, in the one directory the scanner did not read. That is the whole lesson: a source scanner is blind in exactly the shapes you forget to look at, so its first clean run proves nothing. - the six professionals now use the brand, like the six bots - the guard walks data/ and lib/ too - data/menuItems.ts lost a blue/purple gradient Two files are now DOCUMENTED exceptions rather than debt, because their colour is categorical and has to stay mutually distinguishable: lib/constants.ts document status -- pending yellow, processing blue, ready green, error red. Recolouring "processing" to ochre would make state read as brand chrome. lib/infrastructure/providers.ts per-provider identity, so Ollama and OpenAI are tellable apart at a glance. Both sit alongside Callout.tsx's info/warning/error triad, each with its reason written next to it. verify: format, lint, typecheck, 256 tests, build -- all green. Homepage confirmed to emit no raw palette class at all. Claude-Session: https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG Co-authored-by: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Aug 28, 2026
#144 branded the bot page sections. It did not reach the demo underneath them, so every first-party bot still ran the per-colour palette in its interactive step -- the buttons, focus rings, progress dots, message bubbles, dropzone and context panel -- plus the bot switcher in the nav. The colour came from lib/demo/botDemoConfigs.ts, which carried its own accentColor per bot (blue, green, red, indigo, amber). That is the sixth place a colour was chosen, after: globals.css, lib/config/colors.ts, lib/hooks/navigationConfig.ts, ACCENT_HERO_CLASSES, and data/professionals.ts. DemoSection and BotSwitcher are used ONLY by the first-party bot pages (verified: no custom-bot page imports either), so both are now brand: BRAND_BUTTON, BRAND_FOCUS_RING, BRAND_STARTER, BRAND_CHECKBOX, BRAND_PROGRESS, BRAND_MESSAGE, BRAND_DROPZONE, BRAND_CONTEXT_PANEL, BRAND_SWITCHER. accentColor is gone from the demo config, its type, and the whole prop chain. What still emits raw palette, correctly: VISION_STATUS_CONFIG roadmap status -- completed green, in-progress blue, planned amber, vision purple. Four states that have to stay tellable apart; collapsing them to ochre would destroy the information. the /personal templates per-template identity in the memorial/legends product, chosen from an allowlisted surface. Both live behind lib/config/colors.ts, which the guard already documents as an exception -- so the guard passing while those classes ship is correct, not a blind spot. The blind spot was data/professionals.ts, fixed in #149. verify: format, lint, typecheck, 256 tests, build -- all green. Bot demo confirmed ochre end to end against a local production build. Claude-Session: https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG Co-authored-by: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
app/globals.cssdefines the identity — editorial ink, one ochre accent — and states it outright:The bot pages ran a parallel palette anyway. A single viewport of
/bots/legal-expertshowed a blue logo, a blue nav button and an ochre CTA at the same time.Four colour sources, not two
lib/config/colors.tslib/hooks/navigationConfig.tsNAV_COLOR_CLASSESACCENT_HERO_CLASSESgreenandindigoentries both setchatBg: 'bg-blue-50', so it wasn't even self-consistenttext-gray-900,bg-white,border-gray-200…The
Bmark inBotNavigationwas literallybg-gradient-to-r from-blue-600 to-purple-600— the exact thingglobals.cssforbids by name.The fix
The six professional bots are Botsmann, so they wear the brand: one
BRAND_ACCENT, oneBRAND_HERO, oneNAV_COLORS. 113 raw grey/white classes became semantic tokens (text-ink,text-ink-muted,bg-surface,bg-paper,border-edge). Page ground isbg-paper, matching the homepage. TheBmark now renders the shared<Logo>, so it can't drift again.BotPageTemplate.tsxdeleted — nothing imported it.What deliberately stays
The per-colour sets remain for user-created bots.
custom_bots.accent_coloris a real column with aCHECKconstraint and the owner picks it — that's user data, not a design token. Removing it would need a migration and would take a feature away.Not in this PR
/try,/enterprise,/botsand/knowledgestill carry blue/purple gradients — 72 files match the raw palette. Same class, separate pass, so this one stays reviewable.Verify
format:check,lint,typecheck, 240 tests,build— all green. Verified visually against a local production build: blackBmatching the homepage, ochre nav and CTA, warm paper ground, ochre-tinted chat panel.🤖 Generated with Claude Code
https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG