hd-garden 0.4.0 → 0.5.0

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.
Files changed (56) hide show
  1. package/.agents/skills/garden-interactive-chart/SKILL.md +10 -10
  2. package/.agents/skills/garden-ui/SKILL.md +4 -4
  3. package/Makefile +2 -3
  4. package/app/a2/[slug]/page.tsx +0 -1
  5. package/app/a2/page.tsx +1 -1
  6. package/app/about/page.tsx +8 -12
  7. package/app/admin/page.tsx +2 -2
  8. package/app/blog/[...path]/page.tsx +2 -13
  9. package/app/blog/page.tsx +2 -2
  10. package/app/columns/[column]/[...path]/page.tsx +2 -4
  11. package/app/columns/page.tsx +2 -2
  12. package/app/components/AdminDashboard.tsx +3 -3
  13. package/app/components/ArticleMeasure.tsx +114 -42
  14. package/app/components/ArticleTags.tsx +17 -0
  15. package/app/components/BlogArchive.tsx +85 -33
  16. package/app/components/ContentEmptyState.tsx +6 -6
  17. package/app/components/GardenAdminGuide.tsx +1 -1
  18. package/app/components/GardenContentGuide.tsx +1 -2
  19. package/app/components/GardenMediaGuide.tsx +3 -3
  20. package/app/components/GithubProfile.tsx +1 -1
  21. package/app/components/MarkdownImage.tsx +4 -2
  22. package/app/components/SiteFooter.tsx +5 -5
  23. package/app/components/SiteHeader.tsx +1 -5
  24. package/app/components/TagRedirect.tsx +17 -0
  25. package/app/garden/page.tsx +6 -6
  26. package/app/garden-modules.d.ts +0 -1
  27. package/app/globals.css +19 -101
  28. package/app/lib/a2-meta.ts +10 -0
  29. package/app/lib/a2-preview.ts +0 -2
  30. package/app/lib/content.ts +14 -8
  31. package/app/lib/fallback-site-config.ts +15 -15
  32. package/app/lib/generated-content.ts +58 -47
  33. package/app/lib/tag-filter.ts +114 -0
  34. package/app/not-found.tsx +13 -0
  35. package/app/page.tsx +10 -27
  36. package/app/styles/a2.css +96 -15
  37. package/app/styles/shell.css +56 -61
  38. package/app/styles/tokens.css +35 -22
  39. package/app/tags/page.tsx +20 -9
  40. package/package.json +1 -1
  41. package/scripts/build-content.mjs +3 -3
  42. package/scripts/check-post.mjs +0 -3
  43. package/scripts/new-post.mjs +1 -3
  44. package/site.config.yaml +15 -15
  45. package/templates/site/Makefile +2 -3
  46. package/templates/site/site.config.yaml +15 -15
  47. package/ui/garden/check.mjs +2 -4
  48. package/ui/garden/enhance.mjs +57 -0
  49. package/ui/garden/title.mjs +5 -8
  50. package/ui/host.mjs +13 -13
  51. package/ui/preview/dist/garden-ui.css +11 -11
  52. package/ui/preview/dist/garden-ui.esm.js +6 -6
  53. package/ui/preview/dist/garden-ui.iife.js +7 -7
  54. package/ui/react/components/media.tsx +2 -2
  55. package/ui/react/ui.css +11 -11
  56. package/app/components/TagIndex.tsx +0 -97
package/app/tags/page.tsx CHANGED
@@ -1,28 +1,39 @@
1
+ import Link from "next/link";
1
2
  import { Suspense } from "react";
2
3
  import { posts } from "../lib/content";
3
- import { TagIndex } from "../components/TagIndex";
4
+ import { tagCounts, tagFilterHref } from "../lib/tag-filter";
5
+ import { TagRedirect } from "../components/TagRedirect";
4
6
  import { siteDocumentTitle } from "../site.config";
5
7
 
6
8
  export const metadata = {
7
9
  title: siteDocumentTitle,
8
- description: "按标签浏览文章。标签不是专栏,也不是分类。",
10
+ description: "全部标签。",
9
11
  };
10
12
 
