colorsbymax 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +115 -110
- package/README.md +488 -482
- package/dist/{ThemeSwitcher-DB_-2YB8.js → ThemeSwitcher-BFOWqFUZ.js} +74 -14
- package/dist/auto.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,482 +1,488 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/hero.svg" alt="colorsbymax by mrmaxdesigns: re-colour any website, live." width="880">
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<p align="center">
|
|
6
|
-
<a href="https://www.npmjs.com/package/colorsbymax"><img src="https://img.shields.io/npm/v/colorsbymax?style=flat-square&color=0d6b84&label=colorsbymax" alt="colorsbymax on npm"></a>
|
|
7
|
-
<a href="https://www.npmjs.com/package/colorsbymax-mcp"><img src="https://img.shields.io/npm/v/colorsbymax-mcp?style=flat-square&color=7c3aed&label=colorsbymax-mcp" alt="colorsbymax-mcp on npm"></a>
|
|
8
|
-
<img src="https://img.shields.io/badge/React-18%20%7C%2019-be185d?style=flat-square" alt="React 18 or 19">
|
|
9
|
-
<img src="https://img.shields.io/badge/types-included-15803d?style=flat-square" alt="TypeScript types included">
|
|
10
|
-
<a href="LICENSE"><img src="https://img.shields.io/badge/licence-MIT-c2410c?style=flat-square" alt="MIT licence"></a>
|
|
11
|
-
</p>
|
|
12
|
-
|
|
13
|
-
<p align="center"><strong><a href="https://mrmaxdesigns.com/colorsbymax">See it live at mrmaxdesigns.com/colorsbymax →</a></strong><br>Open the colour button on the page and re-colour the whole site.</p>
|
|
14
|
-
|
|
15
|
-
A floating theme switcher for websites. Visitors (or the site's owner) can re-colour the whole site instantly: pick one of the site's own themes, a hand-tuned pick, or one of 715 library themes in 14 categories; build and share custom palettes; or override single colours. Every theme is checked against the Web Content Accessibility Guidelines (WCAG) contrast rules, with one-click fixes.
|
|
16
|
-
|
|
17
|
-
<p align="center">
|
|
18
|
-
<a href="#at-a-glance"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-start.svg" alt="1. Get started" height="36"></a>
|
|
19
|
-
<a href="#coding-agents-mcp"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-agents.svg" alt="2. Coding agents" height="36"></a>
|
|
20
|
-
<a href="#features"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-inside.svg" alt="3. Features" height="36"></a>
|
|
21
|
-
<a href="#add-it-to-a-site"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-control.svg" alt="4. Full control" height="36"></a>
|
|
22
|
-
<a href="#finished-keep-your-colours-and-hide-the-switcher"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-ship.svg" alt="5. Ship it" height="36"></a>
|
|
23
|
-
<a href="#building-the-package"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-hood.svg" alt="6. Under the hood" height="36"></a>
|
|
24
|
-
</p>
|
|
25
|
-
|
|
26
|
-
<br>
|
|
27
|
-
|
|
28
|
-
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-start.svg" alt="01 · Get started: two steps to a live colour switcher" width="100%">
|
|
29
|
-
|
|
30
|
-
## At a glance
|
|
31
|
-
|
|
32
|
-
- **Two steps.** `npm install colorsbymax`, then `import 'colorsbymax/auto'` once. The colour button appears and visitors can re-colour the site, even if its colours are hard-coded (see [Quick start](#quick-start)).
|
|
33
|
-
- **React 18 or 19.**
|
|
34
|
-
- **Tailwind optional.** The panel carries its own styles, so it works with Tailwind v4, older Tailwind or plain CSS. Your site only needs to paint its colours with `var(--color-…)` variables. The optional `colorsbymax/tokens.css` helper is for Tailwind v4 (`@theme` syntax); without Tailwind v4, define the variables yourself.
|
|
35
|
-
- **TypeScript types included.**
|
|
36
|
-
- **No runtime dependencies** besides React. PDF uploads are opt-in and need `pdfjs-dist` (see [PDF uploads](#pdf-uploads)).
|
|
37
|
-
- **ESM only.** Import it from a bundler or `import()`; `require('colorsbymax')` from CommonJS isn't supported.
|
|
38
|
-
- **The colour tools work on their own too.** `contrastRatio`, `checkTheme`, `suggestFix`, `fixAll`, `themeFromPalette`, `darkTokens` and the rest are plain functions with no UI.
|
|
39
|
-
|
|
40
|
-
## Quick start
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npm install colorsbymax
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Then add one line anywhere in your site's code, for example `main.jsx`:
|
|
47
|
-
|
|
48
|
-
```js
|
|
49
|
-
import 'colorsbymax/auto'
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
That's all. The colour button appears in the bottom-right corner once the page has loaded, and visitors can start swapping the site's colours. (npm doesn't let a package change your site on install, so this one line is the only step.)
|
|
53
|
-
|
|
54
|
-
- **Any site's colours.** If your site doesn't use colorsbymax's colour variables, colorsbymax reads the colours actually on the page (backgrounds, text, borders, gradients and icons) and swaps each for its counterpart in the chosen theme: greys follow the theme's background and text, brand shades follow its brand colour, and success and error colours keep their meaning. Content added later is re-coloured too, and picking the site's own theme brings back the exact original.
|
|
55
|
-
- **Settings.** Use `autoMount` instead of the plain import:
|
|
56
|
-
|
|
57
|
-
```js
|
|
58
|
-
import { autoMount } from 'colorsbymax/auto'
|
|
59
|
-
autoMount({ siteName: 'My site', storageKey: 'my-site-theme' })
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
- **Logos keep their own colours** unless a visitor turns on "Colour the logo too" in settings. Mark your logo with `data-colorsbymax-logo` if colorsbymax doesn't find it (it looks for "logo" in a class, id or label).
|
|
63
|
-
- **Where automatic re-colouring falls short:** images keep their colours, hover and focus colours keep the site's own, and colours drawn by `::before`/`::after` aren't swapped. For full control, use the colour variables below; colorsbymax then applies themes to them directly, with no page reading at all.
|
|
64
|
-
|
|
65
|
-
Already installed it? Get the newest version with `npm install colorsbymax@latest` (see [Updating](#updating)).
|
|
66
|
-
|
|
67
|
-
## Try the demo
|
|
68
|
-
|
|
69
|
-
colorsbymax's home, **[mrmaxdesigns.com/colorsbymax](https://mrmaxdesigns.com/colorsbymax)**, is the demo: open the colour button and the whole page re-colours. To run it locally:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
npm install
|
|
73
|
-
npm run dev
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
This serves `demo/`, the same site: built with Tailwind, where every colour is a token, and every token group is used. Its sections are in `demo/site/`.
|
|
77
|
-
|
|
78
|
-
<br>
|
|
79
|
-
|
|
80
|
-
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-agents.svg" alt="02 · Coding agents: let Claude, Cursor or Copilot do it" width="100%">
|
|
81
|
-
|
|
82
|
-
## Coding agents (MCP)
|
|
83
|
-
|
|
84
|
-
Your coding agent can set colorsbymax up and use it for you. [colorsbymax-mcp](mcp/) is an [MCP](https://modelcontextprotocol.io) server that gives Claude Code, Cursor, GitHub Copilot, Codex, Google Antigravity, Gemini CLI, Grok Build, Claude Desktop, Windsurf, Kiro, Zed, JetBrains, Cline, opencode and other agents colorsbymax's own tools:
|
|
85
|
-
|
|
86
|
-
| The agent can… | Tool |
|
|
87
|
-
| --- | --- |
|
|
88
|
-
| Look at your project and add colorsbymax the right way for its framework: Vite, Next.js, Remix, Gatsby, Astro, Nuxt, SvelteKit, Vue, Svelte or plain HTML | `setup_plan` |
|
|
89
|
-
| Find themes by mood, category or closeness to your brand colour, in light or dark | `find_themes`, `get_theme` |
|
|
90
|
-
| Build a complete, accessible theme around your brand colours | `theme_from_colours` |
|
|
91
|
-
| Check contrast and suggest the smallest fixes | `check_contrast` |
|
|
92
|
-
| Make your chosen colours the default and hide the switcher in production, or remove colorsbymax and keep them | `finish` |
|
|
93
|
-
| Read these docs and the full TypeScript API | `docs` |
|
|
94
|
-
|
|
95
|
-
It reads your project but never changes it: the agent makes the edits, so you review them as usual. It runs with `npx`, so there's nothing to install first (Node 18 or later).
|
|
96
|
-
|
|
97
|
-
**Adding the server doesn't change your site by itself.** It gives your agent the tools; the agent then sets colorsbymax up when you ask:
|
|
98
|
-
|
|
99
|
-
1. **Add the server** once, with the steps for your editor below.
|
|
100
|
-
2. **Start a new chat or session** in your project. Agents load MCP servers when a session starts, so one that was already open won't see it yet.
|
|
101
|
-
3. **Ask:** *"Add colorsbymax to this project."* The agent installs the package and adds the one line (or the right version of it for your framework).
|
|
102
|
-
4. **Run your site** (for example `npm run dev`). The colour button appears in the bottom-right corner.
|
|
103
|
-
|
|
104
|
-
### Claude Code
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
claude mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
That adds it for you in this project. Add `--scope user` to have it in every project, or `--scope project` to share it with your team through a `.mcp.json` file. Check it with `/mcp` inside Claude Code.
|
|
111
|
-
|
|
112
|
-
If your terminal says `claude` isn't found (the desktop app doesn't always put it on your PATH), ask Claude Code itself: *"Add the colorsbymax MCP server: `npx -y colorsbymax-mcp`."*
|
|
113
|
-
|
|
114
|
-
### Cursor
|
|
115
|
-
|
|
116
|
-
Add this to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for every project:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"mcpServers": {
|
|
121
|
-
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
It then shows under **Settings → MCP**, and Cursor's agent uses it when you ask about colours or themes.
|
|
127
|
-
|
|
128
|
-
### VS Code (GitHub Copilot)
|
|
129
|
-
|
|
130
|
-
Add this to `.vscode/mcp.json`, then use it from Copilot Chat in **Agent** mode:
|
|
131
|
-
|
|
132
|
-
```json
|
|
133
|
-
{
|
|
134
|
-
"servers": {
|
|
135
|
-
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Claude Desktop
|
|
141
|
-
|
|
142
|
-
Open **Settings → Developer → Edit Config**, add the same `mcpServers` entry as Cursor to `claude_desktop_config.json`, and restart Claude Desktop.
|
|
143
|
-
|
|
144
|
-
### GitHub Copilot CLI
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
copilot mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Or type `/mcp add` inside `copilot`. It's saved to `~/.copilot/mcp-config.json`.
|
|
151
|
-
|
|
152
|
-
### Codex (OpenAI)
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
codex mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
It's saved to `~/.codex/config.toml`, which the Codex IDE extension shares. To write it by hand:
|
|
159
|
-
|
|
160
|
-
```toml
|
|
161
|
-
[mcp_servers.colorsbymax]
|
|
162
|
-
command = "npx"
|
|
163
|
-
args = ["-y", "colorsbymax-mcp"]
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Google Antigravity
|
|
167
|
-
|
|
168
|
-
In the agent panel, open **… → MCP Servers → Manage MCP Servers → View raw config**, add the same `mcpServers` entry as Cursor to `~/.gemini/config/mcp_config.json`, and save. Antigravity reloads it by itself. For one project, use `.agents/mcp_config.json`. In the Antigravity CLI, `/mcp` opens the same manager.
|
|
169
|
-
|
|
170
|
-
### Gemini CLI
|
|
171
|
-
|
|
172
|
-
Add the same `mcpServers` entry as Cursor to `~/.gemini/settings.json` (or `.gemini/settings.json` in your project), restart Gemini CLI, and check it with `/mcp`.
|
|
173
|
-
|
|
174
|
-
### Grok Build (xAI)
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
grok mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
It's saved to `~/.grok/config.toml`; add `--scope project` for `.grok/config.toml`. The first start downloads the server, so if it times out, raise `startup_timeout_sec` for it in that file.
|
|
181
|
-
|
|
182
|
-
### Windsurf, Kiro, JetBrains, Cline and Roo
|
|
183
|
-
|
|
184
|
-
They take the same `mcpServers` entry as Cursor:
|
|
185
|
-
|
|
186
|
-
- **Windsurf:** `~/.codeium/windsurf/mcp_config.json`
|
|
187
|
-
- **Kiro:** `.kiro/settings/mcp.json` in your project, or `~/.kiro/settings/mcp.json`. Kiro doesn't read your shell's PATH, so use the full path to `npx` if it can't start.
|
|
188
|
-
- **JetBrains:** AI Assistant under **Settings → Tools → AI Assistant → Model Context Protocol (MCP)**; Junie under **Settings → Tools → Junie → MCP Settings**.
|
|
189
|
-
- **Cline and Roo Code:** in the extension's **MCP Servers** view, choose **Configure** (or **Edit MCP Settings**).
|
|
190
|
-
|
|
191
|
-
### Zed and opencode
|
|
192
|
-
|
|
193
|
-
Zed calls them context servers. In `settings.json`, or through **Settings → AI → MCP Servers → Add Server**:
|
|
194
|
-
|
|
195
|
-
```json
|
|
196
|
-
{
|
|
197
|
-
"context_servers": {
|
|
198
|
-
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
opencode, in `opencode.json`:
|
|
204
|
-
|
|
205
|
-
```json
|
|
206
|
-
{
|
|
207
|
-
"mcp": {
|
|
208
|
-
"colorsbymax": { "type": "local", "command": ["npx", "-y", "colorsbymax-mcp"] }
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### Any other MCP client
|
|
214
|
-
|
|
215
|
-
Most take the same `mcpServers` entry as Cursor: the command is `npx`, with `-y colorsbymax-mcp` as its arguments.
|
|
216
|
-
|
|
217
|
-
On Windows, if an editor can't start `npx`, use `"command": "cmd"` with `"args": ["/c", "npx", "-y", "colorsbymax-mcp"]`.
|
|
218
|
-
|
|
219
|
-
### What to ask
|
|
220
|
-
|
|
221
|
-
- *"Add colorsbymax to this project."*
|
|
222
|
-
- *"Find me a calm ocean theme that also works in dark mode."*
|
|
223
|
-
- *"Build a theme around our brand colours #e63946 and #1d3557, and check its contrast."*
|
|
224
|
-
- *"Does white text pass on #f59e0b?"*
|
|
225
|
-
- *"I've picked my colours in the panel. Make them the default and hide the switcher in production."* Paste the theme from the panel's **Import / export**, or name the theme.
|
|
226
|
-
|
|
227
|
-
### Without MCP
|
|
228
|
-
|
|
229
|
-
Any coding agent can still do it from a prompt. Paste this into Claude, Cursor, Copilot or another agent:
|
|
230
|
-
|
|
231
|
-
> Install the colorsbymax npm package in this project and add `import 'colorsbymax/auto'` to the app's entry file, so the colorsbymax colour button appears on every page. For Next.js, Remix or other server-rendered apps, load it in the browser only, with `import('colorsbymax/auto')` inside a `useEffect`. Follow https://github.com/MaxMuyalwa/colorsbymax#quick-start and don't change anything else.
|
|
232
|
-
|
|
233
|
-
When you're done choosing colours, the panel's **I'm done** button gives you ready-made prompts for keeping your colours, hiding the switcher or removing it (see [Finished?](#finished-keep-your-colours-and-hide-the-switcher)).
|
|
234
|
-
|
|
235
|
-
<br>
|
|
236
|
-
|
|
237
|
-
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-inside.svg" alt="03 · What's inside: everything in the panel" width="100%">
|
|
238
|
-
|
|
239
|
-
## Features
|
|
240
|
-
|
|
241
|
-
- **Site themes first.** The panel opens on a group named after the site, holding its own colours. If those fail contrast, an accessible version is generated automatically.
|
|
242
|
-
- **Scan the site.** Press "Scan site" and colorsbymax reads the colours actually painted on the page (ignoring any theme it has applied, and including gradients). It works out the page background, surfaces, text and brand colours, then adds themes named after the site: Scanned (as found), Accessible, Soft, Bold, Complementary, and the closest library matches. Scans run only when asked, and the results are remembered.
|
|
243
|
-
- **Max’s picks and library.** 5 hand-tuned picks, plus 715 library themes (Bright, Fun, Pastel, Earth tones, Summer, Autumn, Winter, Spring, Ocean, Warm, Nature, Moody, Monochrome, Eclectic) with search and "Surprise me". The library loads only when the panel opens.
|
|
244
|
-
- **Custom palettes, single-colour overrides, JSON
|
|
245
|
-
- **Palettes from images and PDFs.** In Import / export, upload or drop a mood board, screenshot or photo, or paste one straight from the clipboard: take a screenshot, open the panel and press Ctrl+V (⌘V on a Mac), or use **Paste image**. colorsbymax picks out its main colours, lets you leave any out, previews the palette it builds around them and saves it as a custom palette. Nothing leaves the browser. PDFs, such as brand guides, work where the site [turns them on](#pdf-uploads); hex codes written in a PDF take priority.
|
|
246
|
-
- **Contrast checks.** Problems show as a badge on the theme; the breakdown offers per-item fixes or "Fix all automatically", which changes lightness only.
|
|
247
|
-
- **No flash on reload.** An inline pre-paint script applies the saved theme before the page draws.
|
|
248
|
-
- **Works on any site.** The panel carries its own stylesheet inside a shadow root, so it needs no Tailwind or other CSS from the site, and the site's CSS can't restyle it.
|
|
249
|
-
- **Movable colour button.** The floating button starts in the corner; visitors can drag it anywhere (mouse or touch; a tooltip says so on hover, and an open panel moves with it) and it stays there, remembered across reloads. The panel then opens beside it, on whichever side has room. Its dot cycles through the current theme's colours.
|
|
250
|
-
- **Light and dark mode, for any site.** Every built-in theme is designed light and has a generated dark twin (dark surfaces, light text, brand colours lifted until they read on dark, then contrast-checked). Switching to Dark, one click in the panel's header, turns the whole site dark, even one that never had a dark mode. Auto follows the visitor's device, and a light and dark switch can go anywhere on the site (see [Dark mode](#dark-mode)). Custom palettes stay as they were made.
|
|
251
|
-
- **Visitor settings.** The gear in the panel header opens settings: theme mode (Light, Dark, Auto), panel size (Compact, Standard, Large), which groups and sections to show, whether the button can be dragged or its dot animates, and moving the button back to its corner. Saved per site.
|
|
252
|
-
- **Resizable panel.** Drag the panel's free edges or corner (the ones away from the colour button) to any size, or pick a size in settings; double-click an edge to reset it. The layout follows the panel's width, so a large panel shows three theme cards a row.
|
|
253
|
-
- **Audit the page.** The **Audit** button in the panel header looks at the page in the chosen colours and pins notes to what won't look right: a logo that disappears against its background (with a one-click "Colour the logo", or tips when it's a picture colorsbymax can't re-colour, plus "Preview inverted"), pictures whose solid background shows as a box, and text or icons too faint to read. The notes stay on the page as you scroll; **Re-check** after a fix (it also re-checks when the colours change) and close it from its bar.
|
|
254
|
-
- **Clear groups and feedback.** The site's own group (globe), Max’s picks (paintbrush) and Yours (person) sit in their own row, apart from the library's categories. Toasts confirm what just happened; saving, importing or building a palette says it went to Yours and offers "Show" to jump straight to it. Tooltips are drawn in the panel's colours.
|
|
255
|
-
- **Themed scrollbars.** The page's scrollbars and the panel's slim one take the selected theme's primary colour. Turn the page's off with `scrollbars: false`.
|
|
256
|
-
- **Accessible panel.** A labelled dialog with focus trap, Escape, the colour button or an outside click to close, keyboard operable, and reduced-motion support.
|
|
257
|
-
|
|
258
|
-
## How it works
|
|
259
|
-
|
|
260
|
-
Every colour is one of 35 tokens (`primary`, `surface`, `ink`, `data-1`…), exposed as `--color-<token>` CSS variables. Applying a theme just sets those variables on `<html>`, so anything the site paints with `var(--color-primary)` (directly, or through Tailwind CSS v4 utilities like `bg-primary`) changes instantly. There's no rebuild and no re-render.
|
|
261
|
-
|
|
262
|
-
The switcher renders into a `<colorsbymax-root>` element on `<body>` with its own shadow root and stylesheet. Only the `--color-*` variables cross into it. With reduced motion, the colour button's dot holds still on the theme's primary colour.
|
|
263
|
-
|
|
264
|
-
<br>
|
|
265
|
-
|
|
266
|
-
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-control.svg" alt="04 · Full control: paint with colour tokens" width="100%">
|
|
267
|
-
|
|
268
|
-
## Add it to a site
|
|
269
|
-
|
|
270
|
-
This is the full setup, for sites that want exact control over which colour goes where. colorsbymax needs React 18 or 19, and ships as plain JavaScript with TypeScript types, so Vite, Next.js, webpack and other bundlers use it without extra setup:
|
|
271
|
-
|
|
272
|
-
1. **Paint the site with the token variables.** Use `var(--color-<token>)` wherever the site sets a colour, with your own colours as the starting values.
|
|
273
|
-
|
|
274
|
-
With Tailwind CSS v4, import the defaults (`colorsbymax/tokens.css` is Tailwind v4 syntax), override them, and use the token utilities (`bg-primary`, `text-ink`, …) instead of hard-coded colours:
|
|
275
|
-
|
|
276
|
-
```css
|
|
277
|
-
@import "tailwindcss";
|
|
278
|
-
@import "colorsbymax/tokens.css";
|
|
279
|
-
|
|
280
|
-
@theme static {
|
|
281
|
-
--color-primary: #c67cde; /* your colours */
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
With plain CSS, or Tailwind before v4, define the variables yourself:
|
|
286
|
-
|
|
287
|
-
```css
|
|
288
|
-
:root {
|
|
289
|
-
--color-primary: #c67cde;
|
|
290
|
-
}
|
|
291
|
-
.button {
|
|
292
|
-
background: var(--color-primary);
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
2. **Wrap the app and render the switcher:**
|
|
297
|
-
|
|
298
|
-
```jsx
|
|
299
|
-
import { ThemeProvider, ThemeSwitcher } from 'colorsbymax'
|
|
300
|
-
|
|
301
|
-
<ThemeProvider config={config}>
|
|
302
|
-
<App />
|
|
303
|
-
<ThemeSwitcher />
|
|
304
|
-
</ThemeProvider>
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
The switcher needs React but not a React site: `autoMount` from `colorsbymax/auto` mounts it on its own next to any page.
|
|
308
|
-
|
|
309
|
-
3. **Add the pre-paint script** to `<head>`, as a classic inline `<script>`, using the same storage key. `prePaintScript(storageKey)` returns its source, and `demo/index.html` shows it in place.
|
|
310
|
-
|
|
311
|
-
Without a `siteName`, the site group is named from the page's `og:site_name`, its title or its host name.
|
|
312
|
-
|
|
313
|
-
### Config
|
|
314
|
-
|
|
315
|
-
```js
|
|
316
|
-
{
|
|
317
|
-
siteName: 'Tsungi', // name of the first theme group
|
|
318
|
-
storageKey: 'tsungi-theme', // localStorage key (match the pre-paint script)
|
|
319
|
-
defaultTheme: { name, tokens }, // the site's own colours; missing tokens are filled in
|
|
320
|
-
themes: [{ id, name, tokens }], // optional extra themes made for the site
|
|
321
|
-
usage: { primary: 'Buttons…' }, // optional notes shown in the colour editors
|
|
322
|
-
scrollbars: true, // colour the page's scrollbars from the theme (default)
|
|
323
|
-
pdf: loadPdf, // optional: allow PDF uploads (see below)
|
|
324
|
-
recolour: 'auto', // re-colour hard-coded colours: 'auto' (only if the site has
|
|
325
|
-
// no --color-* variables, the default), true or false
|
|
326
|
-
position: 'bottom-right', // where the button starts: bottom-right (default), bottom-left,
|
|
327
|
-
// top-left, or top-right (just under a floating nav bar)
|
|
328
|
-
hidden: import.meta.env.PROD, // hide the button (the theme still applies), e.g. in production
|
|
329
|
-
defaultMode: 'light', // the mode first-time visitors start in: 'light' (default),
|
|
330
|
-
// 'dark', or 'system' to follow their device
|
|
331
|
-
colourLogo: false, // themes colour the logo too, for first-time visitors (default
|
|
332
|
-
// false: it keeps its own colours); visitors can change it
|
|
333
|
-
features: { scan: false }, // parts of the panel to switch off for everyone (all on by default):
|
|
334
|
-
// picks, library, search, surprise, scan, custom, overrides,
|
|
335
|
-
// importExport, audit, addToSite, colourStyle, colourCount
|
|
336
|
-
colourStyle: 'colourful', // on a site colorsbymax re-colours: 'colourful' (default) paints
|
|
337
|
-
// its header, hero, sections, cards, buttons and footer by role;
|
|
338
|
-
// 'subtle' only swaps the colours it already has
|
|
339
|
-
intro: true, // the button pops in with a burst of the theme's colours a moment
|
|
340
|
-
// after the page loads (default); reduced motion fades it in
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
```bash
|
|
469
|
-
npm run
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
##
|
|
481
|
-
|
|
482
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/hero.svg" alt="colorsbymax by mrmaxdesigns: re-colour any website, live." width="880">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/colorsbymax"><img src="https://img.shields.io/npm/v/colorsbymax?style=flat-square&color=0d6b84&label=colorsbymax" alt="colorsbymax on npm"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/colorsbymax-mcp"><img src="https://img.shields.io/npm/v/colorsbymax-mcp?style=flat-square&color=7c3aed&label=colorsbymax-mcp" alt="colorsbymax-mcp on npm"></a>
|
|
8
|
+
<img src="https://img.shields.io/badge/React-18%20%7C%2019-be185d?style=flat-square" alt="React 18 or 19">
|
|
9
|
+
<img src="https://img.shields.io/badge/types-included-15803d?style=flat-square" alt="TypeScript types included">
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/licence-MIT-c2410c?style=flat-square" alt="MIT licence"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center"><strong><a href="https://mrmaxdesigns.com/colorsbymax">See it live at mrmaxdesigns.com/colorsbymax →</a></strong><br>Open the colour button on the page and re-colour the whole site.</p>
|
|
14
|
+
|
|
15
|
+
A floating theme switcher for websites. Visitors (or the site's owner) can re-colour the whole site instantly: pick one of the site's own themes, a hand-tuned pick, or one of 715 library themes in 14 categories; build and share custom palettes; or override single colours. Every theme is checked against the Web Content Accessibility Guidelines (WCAG) contrast rules, with one-click fixes.
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="#at-a-glance"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-start.svg" alt="1. Get started" height="36"></a>
|
|
19
|
+
<a href="#coding-agents-mcp"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-agents.svg" alt="2. Coding agents" height="36"></a>
|
|
20
|
+
<a href="#features"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-inside.svg" alt="3. Features" height="36"></a>
|
|
21
|
+
<a href="#add-it-to-a-site"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-control.svg" alt="4. Full control" height="36"></a>
|
|
22
|
+
<a href="#finished-keep-your-colours-and-hide-the-switcher"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-ship.svg" alt="5. Ship it" height="36"></a>
|
|
23
|
+
<a href="#building-the-package"><img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/nav-hood.svg" alt="6. Under the hood" height="36"></a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<br>
|
|
27
|
+
|
|
28
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-start.svg" alt="01 · Get started: two steps to a live colour switcher" width="100%">
|
|
29
|
+
|
|
30
|
+
## At a glance
|
|
31
|
+
|
|
32
|
+
- **Two steps.** `npm install colorsbymax`, then `import 'colorsbymax/auto'` once. The colour button appears and visitors can re-colour the site, even if its colours are hard-coded (see [Quick start](#quick-start)).
|
|
33
|
+
- **React 18 or 19.**
|
|
34
|
+
- **Tailwind optional.** The panel carries its own styles, so it works with Tailwind v4, older Tailwind or plain CSS. Your site only needs to paint its colours with `var(--color-…)` variables. The optional `colorsbymax/tokens.css` helper is for Tailwind v4 (`@theme` syntax); without Tailwind v4, define the variables yourself.
|
|
35
|
+
- **TypeScript types included.**
|
|
36
|
+
- **No runtime dependencies** besides React. PDF uploads are opt-in and need `pdfjs-dist` (see [PDF uploads](#pdf-uploads)).
|
|
37
|
+
- **ESM only.** Import it from a bundler or `import()`; `require('colorsbymax')` from CommonJS isn't supported.
|
|
38
|
+
- **The colour tools work on their own too.** `contrastRatio`, `checkTheme`, `suggestFix`, `fixAll`, `themeFromPalette`, `darkTokens` and the rest are plain functions with no UI.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install colorsbymax
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then add one line anywhere in your site's code, for example `main.jsx`:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import 'colorsbymax/auto'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
That's all. The colour button appears in the bottom-right corner once the page has loaded, and visitors can start swapping the site's colours. (npm doesn't let a package change your site on install, so this one line is the only step.)
|
|
53
|
+
|
|
54
|
+
- **Any site's colours.** If your site doesn't use colorsbymax's colour variables, colorsbymax reads the colours actually on the page (backgrounds, text, borders, gradients and icons) and swaps each for its counterpart in the chosen theme: greys follow the theme's background and text, brand shades follow its brand colour, and success and error colours keep their meaning. Content added later is re-coloured too, and picking the site's own theme brings back the exact original.
|
|
55
|
+
- **Settings.** Use `autoMount` instead of the plain import:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
import { autoMount } from 'colorsbymax/auto'
|
|
59
|
+
autoMount({ siteName: 'My site', storageKey: 'my-site-theme' })
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **Logos keep their own colours** unless a visitor turns on "Colour the logo too" in settings. Mark your logo with `data-colorsbymax-logo` if colorsbymax doesn't find it (it looks for "logo" in a class, id or label).
|
|
63
|
+
- **Where automatic re-colouring falls short:** images keep their colours, hover and focus colours keep the site's own, and colours drawn by `::before`/`::after` aren't swapped. For full control, use the colour variables below; colorsbymax then applies themes to them directly, with no page reading at all.
|
|
64
|
+
|
|
65
|
+
Already installed it? Get the newest version with `npm install colorsbymax@latest` (see [Updating](#updating)).
|
|
66
|
+
|
|
67
|
+
## Try the demo
|
|
68
|
+
|
|
69
|
+
colorsbymax's home, **[mrmaxdesigns.com/colorsbymax](https://mrmaxdesigns.com/colorsbymax)**, is the demo: open the colour button and the whole page re-colours. To run it locally:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install
|
|
73
|
+
npm run dev
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This serves `demo/`, the same site: built with Tailwind, where every colour is a token, and every token group is used. Its sections are in `demo/site/`.
|
|
77
|
+
|
|
78
|
+
<br>
|
|
79
|
+
|
|
80
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-agents.svg" alt="02 · Coding agents: let Claude, Cursor or Copilot do it" width="100%">
|
|
81
|
+
|
|
82
|
+
## Coding agents (MCP)
|
|
83
|
+
|
|
84
|
+
Your coding agent can set colorsbymax up and use it for you. [colorsbymax-mcp](mcp/) is an [MCP](https://modelcontextprotocol.io) server that gives Claude Code, Cursor, GitHub Copilot, Codex, Google Antigravity, Gemini CLI, Grok Build, Claude Desktop, Windsurf, Kiro, Zed, JetBrains, Cline, opencode and other agents colorsbymax's own tools:
|
|
85
|
+
|
|
86
|
+
| The agent can… | Tool |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| Look at your project and add colorsbymax the right way for its framework: Vite, Next.js, Remix, Gatsby, Astro, Nuxt, SvelteKit, Vue, Svelte or plain HTML | `setup_plan` |
|
|
89
|
+
| Find themes by mood, category or closeness to your brand colour, in light or dark | `find_themes`, `get_theme` |
|
|
90
|
+
| Build a complete, accessible theme around your brand colours | `theme_from_colours` |
|
|
91
|
+
| Check contrast and suggest the smallest fixes | `check_contrast` |
|
|
92
|
+
| Make your chosen colours the default and hide the switcher in production, or remove colorsbymax and keep them | `finish` |
|
|
93
|
+
| Read these docs and the full TypeScript API | `docs` |
|
|
94
|
+
|
|
95
|
+
It reads your project but never changes it: the agent makes the edits, so you review them as usual. It runs with `npx`, so there's nothing to install first (Node 18 or later).
|
|
96
|
+
|
|
97
|
+
**Adding the server doesn't change your site by itself.** It gives your agent the tools; the agent then sets colorsbymax up when you ask:
|
|
98
|
+
|
|
99
|
+
1. **Add the server** once, with the steps for your editor below.
|
|
100
|
+
2. **Start a new chat or session** in your project. Agents load MCP servers when a session starts, so one that was already open won't see it yet.
|
|
101
|
+
3. **Ask:** *"Add colorsbymax to this project."* The agent installs the package and adds the one line (or the right version of it for your framework).
|
|
102
|
+
4. **Run your site** (for example `npm run dev`). The colour button appears in the bottom-right corner.
|
|
103
|
+
|
|
104
|
+
### Claude Code
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
claude mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
That adds it for you in this project. Add `--scope user` to have it in every project, or `--scope project` to share it with your team through a `.mcp.json` file. Check it with `/mcp` inside Claude Code.
|
|
111
|
+
|
|
112
|
+
If your terminal says `claude` isn't found (the desktop app doesn't always put it on your PATH), ask Claude Code itself: *"Add the colorsbymax MCP server: `npx -y colorsbymax-mcp`."*
|
|
113
|
+
|
|
114
|
+
### Cursor
|
|
115
|
+
|
|
116
|
+
Add this to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for every project:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
It then shows under **Settings → MCP**, and Cursor's agent uses it when you ask about colours or themes.
|
|
127
|
+
|
|
128
|
+
### VS Code (GitHub Copilot)
|
|
129
|
+
|
|
130
|
+
Add this to `.vscode/mcp.json`, then use it from Copilot Chat in **Agent** mode:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"servers": {
|
|
135
|
+
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Claude Desktop
|
|
141
|
+
|
|
142
|
+
Open **Settings → Developer → Edit Config**, add the same `mcpServers` entry as Cursor to `claude_desktop_config.json`, and restart Claude Desktop.
|
|
143
|
+
|
|
144
|
+
### GitHub Copilot CLI
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
copilot mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Or type `/mcp add` inside `copilot`. It's saved to `~/.copilot/mcp-config.json`.
|
|
151
|
+
|
|
152
|
+
### Codex (OpenAI)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
codex mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
It's saved to `~/.codex/config.toml`, which the Codex IDE extension shares. To write it by hand:
|
|
159
|
+
|
|
160
|
+
```toml
|
|
161
|
+
[mcp_servers.colorsbymax]
|
|
162
|
+
command = "npx"
|
|
163
|
+
args = ["-y", "colorsbymax-mcp"]
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Google Antigravity
|
|
167
|
+
|
|
168
|
+
In the agent panel, open **… → MCP Servers → Manage MCP Servers → View raw config**, add the same `mcpServers` entry as Cursor to `~/.gemini/config/mcp_config.json`, and save. Antigravity reloads it by itself. For one project, use `.agents/mcp_config.json`. In the Antigravity CLI, `/mcp` opens the same manager.
|
|
169
|
+
|
|
170
|
+
### Gemini CLI
|
|
171
|
+
|
|
172
|
+
Add the same `mcpServers` entry as Cursor to `~/.gemini/settings.json` (or `.gemini/settings.json` in your project), restart Gemini CLI, and check it with `/mcp`.
|
|
173
|
+
|
|
174
|
+
### Grok Build (xAI)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
grok mcp add colorsbymax -- npx -y colorsbymax-mcp
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
It's saved to `~/.grok/config.toml`; add `--scope project` for `.grok/config.toml`. The first start downloads the server, so if it times out, raise `startup_timeout_sec` for it in that file.
|
|
181
|
+
|
|
182
|
+
### Windsurf, Kiro, JetBrains, Cline and Roo
|
|
183
|
+
|
|
184
|
+
They take the same `mcpServers` entry as Cursor:
|
|
185
|
+
|
|
186
|
+
- **Windsurf:** `~/.codeium/windsurf/mcp_config.json`
|
|
187
|
+
- **Kiro:** `.kiro/settings/mcp.json` in your project, or `~/.kiro/settings/mcp.json`. Kiro doesn't read your shell's PATH, so use the full path to `npx` if it can't start.
|
|
188
|
+
- **JetBrains:** AI Assistant under **Settings → Tools → AI Assistant → Model Context Protocol (MCP)**; Junie under **Settings → Tools → Junie → MCP Settings**.
|
|
189
|
+
- **Cline and Roo Code:** in the extension's **MCP Servers** view, choose **Configure** (or **Edit MCP Settings**).
|
|
190
|
+
|
|
191
|
+
### Zed and opencode
|
|
192
|
+
|
|
193
|
+
Zed calls them context servers. In `settings.json`, or through **Settings → AI → MCP Servers → Add Server**:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"context_servers": {
|
|
198
|
+
"colorsbymax": { "command": "npx", "args": ["-y", "colorsbymax-mcp"] }
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
opencode, in `opencode.json`:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"mcp": {
|
|
208
|
+
"colorsbymax": { "type": "local", "command": ["npx", "-y", "colorsbymax-mcp"] }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Any other MCP client
|
|
214
|
+
|
|
215
|
+
Most take the same `mcpServers` entry as Cursor: the command is `npx`, with `-y colorsbymax-mcp` as its arguments.
|
|
216
|
+
|
|
217
|
+
On Windows, if an editor can't start `npx`, use `"command": "cmd"` with `"args": ["/c", "npx", "-y", "colorsbymax-mcp"]`.
|
|
218
|
+
|
|
219
|
+
### What to ask
|
|
220
|
+
|
|
221
|
+
- *"Add colorsbymax to this project."*
|
|
222
|
+
- *"Find me a calm ocean theme that also works in dark mode."*
|
|
223
|
+
- *"Build a theme around our brand colours #e63946 and #1d3557, and check its contrast."*
|
|
224
|
+
- *"Does white text pass on #f59e0b?"*
|
|
225
|
+
- *"I've picked my colours in the panel. Make them the default and hide the switcher in production."* Paste the theme from the panel's **Import / export**, or name the theme.
|
|
226
|
+
|
|
227
|
+
### Without MCP
|
|
228
|
+
|
|
229
|
+
Any coding agent can still do it from a prompt. Paste this into Claude, Cursor, Copilot or another agent:
|
|
230
|
+
|
|
231
|
+
> Install the colorsbymax npm package in this project and add `import 'colorsbymax/auto'` to the app's entry file, so the colorsbymax colour button appears on every page. For Next.js, Remix or other server-rendered apps, load it in the browser only, with `import('colorsbymax/auto')` inside a `useEffect`. Follow https://github.com/MaxMuyalwa/colorsbymax#quick-start and don't change anything else.
|
|
232
|
+
|
|
233
|
+
When you're done choosing colours, the panel's **I'm done** button gives you ready-made prompts for keeping your colours, hiding the switcher or removing it (see [Finished?](#finished-keep-your-colours-and-hide-the-switcher)).
|
|
234
|
+
|
|
235
|
+
<br>
|
|
236
|
+
|
|
237
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-inside.svg" alt="03 · What's inside: everything in the panel" width="100%">
|
|
238
|
+
|
|
239
|
+
## Features
|
|
240
|
+
|
|
241
|
+
- **Site themes first.** The panel opens on a group named after the site, holding its own colours. If those fail contrast, an accessible version is generated automatically.
|
|
242
|
+
- **Scan the site.** Press "Scan site" and colorsbymax reads the colours actually painted on the page (ignoring any theme it has applied, and including gradients). It works out the page background, surfaces, text and brand colours, then adds themes named after the site: Scanned (as found), Accessible, Soft, Bold, Complementary, and the closest library matches. Scans run only when asked, and the results are remembered.
|
|
243
|
+
- **Max’s picks and library.** 5 hand-tuned picks, plus 715 library themes (Bright, Fun, Pastel, Earth tones, Summer, Autumn, Winter, Spring, Ocean, Warm, Nature, Moody, Monochrome, Eclectic) with search and "Surprise me". The library loads only when the panel opens.
|
|
244
|
+
- **Custom palettes, single-colour overrides, import and export as JSON or CSS.**
|
|
245
|
+
- **Palettes from images and PDFs.** In Import / export, upload or drop a mood board, screenshot or photo, or paste one straight from the clipboard: take a screenshot, open the panel and press Ctrl+V (⌘V on a Mac), or use **Paste image**. colorsbymax picks out its main colours, lets you leave any out, previews the palette it builds around them and saves it as a custom palette. Nothing leaves the browser. PDFs, such as brand guides, work where the site [turns them on](#pdf-uploads); hex codes written in a PDF take priority.
|
|
246
|
+
- **Contrast checks.** Problems show as a badge on the theme; the breakdown offers per-item fixes or "Fix all automatically", which changes lightness only.
|
|
247
|
+
- **No flash on reload.** An inline pre-paint script applies the saved theme before the page draws.
|
|
248
|
+
- **Works on any site.** The panel carries its own stylesheet inside a shadow root, so it needs no Tailwind or other CSS from the site, and the site's CSS can't restyle it.
|
|
249
|
+
- **Movable colour button.** The floating button starts in the corner; visitors can drag it anywhere (mouse or touch; a tooltip says so on hover, and an open panel moves with it) and it stays there, remembered across reloads. The panel then opens beside it, on whichever side has room. Its dot cycles through the current theme's colours.
|
|
250
|
+
- **Light and dark mode, for any site.** Every built-in theme is designed light and has a generated dark twin (dark surfaces, light text, brand colours lifted until they read on dark, then contrast-checked). Switching to Dark, one click in the panel's header, turns the whole site dark, even one that never had a dark mode. Auto follows the visitor's device, and a light and dark switch can go anywhere on the site (see [Dark mode](#dark-mode)). Custom palettes stay as they were made.
|
|
251
|
+
- **Visitor settings.** The gear in the panel header opens settings: theme mode (Light, Dark, Auto), panel size (Compact, Standard, Large), which groups and sections to show, whether the button can be dragged or its dot animates, and moving the button back to its corner. Saved per site.
|
|
252
|
+
- **Resizable panel.** Drag the panel's free edges or corner (the ones away from the colour button) to any size, or pick a size in settings; double-click an edge to reset it. The layout follows the panel's width, so a large panel shows three theme cards a row.
|
|
253
|
+
- **Audit the page.** The **Audit** button in the panel header looks at the page in the chosen colours and pins notes to what won't look right: a logo that disappears against its background (with a one-click "Colour the logo", or tips when it's a picture colorsbymax can't re-colour, plus "Preview inverted"), pictures whose solid background shows as a box, and text or icons too faint to read. The notes stay on the page as you scroll; **Re-check** after a fix (it also re-checks when the colours change) and close it from its bar.
|
|
254
|
+
- **Clear groups and feedback.** The site's own group (globe), Max’s picks (paintbrush) and Yours (person) sit in their own row, apart from the library's categories. Toasts confirm what just happened; saving, importing or building a palette says it went to Yours and offers "Show" to jump straight to it. Tooltips are drawn in the panel's colours.
|
|
255
|
+
- **Themed scrollbars.** The page's scrollbars and the panel's slim one take the selected theme's primary colour. Turn the page's off with `scrollbars: false`.
|
|
256
|
+
- **Accessible panel.** A labelled dialog with focus trap, Escape, the colour button or an outside click to close, keyboard operable, and reduced-motion support.
|
|
257
|
+
|
|
258
|
+
## How it works
|
|
259
|
+
|
|
260
|
+
Every colour is one of 35 tokens (`primary`, `surface`, `ink`, `data-1`…), exposed as `--color-<token>` CSS variables. Applying a theme just sets those variables on `<html>`, so anything the site paints with `var(--color-primary)` (directly, or through Tailwind CSS v4 utilities like `bg-primary`) changes instantly. There's no rebuild and no re-render.
|
|
261
|
+
|
|
262
|
+
The switcher renders into a `<colorsbymax-root>` element on `<body>` with its own shadow root and stylesheet. Only the `--color-*` variables cross into it. With reduced motion, the colour button's dot holds still on the theme's primary colour.
|
|
263
|
+
|
|
264
|
+
<br>
|
|
265
|
+
|
|
266
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-control.svg" alt="04 · Full control: paint with colour tokens" width="100%">
|
|
267
|
+
|
|
268
|
+
## Add it to a site
|
|
269
|
+
|
|
270
|
+
This is the full setup, for sites that want exact control over which colour goes where. colorsbymax needs React 18 or 19, and ships as plain JavaScript with TypeScript types, so Vite, Next.js, webpack and other bundlers use it without extra setup:
|
|
271
|
+
|
|
272
|
+
1. **Paint the site with the token variables.** Use `var(--color-<token>)` wherever the site sets a colour, with your own colours as the starting values.
|
|
273
|
+
|
|
274
|
+
With Tailwind CSS v4, import the defaults (`colorsbymax/tokens.css` is Tailwind v4 syntax), override them, and use the token utilities (`bg-primary`, `text-ink`, …) instead of hard-coded colours:
|
|
275
|
+
|
|
276
|
+
```css
|
|
277
|
+
@import "tailwindcss";
|
|
278
|
+
@import "colorsbymax/tokens.css";
|
|
279
|
+
|
|
280
|
+
@theme static {
|
|
281
|
+
--color-primary: #c67cde; /* your colours */
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
With plain CSS, or Tailwind before v4, define the variables yourself:
|
|
286
|
+
|
|
287
|
+
```css
|
|
288
|
+
:root {
|
|
289
|
+
--color-primary: #c67cde;
|
|
290
|
+
}
|
|
291
|
+
.button {
|
|
292
|
+
background: var(--color-primary);
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
2. **Wrap the app and render the switcher:**
|
|
297
|
+
|
|
298
|
+
```jsx
|
|
299
|
+
import { ThemeProvider, ThemeSwitcher } from 'colorsbymax'
|
|
300
|
+
|
|
301
|
+
<ThemeProvider config={config}>
|
|
302
|
+
<App />
|
|
303
|
+
<ThemeSwitcher />
|
|
304
|
+
</ThemeProvider>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The switcher needs React but not a React site: `autoMount` from `colorsbymax/auto` mounts it on its own next to any page.
|
|
308
|
+
|
|
309
|
+
3. **Add the pre-paint script** to `<head>`, as a classic inline `<script>`, using the same storage key. `prePaintScript(storageKey)` returns its source, and `demo/index.html` shows it in place.
|
|
310
|
+
|
|
311
|
+
Without a `siteName`, the site group is named from the page's `og:site_name`, its title or its host name.
|
|
312
|
+
|
|
313
|
+
### Config
|
|
314
|
+
|
|
315
|
+
```js
|
|
316
|
+
{
|
|
317
|
+
siteName: 'Tsungi', // name of the first theme group
|
|
318
|
+
storageKey: 'tsungi-theme', // localStorage key (match the pre-paint script)
|
|
319
|
+
defaultTheme: { name, tokens }, // the site's own colours; missing tokens are filled in
|
|
320
|
+
themes: [{ id, name, tokens }], // optional extra themes made for the site
|
|
321
|
+
usage: { primary: 'Buttons…' }, // optional notes shown in the colour editors
|
|
322
|
+
scrollbars: true, // colour the page's scrollbars from the theme (default)
|
|
323
|
+
pdf: loadPdf, // optional: allow PDF uploads (see below)
|
|
324
|
+
recolour: 'auto', // re-colour hard-coded colours: 'auto' (only if the site has
|
|
325
|
+
// no --color-* variables, the default), true or false
|
|
326
|
+
position: 'bottom-right', // where the button starts: bottom-right (default), bottom-left,
|
|
327
|
+
// top-left, or top-right (just under a floating nav bar)
|
|
328
|
+
hidden: import.meta.env.PROD, // hide the button (the theme still applies), e.g. in production
|
|
329
|
+
defaultMode: 'light', // the mode first-time visitors start in: 'light' (default),
|
|
330
|
+
// 'dark', or 'system' to follow their device
|
|
331
|
+
colourLogo: false, // themes colour the logo too, for first-time visitors (default
|
|
332
|
+
// false: it keeps its own colours); visitors can change it
|
|
333
|
+
features: { scan: false }, // parts of the panel to switch off for everyone (all on by default):
|
|
334
|
+
// picks, library, search, surprise, scan, custom, overrides,
|
|
335
|
+
// importExport, audit, addToSite, colourStyle, colourCount
|
|
336
|
+
colourStyle: 'colourful', // on a site colorsbymax re-colours: 'colourful' (default) paints
|
|
337
|
+
// its header, hero, sections, cards, buttons and footer by role;
|
|
338
|
+
// 'subtle' only swaps the colours it already has
|
|
339
|
+
intro: true, // the button pops in with a burst of the theme's colours a moment
|
|
340
|
+
// after the page loads (default); reduced motion fades it in
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
A bar pinned above your nav (an announcement, a cookie notice)? Set its height on `<html>` and the colour button and panel make room for it:
|
|
345
|
+
|
|
346
|
+
```js
|
|
347
|
+
document.documentElement.style.setProperty('--colorsbymax-offset-top', `${bar.offsetHeight}px`)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Dark mode
|
|
351
|
+
|
|
352
|
+
Dark mode works on any site: every theme has a dark twin, so choosing Dark (or Auto, on a device set to dark) re-colours the whole page, and text, buttons and icons are checked for contrast on the dark background. It applies on every page load, and keeps working when the switcher is hidden in production.
|
|
353
|
+
|
|
354
|
+
Give visitors a light and dark switch anywhere, styled your way, by marking an element with `data-colorsbymax-mode`:
|
|
355
|
+
|
|
356
|
+
```html
|
|
357
|
+
<button data-colorsbymax-mode="toggle">Light / dark</button>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The panel's **Add to site** button (next to Light, Dark and Auto) previews one in your top bar and gives you ready-made code and an AI-editor prompt. `toggle` switches between light and dark; `light`, `dark` and `system` set one mode. colorsbymax wires the click, remembers the choice and sets `aria-pressed`. The page is marked with the current mode, for anything your CSS wants to adjust, like photos:
|
|
361
|
+
|
|
362
|
+
```css
|
|
363
|
+
html[data-colorsbymax-scheme="dark"] .hero-photo {
|
|
364
|
+
filter: brightness(0.9);
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
With `ThemeProvider`, `useTheme()` gives `mode` ('light' or 'dark'), `modeSetting` (including 'system') and `setMode(mode)`, for building your own switch.
|
|
369
|
+
|
|
370
|
+
### PDF uploads
|
|
371
|
+
|
|
372
|
+
Building a palette from an image works out of the box. PDFs, such as brand guides, need [PDF.js](https://mozilla.github.io/pdf.js/), which is large, so it's opt-in: install it and pass the loader from `colorsbymax/pdf`.
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
npm install pdfjs-dist
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
```jsx
|
|
379
|
+
import { loadPdf } from 'colorsbymax/pdf'
|
|
380
|
+
|
|
381
|
+
<ThemeProvider config={{ ...config, pdf: loadPdf }}>
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
PDF.js still downloads only when a visitor picks a PDF. Sites that don't opt in never install or bundle it, and the upload offers images only.
|
|
385
|
+
|
|
386
|
+
`examples/tsungi.config.js` is a complete example for tsungi.online, the first site to use colorsbymax.
|
|
387
|
+
|
|
388
|
+
<br>
|
|
389
|
+
|
|
390
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-ship.svg" alt="05 · Ship it: keep your colours and go live" width="100%">
|
|
391
|
+
|
|
392
|
+
## Finished? Keep your colours and hide the switcher
|
|
393
|
+
|
|
394
|
+
The colours you pick in the panel are saved only in your own browser. When you're happy with them, press **I'm done** at the bottom of the panel. It shows your colours and three ways to finish, each with code to copy and a prompt you can paste into Claude, Cursor, Copilot or any AI editor. **Cancel, keep using colorsbymax** takes you back without changing anything.
|
|
395
|
+
|
|
396
|
+
### Keep the colours and hide it in production (recommended)
|
|
397
|
+
|
|
398
|
+
Make your pick the site's default for everyone, and keep the button out of production while it still shows when you run the site locally, so you can keep iterating:
|
|
399
|
+
|
|
400
|
+
```js
|
|
401
|
+
// With the one-line setup, replace `import 'colorsbymax/auto'` with:
|
|
402
|
+
import { autoMount } from 'colorsbymax/auto'
|
|
403
|
+
|
|
404
|
+
autoMount({
|
|
405
|
+
defaultTheme: { name: 'Ocean', tokens: { primary: '#0d6b84', /* …every colour… */ } },
|
|
406
|
+
hidden: import.meta.env.PROD,
|
|
407
|
+
})
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
With `ThemeProvider`, add the same `defaultTheme` and `hidden` to its `config`. The panel fills in all your colours for you. Not using Vite? Use `process.env.NODE_ENV === 'production'` in place of `import.meta.env.PROD` (Next.js, webpack).
|
|
411
|
+
|
|
412
|
+
**Bring it back later:** it keeps showing in development. To show it in production again, set `hidden: false` or remove the line, or ask your AI editor: *"Show the colorsbymax colour switcher again in production: in its config, set hidden to false or remove the hidden line."*
|
|
413
|
+
|
|
414
|
+
### Hide it on this device only
|
|
415
|
+
|
|
416
|
+
Hides the button in your browser straight away, with no code change and nothing different for anyone else. **To bring it back**, press **Alt+Shift+C** on the page, or open it with `?colorsbymax` at the end of the address.
|
|
417
|
+
|
|
418
|
+
### Remove colorsbymax
|
|
419
|
+
|
|
420
|
+
1. `npm uninstall colorsbymax`
|
|
421
|
+
2. Delete its import (`import 'colorsbymax/auto'`, `autoMount`, or `ThemeProvider` and `ThemeSwitcher`) and any colorsbymax pre-paint script.
|
|
422
|
+
3. Keep your colours:
|
|
423
|
+
- If your site uses the `--color-*` variables, paste the CSS the panel gives you (`:root { --color-primary: …; … }`) into your global stylesheet.
|
|
424
|
+
- If colorsbymax was re-colouring hard-coded colours for you, the chosen colours only exist while it runs, so your CSS needs updating to them. The panel's prompt asks your AI editor to do that.
|
|
425
|
+
|
|
426
|
+
To bring it back later, install it again and follow the [Quick start](#quick-start).
|
|
427
|
+
|
|
428
|
+
## Updating
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
npm install colorsbymax@latest
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
This moves you to the newest release and records it in your `package.json`. `npm update` alone isn't enough while colorsbymax is below 1.0: with the usual `^0.1.0` range, npm treats 0.2.0 as a breaking change and stays on 0.1.x. Check which version you have with `npm ls colorsbymax`.
|
|
435
|
+
|
|
436
|
+
If it still installs the old version right after a release, npm is using its cached list of versions; add `--prefer-online` to check the registry:
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
npm install colorsbymax@latest --prefer-online
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
What changed in each release, and anything you need to do when upgrading, is in [CHANGELOG.md](CHANGELOG.md).
|
|
443
|
+
|
|
444
|
+
<br>
|
|
445
|
+
|
|
446
|
+
<img src="https://raw.githubusercontent.com/MaxMuyalwa/colorsbymax/main/docs/readme/section-hood.svg" alt="06 · Under the hood: build, regenerate, contribute" width="100%">
|
|
447
|
+
|
|
448
|
+
## Building the package
|
|
449
|
+
|
|
450
|
+
`src/` is the source; `dist/` is what sites install: plain JavaScript with the JSX compiled away. `types/` holds the hand-written TypeScript declarations; `npm run typecheck` compiles `types/check.tsx` against them and checks they match the built exports. The panel's icons are copied from Lucide into `src/icons.jsx` by `npm run icons`. `dist/` is committed so installs straight from GitHub work even when npm skips install scripts, so rebuild it before committing changes to `src/`. `npm publish` also rebuilds it first:
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
npm run build
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## README artwork
|
|
457
|
+
|
|
458
|
+
The hero, the section banners and the navigation chips are SVGs in `docs/readme/`, drawn by `scripts/make-readme-art.mjs` from colorsbymax's own themes:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
node scripts/make-readme-art.mjs
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
## Panel styles
|
|
465
|
+
|
|
466
|
+
The panel is styled with Tailwind classes in `src/ThemePanel.jsx` and `src/ThemeSwitcher.jsx`. `scripts/build-css.mjs` compiles them, with `src/panel.css`, into `src/panel-css.generated.js`. The demo server does this automatically as you edit; otherwise run:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
npm run css
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Regenerating the library
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
npm run presets
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
`scripts/generate-presets.mjs` turns each source palette into a full theme, auto-fixes contrast, drops anything that still fails or duplicates another theme, names it and tags its categories. Adjust the category rules at the top of the script.
|
|
479
|
+
|
|
480
|
+
## Notices
|
|
481
|
+
|
|
482
|
+
The library palettes come from [nice-color-palettes](https://github.com/Jam3/nice-color-palettes) (MIT). Its licence notice is in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) and must ship with every copy.
|
|
483
|
+
|
|
484
|
+
PDF reading uses [pdfjs-dist](https://github.com/mozilla/pdf.js) (Apache-2.0), installed as a dependency rather than bundled into colorsbymax.
|
|
485
|
+
|
|
486
|
+
## Licence
|
|
487
|
+
|
|
488
|
+
colorsbymax is released under the [MIT Licence](LICENSE). The names colorsbymax™ and mrmaxdesigns are marks of Max Muyalwa and aren't covered by the code licence.
|