claude-code-memory-explorer 0.14.1 → 0.15.0-rc.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/README.md +49 -17
- package/lib/net-guard.js +20 -3
- package/package.json +1 -1
- package/public/style.css +1 -1
- package/public/themes.css +49 -47
package/README.md
CHANGED
|
@@ -4,38 +4,70 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/claude-code-memory-explorer)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
See every memory file that Claude Code loads for a project, and let Claude find what is stale, false, or in conflict.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**[Documentation](https://nikiforovall.blog/claude-code-memory/)**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<picture>
|
|
12
|
+
<source media="(prefers-color-scheme: dark)" srcset="website/public/shots/themes/ember-h3-hub-memory-dark.webp">
|
|
13
|
+
<img alt="Memory Diagnoser with memory files grouped by user, project, rules, auto memory, and agent memory, the project CLAUDE.md open with four findings, and the summary cards at the bottom" src="website/public/shots/themes/ember-h3-hub-memory-light.webp">
|
|
14
|
+
</picture>
|
|
12
15
|
|
|
13
|
-
## Getting
|
|
16
|
+
## Getting started
|
|
17
|
+
|
|
18
|
+
You need Node.js 20 or later. Open a terminal in your project directory and run:
|
|
14
19
|
|
|
15
20
|
```bash
|
|
16
21
|
npx claude-code-memory-explorer --open
|
|
17
22
|
```
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
The app scans the memory files for the current directory and opens the page in your browser. The default port is 3544. You do not need a config file. Browsing changes nothing on disk.
|
|
25
|
+
|
|
26
|
+
To run an analysis, you also need Claude Code, installed and logged in. See [Getting started](https://nikiforovall.blog/claude-code-memory/getting-started/).
|
|
20
27
|
|
|
21
28
|
## Features
|
|
22
29
|
|
|
23
|
-
- **Full memory stack
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
30
|
+
- **Full memory stack.** Managed policy, user and project `CLAUDE.md` files (including `CLAUDE.local.md` and nested files in subdirectories), user and project rules, project skills, auto memory, agent memory, and the files they import or link, in one tree. See [What Claude Code loads](https://nikiforovall.blog/claude-code-memory/guides/memory-stack/).
|
|
31
|
+
- **Load types.** Each file shows when Claude Code loads it: always, startup, conditional, on-demand, tree, import, or link.
|
|
32
|
+
- **Memory footprint.** A bar and summary cards show the files, characters, and bytes that can load in each session, split by scope. The app does not estimate tokens.
|
|
33
|
+
- **Rules with paths.** A rule with `paths` in its frontmatter shows as conditional, with its globs as badges in the file view.
|
|
34
|
+
- **Auto memory and agent memory.** A `MEMORY.md` index shows as a table of its linked notes, with a mark at the 200-line startup cutoff. A cleanup button removes index lines that point to missing files.
|
|
35
|
+
- **Analyze with Claude.** Runs `claude -p` on your machine with one reviewer subagent per file. Reviewers check each claim against your repository. You get a health score, findings such as duplicates, contradictions, and stale facts, and a suggested fix for each. Copy one finding as a prompt, or several as a fix plan. Each run shows its cost. See [Analyze memory with Claude](https://nikiforovall.blog/claude-code-memory/guides/analyze/).
|
|
36
|
+
- **Keyboard-driven.** <kbd>↓</kbd> <kbd>↑</kbd> or <kbd>j</kbd> <kbd>k</kbd> move through the tree, <kbd>e</kbd> opens the file in your editor, <kbd>Shift</kbd>+<kbd>P</kbd> switches the project, and <kbd>?</kbd> shows all keys. See [Keyboard shortcuts](https://nikiforovall.blog/claude-code-memory/reference/shortcuts/).
|
|
37
|
+
- **17 color themes**, each in light and dark. The app installs as a progressive web app.
|
|
38
|
+
- **Claude Code Hub.** Runs on its own or as a tab in [Claude Code Hub](https://github.com/NikiforovAll/claude-code-hub), with project and theme sync. See [Run inside Claude Code Hub](https://nikiforovall.blog/claude-code-memory/reference/hub/).
|
|
39
|
+
|
|
40
|
+
<picture>
|
|
41
|
+
<source media="(prefers-color-scheme: dark)" srcset="website/public/shots/themes/ember-memory-analysis-dark.webp">
|
|
42
|
+
<img alt="Claude analysis: health 77 of 100, counts by severity, a memory map colored by worst finding, and the list of findings with suggested fixes" src="website/public/shots/themes/ember-memory-analysis-light.webp">
|
|
43
|
+
</picture>
|
|
44
|
+
|
|
45
|
+
<picture>
|
|
46
|
+
<source media="(prefers-color-scheme: dark)" srcset="website/public/shots/themes/ember-h3c-hub-memory-auto-memory-dark.webp">
|
|
47
|
+
<img alt="The auto memory MEMORY.md with a startup badge, its index table of linked notes, and three findings above the content" src="website/public/shots/themes/ember-h3c-hub-memory-auto-memory-light.webp">
|
|
48
|
+
</picture>
|
|
49
|
+
|
|
50
|
+
<picture>
|
|
51
|
+
<source media="(prefers-color-scheme: dark)" srcset="website/public/shots/themes/ember-h3d-hub-memory-rule-dark.webp">
|
|
52
|
+
<img alt="The api-design rule with a conditional badge, its paths frontmatter as badges, and one finding" src="website/public/shots/themes/ember-h3d-hub-memory-rule-light.webp">
|
|
53
|
+
</picture>
|
|
28
54
|
|
|
29
55
|
## Configuration
|
|
30
56
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
57
|
+
| Flag | What it does | Default |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `--port <n>` | Port to listen on. If the port is busy, the app uses a random free port and prints it. | `PORT`, else `3544` |
|
|
60
|
+
| `--open` | Opens the page in your browser after start. | Off |
|
|
61
|
+
| `--dir <path>` | Claude config dir to read. | `CLAUDE_CONFIG_DIR`, else `CLAUDE_DIR`, else `~/.claude` |
|
|
62
|
+
| `--project <path>` | Project the server starts on. | The current directory |
|
|
63
|
+
| `--host <addr>` | Address to bind. | `HOST`, else `127.0.0.1` |
|
|
64
|
+
| `--allowed-hosts <list>` | Comma-separated extra `Host` header values to accept. | `ALLOWED_HOSTS`, else none |
|
|
65
|
+
|
|
66
|
+
The app has no authentication. Bind a non-loopback address only on a network you trust.
|
|
67
|
+
|
|
68
|
+
To look at a different project, use the project picker (<kbd>Shift</kbd>+<kbd>P</kbd>) or add `?project=/path` to the URL. The pencil button and <kbd>e</kbd> run the editor in `EDITOR`, or `code` when it is not set. Analyze saves its runs in `<config dir>/memory-analysis/`.
|
|
37
69
|
|
|
38
|
-
|
|
70
|
+
For all options and the files the app reads and writes, see [CLI and configuration](https://nikiforovall.blog/claude-code-memory/reference/configuration/). For common problems, see [Troubleshooting](https://nikiforovall.blog/claude-code-memory/reference/troubleshooting/).
|
|
39
71
|
|
|
40
72
|
## License
|
|
41
73
|
|
package/lib/net-guard.js
CHANGED
|
@@ -181,6 +181,16 @@ function createNetGuard(config = {}) {
|
|
|
181
181
|
return next();
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
// For a WebSocket upgrade, which originGuard must not judge: the handshake is a
|
|
185
|
+
// GET, and WebSocket has no CORS, so any page can open one. Browsers always send
|
|
186
|
+
// Origin on the handshake, so a missing or `null` one is refused, not trusted.
|
|
187
|
+
// Returns null when allowed, or the reason it was refused.
|
|
188
|
+
function upgradeVerdict(req) {
|
|
189
|
+
if (!hostAllowed(parseHostHeader(req.headers.host))) return 'unrecognized Host header';
|
|
190
|
+
if (originVerdict(req.headers.origin) !== true) return 'cross-origin or missing Origin';
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
184
194
|
// Constant for the life of the process, and frameGuard runs ahead of
|
|
185
195
|
// express.static — so this is built once rather than per asset fetch.
|
|
186
196
|
//
|
|
@@ -229,12 +239,19 @@ function createNetGuard(config = {}) {
|
|
|
229
239
|
* @param {any} app express app (or any http request handler)
|
|
230
240
|
* @param {number} port 0 selects a free port
|
|
231
241
|
* @param {(port: number) => void} [onReady]
|
|
232
|
-
*
|
|
242
|
+
* `onUpgrade` is attached to both servers; a caller that attached it to the
|
|
243
|
+
* returned one alone would drop every WebSocket that arrives over the other family.
|
|
244
|
+
*
|
|
245
|
+
* @param {{maxHeaderSize?: number, onUpgrade?: (req: any, socket: any, head: Buffer) => void}} [opts]
|
|
233
246
|
*/
|
|
234
247
|
function listenLoopback(app, port, onReady, opts = {}) {
|
|
235
248
|
const http = require('http');
|
|
236
249
|
const serverOpts = opts.maxHeaderSize ? { maxHeaderSize: opts.maxHeaderSize } : {};
|
|
237
|
-
const makeServer = (handler) =>
|
|
250
|
+
const makeServer = (handler) => {
|
|
251
|
+
const s = http.createServer(serverOpts, handler);
|
|
252
|
+
if (opts.onUpgrade) s.on('upgrade', opts.onUpgrade);
|
|
253
|
+
return s;
|
|
254
|
+
};
|
|
238
255
|
const server = makeServer(app);
|
|
239
256
|
let secondary = null;
|
|
240
257
|
|
|
@@ -261,7 +278,7 @@ function createNetGuard(config = {}) {
|
|
|
261
278
|
return `WARNING: listening on ${BIND_HOST} - reachable from your network, with no authentication.`;
|
|
262
279
|
}
|
|
263
280
|
|
|
264
|
-
return { BIND_HOST, ALLOWED_HOSTS, hostGuard, originGuard, frameGuard, listenLoopback, exposureWarning };
|
|
281
|
+
return { BIND_HOST, ALLOWED_HOSTS, EXPOSED, hostGuard, originGuard, upgradeVerdict, frameGuard, listenLoopback, exposureWarning };
|
|
265
282
|
}
|
|
266
283
|
|
|
267
284
|
module.exports = { createNetGuard, parseHostHeader, isLoopbackAddress };
|
package/package.json
CHANGED
package/public/style.css
CHANGED
|
@@ -1246,7 +1246,7 @@ body.light {
|
|
|
1246
1246
|
--text-secondary: #444444;
|
|
1247
1247
|
--text-tertiary: #666666;
|
|
1248
1248
|
--text-muted: #888888;
|
|
1249
|
-
--accent-text: #
|
|
1249
|
+
--accent-text: #a0501c;
|
|
1250
1250
|
--accent-dim: rgba(232, 111, 51, 0.18);
|
|
1251
1251
|
--accent-glow: rgba(232, 111, 51, 0.5);
|
|
1252
1252
|
--success: #1a8a5a;
|
package/public/themes.css
CHANGED
|
@@ -11,18 +11,18 @@ body.light .theme-swatch-gruvbox { --sw-bg: #f3eee0; --sw-accent: #d65d0e; --sw-
|
|
|
11
11
|
body.light .theme-swatch-catppuccin { --sw-bg: #eff1f5; --sw-accent: #8839ef; --sw-ink: #4c4f69; --sw-border: #bcc0cc; }
|
|
12
12
|
.theme-swatch-tokyo-night { --sw-bg: #1a1b26; --sw-accent: #7aa2f7; --sw-ink: #c0caf5; --sw-border: #3b4261; }
|
|
13
13
|
body.light .theme-swatch-tokyo-night { --sw-bg: #e9eaf0; --sw-accent: #2e7de9; --sw-ink: #343b58; --sw-border: #a8aecb; }
|
|
14
|
-
.theme-swatch-solarized { --sw-bg: #073642; --sw-accent: #
|
|
15
|
-
body.light .theme-swatch-solarized { --sw-bg: #
|
|
14
|
+
.theme-swatch-solarized { --sw-bg: #073642; --sw-accent: #c96f47; --sw-ink: #e2dfd0; --sw-border: #586e75; }
|
|
15
|
+
body.light .theme-swatch-solarized { --sw-bg: #fdf6e3; --sw-accent: #2280c2; --sw-ink: #073642; --sw-border: #cdc4ab; }
|
|
16
16
|
.theme-swatch-dracula { --sw-bg: #282a36; --sw-accent: #bd93f9; --sw-ink: #f8f8f2; --sw-border: #565a75; }
|
|
17
17
|
body.light .theme-swatch-dracula { --sw-bg: #f0f0f5; --sw-accent: #7c3aed; --sw-ink: #16161e; --sw-border: #c9c9d6; }
|
|
18
18
|
.theme-swatch-nord { --sw-bg: #2e3440; --sw-accent: #88c0d0; --sw-ink: #eceff4; --sw-border: #4c566a; }
|
|
19
19
|
body.light .theme-swatch-nord { --sw-bg: #eceff4; --sw-accent: #5e81ac; --sw-ink: #2e3440; --sw-border: #c2c9d6; }
|
|
20
20
|
.theme-swatch-rose-pine { --sw-bg: #1f1d2e; --sw-accent: #c4a7e7; --sw-ink: #e0def4; --sw-border: #403d52; }
|
|
21
|
-
body.light .theme-swatch-rose-pine { --sw-bg: #faf4ed; --sw-accent: #907aa9; --sw-ink: #575279; --sw-border: #
|
|
21
|
+
body.light .theme-swatch-rose-pine { --sw-bg: #faf4ed; --sw-accent: #907aa9; --sw-ink: #575279; --sw-border: #cecacd; }
|
|
22
22
|
.theme-swatch-everforest { --sw-bg: #2d353b; --sw-accent: #a7c080; --sw-ink: #d3c6aa; --sw-border: #475258; }
|
|
23
|
-
body.light .theme-swatch-everforest { --sw-bg: #
|
|
23
|
+
body.light .theme-swatch-everforest { --sw-bg: #f5f4e8; --sw-accent: #6f8352; --sw-ink: #3d484e; --sw-border: #d3d2bf; }
|
|
24
24
|
.theme-swatch-kanagawa { --sw-bg: #1f1f28; --sw-accent: #7e9cd8; --sw-ink: #dcd7ba; --sw-border: #54546d; }
|
|
25
|
-
body.light .theme-swatch-kanagawa { --sw-bg: #
|
|
25
|
+
body.light .theme-swatch-kanagawa { --sw-bg: #f3f0e4; --sw-accent: #4d699b; --sw-ink: #545464; --sw-border: #d2ccb6; }
|
|
26
26
|
.theme-swatch-one-dark { --sw-bg: #282c34; --sw-accent: #61afef; --sw-ink: #d7dae0; --sw-border: #4b5263; }
|
|
27
27
|
body.light .theme-swatch-one-dark { --sw-bg: #fafafa; --sw-accent: #4078f2; --sw-ink: #383a42; --sw-border: #d4d4d6; }
|
|
28
28
|
.theme-swatch-night-owl { --sw-bg: #0b2942; --sw-accent: #82aaff; --sw-ink: #d6deeb; --sw-border: #5f7e97; }
|
|
@@ -32,7 +32,7 @@ body.light .theme-swatch-monokai { --sw-bg: #f1efed; --sw-accent: #c08a00; --sw-
|
|
|
32
32
|
.theme-swatch-github { --sw-bg: #24292e; --sw-accent: #58a6ff; --sw-ink: #e1e4e8; --sw-border: #444d56; }
|
|
33
33
|
body.light .theme-swatch-github { --sw-bg: #f6f8fa; --sw-accent: #0366d6; --sw-ink: #24292e; --sw-border: #d1d5da; }
|
|
34
34
|
.theme-swatch-ayu { --sw-bg: #10141c; --sw-accent: #e6b450; --sw-ink: #bfbdb6; --sw-border: #2d3343; }
|
|
35
|
-
body.light .theme-swatch-ayu { --sw-bg: #f8f9fa; --sw-accent: #
|
|
35
|
+
body.light .theme-swatch-ayu { --sw-bg: #f8f9fa; --sw-accent: #c97612; --sw-ink: #3d4149; --sw-border: #d8dde2; }
|
|
36
36
|
.theme-swatch-vitesse { --sw-bg: #181818; --sw-accent: #4d9375; --sw-ink: #dbd7ca; --sw-border: #333333; }
|
|
37
37
|
body.light .theme-swatch-vitesse { --sw-bg: #f7f7f7; --sw-accent: #1c6b48; --sw-ink: #393a34; --sw-border: #d6d6d6; }
|
|
38
38
|
.theme-swatch-synthwave { --sw-bg: #262335; --sw-accent: #ff7edb; --sw-ink: #ffffff; --sw-border: #495495; }
|
|
@@ -136,34 +136,36 @@ body.light[data-color-theme="tokyo-night"] {
|
|
|
136
136
|
|
|
137
137
|
/* Solarized */
|
|
138
138
|
body[data-color-theme="solarized"]:not(.light) {
|
|
139
|
-
--accent: #
|
|
140
|
-
--accent-text: #
|
|
141
|
-
--accent-dim: rgba(
|
|
142
|
-
--accent-glow: rgba(
|
|
139
|
+
--accent: #c96f47;
|
|
140
|
+
--accent-text: #d48a6a;
|
|
141
|
+
--accent-dim: rgba(201,111,71,0.25);
|
|
142
|
+
--accent-glow: rgba(201, 111, 71, 0.55);
|
|
143
143
|
--bg-deep: #002b36;
|
|
144
144
|
--bg-surface: #073642;
|
|
145
145
|
--bg-elevated: #0a4250;
|
|
146
146
|
--bg-hover: #11505f;
|
|
147
147
|
--border: #586e75;
|
|
148
|
-
--text-primary: #
|
|
149
|
-
--text-secondary: #
|
|
150
|
-
--text-tertiary: #
|
|
151
|
-
--text-muted: #
|
|
148
|
+
--text-primary: #e2dfd0;
|
|
149
|
+
--text-secondary: #b7c0bf;
|
|
150
|
+
--text-tertiary: #93a1a1;
|
|
151
|
+
--text-muted: #839496;
|
|
152
152
|
}
|
|
153
153
|
body.light[data-color-theme="solarized"] {
|
|
154
|
-
--accent: #
|
|
155
|
-
--accent-text: #
|
|
156
|
-
--accent-dim: rgba(
|
|
157
|
-
--accent-glow: rgba(
|
|
154
|
+
--accent: #2280c2;
|
|
155
|
+
--accent-text: #1b6aa3;
|
|
156
|
+
--accent-dim: rgba(34,128,194,0.18);
|
|
157
|
+
--accent-glow: rgba(34, 128, 194, 0.5);
|
|
158
158
|
--bg-deep: #eee8d5;
|
|
159
|
-
--bg-surface: #
|
|
160
|
-
--bg-elevated: #
|
|
161
|
-
--bg-hover: #
|
|
162
|
-
--border: #
|
|
159
|
+
--bg-surface: #fdf6e3;
|
|
160
|
+
--bg-elevated: #fffbef;
|
|
161
|
+
--bg-hover: #efe8d3;
|
|
162
|
+
--border: #cdc4ab;
|
|
163
163
|
--text-primary: #073642;
|
|
164
|
-
--text-secondary: #
|
|
165
|
-
--text-tertiary: #
|
|
166
|
-
--text-muted: #
|
|
164
|
+
--text-secondary: #4f6369;
|
|
165
|
+
--text-tertiary: #586e75;
|
|
166
|
+
--text-muted: #728589;
|
|
167
|
+
--sidebar-bg: #e6dfc7;
|
|
168
|
+
--sidebar-item-bg: #f3ecd6;
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
/* Dracula */
|
|
@@ -255,11 +257,11 @@ body.light[data-color-theme="rose-pine"] {
|
|
|
255
257
|
--bg-surface: #faf4ed;
|
|
256
258
|
--bg-elevated: #fffaf3;
|
|
257
259
|
--bg-hover: #ebdfd4;
|
|
258
|
-
--border: #
|
|
260
|
+
--border: #cecacd;
|
|
259
261
|
--text-primary: #575279;
|
|
260
262
|
--text-secondary: #635e87;
|
|
261
|
-
--text-tertiary: #
|
|
262
|
-
--text-muted: #
|
|
263
|
+
--text-tertiary: #6e6a88;
|
|
264
|
+
--text-muted: #857f96;
|
|
263
265
|
}
|
|
264
266
|
|
|
265
267
|
/* Everforest */
|
|
@@ -283,15 +285,15 @@ body.light[data-color-theme="everforest"] {
|
|
|
283
285
|
--accent-text: #56683f;
|
|
284
286
|
--accent-dim: rgba(111,131,82,0.18);
|
|
285
287
|
--accent-glow: rgba(111, 131, 82, 0.5);
|
|
286
|
-
--bg-deep: #
|
|
287
|
-
--bg-surface: #
|
|
288
|
-
--bg-elevated: #
|
|
289
|
-
--bg-hover: #
|
|
290
|
-
--border: #
|
|
291
|
-
--text-primary: #
|
|
292
|
-
--text-secondary: #
|
|
293
|
-
--text-tertiary: #
|
|
294
|
-
--text-muted: #
|
|
288
|
+
--bg-deep: #ebeadb;
|
|
289
|
+
--bg-surface: #f5f4e8;
|
|
290
|
+
--bg-elevated: #fbfbf4;
|
|
291
|
+
--bg-hover: #e5e4d3;
|
|
292
|
+
--border: #d3d2bf;
|
|
293
|
+
--text-primary: #3d484e;
|
|
294
|
+
--text-secondary: #55636b;
|
|
295
|
+
--text-tertiary: #66705f;
|
|
296
|
+
--text-muted: #7a8577;
|
|
295
297
|
}
|
|
296
298
|
|
|
297
299
|
/* Kanagawa */
|
|
@@ -315,11 +317,11 @@ body.light[data-color-theme="kanagawa"] {
|
|
|
315
317
|
--accent-text: #38537f;
|
|
316
318
|
--accent-dim: rgba(77,105,155,0.18);
|
|
317
319
|
--accent-glow: rgba(77, 105, 155, 0.5);
|
|
318
|
-
--bg-deep: #
|
|
319
|
-
--bg-surface: #
|
|
320
|
-
--bg-elevated: #
|
|
321
|
-
--bg-hover: #
|
|
322
|
-
--border: #
|
|
320
|
+
--bg-deep: #e9e5d6;
|
|
321
|
+
--bg-surface: #f3f0e4;
|
|
322
|
+
--bg-elevated: #faf8f1;
|
|
323
|
+
--bg-hover: #e2ddcb;
|
|
324
|
+
--border: #d2ccb6;
|
|
323
325
|
--text-primary: #545464;
|
|
324
326
|
--text-secondary: #66667a;
|
|
325
327
|
--text-tertiary: #716e61;
|
|
@@ -408,7 +410,7 @@ body[data-color-theme="monokai"]:not(.light) {
|
|
|
408
410
|
}
|
|
409
411
|
body.light[data-color-theme="monokai"] {
|
|
410
412
|
--accent: #c08a00;
|
|
411
|
-
--accent-text: #
|
|
413
|
+
--accent-text: #856000;
|
|
412
414
|
--accent-dim: rgba(192,138,0,0.18);
|
|
413
415
|
--accent-glow: rgba(192, 138, 0, 0.5);
|
|
414
416
|
--bg-deep: #e9e6e4;
|
|
@@ -471,10 +473,10 @@ body[data-color-theme="ayu"]:not(.light) {
|
|
|
471
473
|
--text-muted: #6c7380;
|
|
472
474
|
}
|
|
473
475
|
body.light[data-color-theme="ayu"] {
|
|
474
|
-
--accent: #
|
|
475
|
-
--accent-text: #
|
|
476
|
-
--accent-dim: rgba(
|
|
477
|
-
--accent-glow: rgba(
|
|
476
|
+
--accent: #c97612;
|
|
477
|
+
--accent-text: #a65e0c;
|
|
478
|
+
--accent-dim: rgba(201,118,18,0.18);
|
|
479
|
+
--accent-glow: rgba(201, 118, 18, 0.5);
|
|
478
480
|
--bg-deep: #eff1f3;
|
|
479
481
|
--bg-surface: #f8f9fa;
|
|
480
482
|
--bg-elevated: #fcfcfc;
|