11
13
  export default function TagsPage() {
12
- const counts = new Map<string, number>();
13
- for (const post of posts) {
14
- for (const tag of post.tags ?? []) counts.set(tag, (counts.get(tag) ?? 0) + 1);
15
- }
16
- const once = [...counts.values()].filter((count) => count === 1).length;
14
+ const tags = tagCounts(posts);
17
15
  return (
18
16
  <main className="sh-main" id="content">
19
17
  <div className="sh-head">
20
18
  <h1>标签</h1>
21
- <p className="sh-deck">{counts.size} 个标签,按使用次数排序;只用过一次的 {once} 个收在下面。点选一个标签,下方列出对应文章。</p>
19
+ <p className="sh-deck">{tags.length} 个标签,按文章数排序。点一个标签,查看带这个标签的文章。</p>
22
20
  </div>
23
21
  <Suspense>
24
- <TagIndex posts={posts} />
22
+ <TagRedirect />
25
23
  </Suspense>
24
+ {tags.length ? (
25
+ <ul className="sh-tagchips sh-tagindex" aria-label="全部标签">
26
+ {tags.map(([tag, count]) => (
27
+ <li key={tag}>
28
+ <Link className="sh-tagchip" href={tagFilterHref([tag])}>
29
+ #{tag}<span className="n num">{count}</span>
30
+ </Link>
31
+ </li>
32
+ ))}
33
+ </ul>
34
+ ) : (
35
+ <p className="sh-deck">还没有标签。</p>
36
+ )}
26
37
  </main>
27
38
  );
28
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hd-garden",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "private": false,
5
5
  "description": "用 Markdown 写作、用 GitHub Pages 发布的个人博客引擎。",
6
6
  "license": "MIT",
@@ -184,7 +184,7 @@ function assertWidgetSidecar(src, markdownPath, sourcePath) {
184
184
  ) {
185
185
  fail(
186
186
  sourcePath,
187
- `widget src 必须位于同名目录 ${stem}/ 内的 .html 或 .pdf,例如 ./${stem}/notes.pdf`,
187
+ `widget src 必须位于同名目录 ${stem}/ 内的 .html 或 .pdf,例如 ./${stem}/diagram.html`,
188
188
  );
189
189
  }
190
190
  return absoluteSource;
@@ -337,7 +337,6 @@ function validateAndNormalize(data, content, markdownPath, kind, sourcePath, lin
337
337
 
338
338
  if (kind === "post") {
339
339
  requireString(data, "description", sourcePath);
340
- requireString(data, "topic", sourcePath);
341
340
  }
342
341
  if (kind === "thought" && data.mediaType) {
343
342
  if (!["image", "audio", "video", "link", "text"].includes(data.mediaType)) {
@@ -348,6 +347,8 @@ function validateAndNormalize(data, content, markdownPath, kind, sourcePath, lin
348
347
  const publishTime = Date.parse(publishAt ?? date);
349
348
  if (!includeDrafts && (data.draft === true || publishTime > now)) return null;
350
349
  delete data.coverAlt;
350
+ // Older posts may still carry `topic:`; it is no longer used.
351
+ delete data.topic;
351
352
  const references = normalizeReferences(data.references, sourcePath);
352
353
  delete data.references;
353
354
 
@@ -562,7 +563,6 @@ export type ContentEntry = {
562
563
  updated?: string;
563
564
  publishAt?: string;
564
565
  draft?: boolean;
565
- topic?: string;
566
566
  tags?: string[];
567
567
  references?: { title: string; url?: string }[];
568
568
  pinned?: boolean;
@@ -272,9 +272,6 @@ const checkFile = (filePath) => {
272
272
  if (typeof data.description !== "string" || !data.description.trim()) {
273
273
  error(errors, "missing-description", 1, `${sourcePath}: front matter 缺少有效的 description`);
274
274
  }
275
- if (typeof data.topic !== "string" || !data.topic.trim()) {
276
- error(errors, "missing-topic", 1, `${sourcePath}: front matter 缺少有效的 topic`);
277
- }
278
275
  if (data.slug !== undefined) {
279
276
  error(errors, "unexpected-slug", 1, `${sourcePath}: 不要写 slug,文件名就是标识`);
280
277
  }
@@ -13,7 +13,6 @@ async function main() {
13
13
  const titleSlug = title.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-|-$/gu, "");
14
14
  const slug = option("SLUG") || titleSlug || `post-${date.slice(0, 10)}-${randomUUID().slice(0, 8)}`;
15
15
  const directory = option("DIR");
16
- const topic = option("TOPIC") || "未分类";
17
16
 
18
17
  if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(slug)) {
19
18
  throw new Error("SLUG 只能包含小写字母、数字和连字符,不含 .md 后缀。");
@@ -43,7 +42,6 @@ async function main() {
43
42
  `title: ${JSON.stringify(title)}`,
44
43
  `date: ${date}`,
45
44
  `description: ${JSON.stringify("请填写一句话摘要。")}`,
46
- `topic: ${JSON.stringify(topic)}`,
47
45
  "tags: []",
48
46
  "draft: true",
49
47
  "---",
@@ -67,7 +65,7 @@ async function main() {
67
65
  console.log(`已创建草稿:${path.relative(root, destination)}`);
68
66
  console.log(`文章路径:/blog/${[...segments, slug].join("/")}/`);
69
67
  console.log("预览:CONTENT_INCLUDE_DRAFTS=1 make dev");
70
- console.log("发布前请完善摘要、分类与正文,并将 draft 改为 false,再运行 make update。");
68
+ console.log("发布前请完善摘要、标签与正文,并将 draft 改为 false,再运行 make update。");
71
69
  }
72
70
 
73
71
  main().catch((error) => {
package/site.config.yaml CHANGED
@@ -1,12 +1,12 @@
1
1
  name: Hedon Garden
2
- tagline: 写作 · 构建 · 保持好奇
3
- description: 一个可 fork、可长期维护的 Markdown 个人博客系统。
2
+ tagline: 写作 · 记录 · 保持好奇
3
+ description: 文章、随想和专栏。
4
4
  locale: zh_CN
5
5
 
6
6
  author:
7
7
  name: Your Name
8
8
  github: your-github-id
9
- githubBio: Write a short introduction for your GitHub profile card.
9
+ githubBio: 一句自我介绍。
10
10
  # 可选:本地没有 GITHUB_TOKEN 时用作置顶仓库降级数据。
11
11
  githubPinned: []
12
12
 
@@ -16,28 +16,28 @@ pages:
16
16
  title: |-
17
17
  记一些正在做的事,
18
18
  和想清楚的问题。
19
- subtitle: 关注软件工程、系统设计与技术实践,也记录偶发的探索和工作笔记。
19
+ subtitle: 软件、笔记,和偶尔的工作记录。
20
20
  blog:
21
21
  title: 博文
22
- subtitle: 阶段性的完整梳理与技术总结。
22
+ subtitle: 写完的长文。
23
23
  thoughts:
24
24
  title: 随想
25
- subtitle: 碎片的念头、偶遇的灵感、短笔记与链接。
25
+ subtitle: 短笔记、图片和链接。
26
26
  columns:
27
27
  title: 专栏
28
- subtitle: 按顺序组织的专题系列,沿着清晰的脉络连点成线。
28
+ subtitle: 按顺序读的一组文章。
29
29
  about:
30
30
  title: 你好,我是 Your Name。
31
- subtitle: 欢迎来到我的个人网站。
32
- heading: 关于我与这里
31
+ subtitle: 文章和笔记都在这里。
32
+ heading: 关于
33
33
  paragraphs:
34
- - 一名工程师 / 创作者。平时主要关注系统开发、技术探索与软件设计。
35
- - 这里是我的公开工作台与数字自留地。比起社交网络上的碎片动态,我更倾向于把探索过程沉淀为有据可查的代码、设计与长篇笔记。
34
+ - 一名工程师。平时写代码,也把想清楚的问题记下来。
35
+ - 这里放文章、随想和专栏。
36
36
  quote: ""
37
37
  focus:
38
- - 软件工程与系统架构
39
- - 原生工具与高质量交互
40
- - 个人长期知识沉淀
38
+ - 软件
39
+ - 笔记
40
+ - 日常
41
41
  cta:
42
42
  href: /blog
43
43
  label: 浏览博文
@@ -45,4 +45,4 @@ pages:
45
45
  title: "用 Markdown 写。\n推送之后,网站自己更新。"
46
46
  subtitle: ""
47
47
 
48
- footer: 持续记录与构建。
48
+ footer: 持续记录。
@@ -4,15 +4,14 @@ MESSAGE ?= 更新博客
4
4
 
5
5
  .PHONY: help new embed skill prepare dev check build update
6
6
 
7
- unexport TITLE SLUG DIR TOPIC URL
7
+ unexport TITLE SLUG DIR URL
8
8
  export GARDEN_NEW_TITLE := $(value TITLE)
9
9
  export GARDEN_NEW_SLUG := $(value SLUG)
10
10
  export GARDEN_NEW_DIR := $(value DIR)
11
- export GARDEN_NEW_TOPIC := $(value TOPIC)
12
11
  export GARDEN_EMBED_URL := $(value URL)
13
12
 
14
13
  help:
15
- @printf "%s\n" "Garden 常用命令:" " make new 用引擎创建文章草稿" ' make new TITLE="文章标题" SLUG=my-post DIR=writing TOPIC="写作"' ' make embed URL="https://example.com" 拉取外部网页摘要' " make skill 安装可交互图表 skill" " make dev 安装依赖并本地预览" " make build 构建公开站点" " make update 检查、提交并触发自动发布"
14
+ @printf "%s\n" "Garden 常用命令:" " make new 用引擎创建文章草稿" ' make new TITLE="文章标题" SLUG=my-post DIR=writing' ' make embed URL="https://example.com" 拉取外部网页摘要' " make skill 安装可交互图表 skill" " make dev 安装依赖并本地预览" " make build 构建公开站点" " make update 检查、提交并触发自动发布"
16
15
 
17
16
  new: prepare
18
17
  npx garden new
@@ -1,12 +1,12 @@
1
1
  name: Garden
2
- tagline: 写作 · 构建 · 保持好奇
3
- description: 一个可长期维护的 Markdown 个人博客。
2
+ tagline: 写作 · 记录 · 保持好奇
3
+ description: 文章、随想和专栏。
4
4
  locale: zh_CN
5
5
 
6
6
  author:
7
7
  name: Your Name
8
8
  github: your-github-id
9
- githubBio: Write a short introduction for your GitHub profile card.
9
+ githubBio: 一句自我介绍。
10
10
  githubPinned: []
11
11
 
12
12
  pages:
@@ -14,28 +14,28 @@ pages:
14
14
  title: |-
15
15
  记一些正在做的事,
16
16
  和想清楚的问题。
17
- subtitle: 关注软件工程、系统设计与技术实践,也记录偶发的探索和工作笔记。
17
+ subtitle: 软件、笔记,和偶尔的工作记录。
18
18
  blog:
19
19
  title: 博文
20
- subtitle: 阶段性的完整梳理与技术总结。
20
+ subtitle: 写完的长文。
21
21
  thoughts:
22
22
  title: 随想
23
- subtitle: 碎片的念头、偶遇的灵感、短笔记与链接。
23
+ subtitle: 短笔记、图片和链接。
24
24
  columns:
25
25
  title: 专栏
26
- subtitle: 按顺序组织的专题系列,沿着清晰的脉络连点成线。
26
+ subtitle: 按顺序读的一组文章。
27
27
  about:
28
28
  title: 你好,我是 Your Name。
29
- subtitle: 欢迎来到我的个人网站。
30
- heading: 关于我与这里
29
+ subtitle: 文章和笔记都在这里。
30
+ heading: 关于
31
31
  paragraphs:
32
- - 一名工程师 / 创作者。平时主要关注系统开发、技术探索与软件设计。
33
- - 这里是我的公开工作台与数字自留地。比起社交网络上的碎片动态,我更倾向于把探索过程沉淀为有据可查的代码、设计与长篇笔记。
32
+ - 一名工程师。平时写代码,也把想清楚的问题记下来。
33
+ - 这里放文章、随想和专栏。
34
34
  quote: ""
35
35
  focus:
36
- - 软件工程与系统架构
37
- - 原生工具与高质量交互
38
- - 个人长期知识沉淀
36
+ - 软件
37
+ - 笔记
38
+ - 日常
39
39
  cta:
40
40
  href: /blog
41
41
  label: 浏览博文
@@ -43,4 +43,4 @@ pages:
43
43
  title: "用 Markdown 写。\n推送之后,网站自己更新。"
44
44
  subtitle: ""
45
45
 
46
- footer: 持续记录与构建。
46
+ footer: 持续记录。
@@ -34,10 +34,8 @@ export function checkGardenMarkdown(markdown, { draft = false, title = "", title
34
34
 
35
35
  if (title) {
36
36
  const split = splitTitle(title);
37
- // Titles stay exactly as written. splitTitle already keeps one line when it cannot split.
38
- if (split.issue === "multiple") {
39
- push(titleLine, "title-split", "标题里有不止一个分隔符,无法分成正好两行。", "只留一个 丨、| 或 \" | \"。", "warning");
40
- } else if (split.issue === "empty") {
37
+ // More than one separator still splits at the first. Only an empty side stays one line.
38
+ if (split.issue === "empty") {
41
39
  push(titleLine, "title-split", "分隔符两侧都要有文字。", "写成「主题丨副题」。", "warning");
42
40
  }
43
41
  }
@@ -74,6 +74,63 @@ export function tableBreakout({
74
74
  return { left: margin, right: margin };
75
75
  }
76
76
 
77
+ /**
78
+ * The width used to decide whether an image widens past the column: its width
79
+ * attribute when it has one, otherwise half its pixels (screenshots are
80
+ * usually 2x). 0 while the image has not loaded. Never more than the image
81
+ * itself, so nothing is enlarged.
82
+ */
83
+ export function imageDisplayWidth({ naturalWidth = 0, attrWidth = 0, density = 2 }) {
84
+ if (attrWidth > 0) return naturalWidth > 0 ? Math.min(attrWidth, naturalWidth) : attrWidth;
85
+ if (!(naturalWidth > 0)) return 0;
86
+ return Math.round(naturalWidth / density);
87
+ }
88
+
89
+ /**
90
+ * The inline width an article image gets, or 0 to leave it to CSS
91
+ * (width:auto; max-width:100%), which shows it at its natural size and caps
92
+ * it at the column, never stretched and never halved. A widened image takes
93
+ * its display width; an image in the column only follows its width attribute,
94
+ * never past its own pixels.
95
+ */
96
+ export function figureImageWidth({ naturalWidth = 0, attrWidth = 0, widened = false, density = 2 }) {
97
+ if (widened) return imageDisplayWidth({ naturalWidth, attrWidth, density });
98
+ if (attrWidth > 0) return naturalWidth > 0 ? Math.min(attrWidth, naturalWidth) : attrWidth;
99
+ return 0;
100
+ }
101
+
102
+ /**
103
+ * How far a figure steps out on each side. Screenshots are usually 2x, so an
104
+ * image displays at naturalWidth / density unless it states its own width.
105
+ * A figure widens only when that display width is wider than the column, and
106
+ * never past the display width, maxWidth in total, or the room on screen.
107
+ */
108
+ export function figureBreakout({
109
+ viewport,
110
+ articleLeft,
111
+ articleRight,
112
+ figureClient,
113
+ imageClient = figureClient,
114
+ naturalWidth = 0,
115
+ attrWidth = 0,
116
+ density = 2,
117
+ maxWidth = 1040,
118
+ minViewport = 900,
119
+ edge = 24,
120
+ }) {
121
+ if (viewport < minViewport) return { left: 0, right: 0 };
122
+ const display = imageDisplayWidth({ naturalWidth, attrWidth, density });
123
+ // Wider than the text column, or it stays in the column.
124
+ if (!(display > figureClient)) return { left: 0, right: 0 };
125
+ const need = Math.floor(display - imageClient);
126
+ if (!(need > 1)) return { left: 0, right: 0 };
127
+ const target = Math.min(figureClient + need, Math.max(maxWidth, figureClient));
128
+ const room = Math.max(0, Math.min(articleLeft - edge, viewport - edge - articleRight));
129
+ const side = Math.min(room, Math.floor((target - figureClient) / 2));
130
+ if (side <= 0) return { left: 0, right: 0 };
131
+ return { left: side, right: side };
132
+ }
133
+
77
134
  /**
78
135
  * Slide the TOC right of a wide element measured against the TOC's original
79
136
  * position. Hide it when the shifted TOC would not fit on screen.
@@ -1,17 +1,14 @@
1
1
  const SEPARATOR = /丨||| \| /gu;
2
2
 
3
3
  /**
4
- * A title splits into exactly two lines when it contains one 丨, | or " | ".
5
- * Anything else stays one line. The separator stays in the accessible name.
4
+ * A title splits into two lines at the first 丨, | or " | ".
5
+ * Later separators stay on the second line. An empty side stays one line.
6
+ * The separator stays in the accessible name.
6
7
  */
7
8
  export function splitTitle(title) {
8
9
  const text = String(title ?? "");
9
- const matches = [...text.matchAll(SEPARATOR)];
10
- if (matches.length === 0) return { split: false, title: text, lines: [text], separator: null, issue: null };
11
- if (matches.length > 1) {
12
- return { split: false, title: text, lines: [text], separator: null, issue: "multiple" };
13
- }
14
- const match = matches[0];
10
+ const match = [...text.matchAll(SEPARATOR)][0];
11
+ if (!match) return { split: false, title: text, lines: [text], separator: null, issue: null };
15
12
  const before = text.slice(0, match.index).trim();
16
13
  const after = text.slice(match.index + match[0].length).trim();
17
14
  const separator = match[0] === " | " ? " | " : match[0];
package/ui/host.mjs CHANGED
@@ -61,11 +61,11 @@ const THEMES = {
61
61
  rule: "#E6E3DC",
62
62
  ruleStrong: "#D6D2C9",
63
63
  card: "#FFFFFF",
64
- paper: "#F8F7F3",
65
- well: "#F0EEE8",
66
- blue: "#2C55B4",
67
- blueTint: "#EAF0FC",
68
- blueLine: "rgba(44,85,180,.28)",
64
+ paper: "#FAF9F5",
65
+ well: "#F0EEE6",
66
+ blue: "#30302E",
67
+ blueTint: "#F0EEE6",
68
+ blueLine: "rgba(20,20,19,.22)",
69
69
  },
70
70
  dark: {
71
71
  ink: "#EEECE7",
@@ -73,14 +73,14 @@ const THEMES = {
73
73
  soft: "#BDB9B0",
74
74
  muted: "#A09B91",
75
75
  grey: "#A09B91",
76
- rule: "#2F2D29",
77
- ruleStrong: "#45423C",
78
- card: "#1E1D1A",
79
- paper: "#161513",
80
- well: "#22211D",
81
- blue: "#93B2F4",
82
- blueTint: "rgba(147,178,244,.13)",
83
- blueLine: "rgba(147,178,244,.35)",
76
+ rule: "#3D3D3A",
77
+ ruleStrong: "#4D4C48",
78
+ card: "#262624",
79
+ paper: "#1F1E1D",
80
+ well: "#262624",
81
+ blue: "#EEECE7",
82
+ blueTint: "#30302E",
83
+ blueLine: "rgba(238,236,231,.25)",
84
84
  },
85
85
  };
86
86
 
@@ -22,23 +22,23 @@
22
22
  --gui-control-border: var(--rule-strong, #d6d2c9);
23
23
  --gui-check-border: var(--rule-strong, #d6d2c9);
24
24
  --gui-control-bg: var(--card, #fff);
25
- --gui-surface: var(--well, #f0eee8);
26
- --gui-chip: var(--well, #f0eee8);
27
- --gui-hover: var(--well, #f0eee8);
25
+ --gui-surface: var(--well, #f0eee6);
26
+ --gui-chip: var(--well, #f0eee6);
27
+ --gui-hover: var(--well, #f0eee6);
28
28
  --gui-solid: var(--ink, #1b1a18);
29
29
  --gui-solid-hover: var(--soft, #4a4844);
30
- --gui-on-solid: var(--paper, #f8f7f3);
31
- --gui-segment: var(--well, #f0eee8);
30
+ --gui-on-solid: var(--paper, #faf9f5);
31
+ --gui-segment: var(--well, #f0eee6);
32
32
  --gui-segment-selected: var(--card, #fff);
33
33
  --gui-segment-shadow: none;
34
- --gui-progress: var(--blue, #2c55b4);
35
- --gui-progress-track: var(--well, #f0eee8);
36
- --gui-focus: var(--blue, #2c55b4);
37
- --gui-bubble: var(--blue-tint, #eaf0fc);
34
+ --gui-progress: var(--blue, #30302e);
35
+ --gui-progress-track: var(--well, #f0eee6);
36
+ --gui-focus: var(--blue, #30302e);
37
+ --gui-bubble: var(--blue-tint, #f0eee6);
38
38
  --gui-popover-border: var(--rule, #e6e3dc);
39
39
  --gui-shadow: none;
40
- --gui-code-bg: var(--well, #f0eee8);
41
- --gui-accent: var(--blue, #2c55b4);
40
+ --gui-code-bg: var(--well, #f0eee6);
41
+ --gui-accent: var(--blue, #30302e);
42
42
  --gui-series-plain: var(--ink, #1b1a18);
43
43
  --gui-series-accent: var(--blue);
44
44
  --gui-series-new: #00a240;