diff --git a/apps/web/src/components/ThemeProvider.tsx b/apps/web/src/components/ThemeProvider.tsx index 6d4353f4..e24555bf 100644 --- a/apps/web/src/components/ThemeProvider.tsx +++ b/apps/web/src/components/ThemeProvider.tsx @@ -175,7 +175,7 @@ const EDITOR_THEME_STORAGE_KEY = "edgeever.editor-theme"; const CUSTOM_EDITOR_THEME_STORAGE_KEY = "edgeever.custom-editor-theme"; const CUSTOM_EDITOR_THEMES_STORAGE_KEY = "edgeever.custom-editor-themes"; const LIGHT_THEME_COLOR = "#eef1f4"; -const DARK_THEME_COLOR = "#101311"; +const DARK_THEME_COLOR = "#101010"; const AppearanceThemeContext = createContext(null); const MermaidThemeContext = createContext(null); const MarkdownThemeContext = createContext(null); diff --git a/apps/web/src/components/settings/NoteProseCssPreview.tsx b/apps/web/src/components/settings/NoteProseCssPreview.tsx index 2c756a01..a7b1147a 100644 --- a/apps/web/src/components/settings/NoteProseCssPreview.tsx +++ b/apps/web/src/components/settings/NoteProseCssPreview.tsx @@ -10,8 +10,8 @@ const previewBaseCss = ` color: #27272a; } .${NOTE_PROSE_CSS_PREVIEW_DARK_CLASS} .edgeever-editor { - background: #191e1b; - color: #dee3e0; + background: #1c1c1c; + color: #dedede; } .ProseMirror { margin: 0; diff --git a/apps/web/src/lib/dark-theme.test.mjs b/apps/web/src/lib/dark-theme.test.mjs index f97c879d..d84d269e 100644 --- a/apps/web/src/lib/dark-theme.test.mjs +++ b/apps/web/src/lib/dark-theme.test.mjs @@ -42,7 +42,7 @@ describe("dark theme contracts", () => { const memoCard = readFileSync(new URL("../components/MemoCard.tsx", import.meta.url), "utf8"); expect(css).toContain(":root.dark .edgeever-public-share .ProseMirror"); expect(css).toContain("color: hsl(var(--foreground));"); - expect(css).toContain("--workspace-memo-divider: #3b4540;"); + expect(css).toContain("--workspace-memo-divider: #404040;"); expect(css).toContain(":root.dark .edgeever-workspace-memo-list .edgeever-memo-divider"); expect(memoCard).toContain("edgeever-memo-divider"); expect(memoCard).not.toContain("dark:lg:border-slate-300"); @@ -67,21 +67,22 @@ describe("dark theme contracts", () => { test("workspace dark surfaces stay neutral and bundled editor themes blend into the canvas", () => { const css = readFileSync(new URL("../styles/globals.css", import.meta.url), "utf8"); - expect(css).toContain("--workspace-canvas: #101311;"); - expect(css).toContain("--workspace-sidebar: #121612;"); - expect(css).toContain("--workspace-memo-list: #151a17;"); - expect(css).toContain("--workspace-editor: #191e1b;"); + expect(css).toContain("--workspace-canvas: #101010;"); + expect(css).toContain("--workspace-sidebar: #141414;"); + expect(css).toContain("--workspace-memo-list: #181818;"); + expect(css).toContain("--workspace-editor: #1c1c1c;"); + expect(css).toContain("--slate-500-rgb: 161 161 161;"); expect(css).toContain(':not([data-editor-theme="custom"])'); expect(css).toContain("--editor-theme-bg: var(--workspace-editor);"); - expect(contrastRatio("#cad4ce", "#191e1b")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio("#9aa9a0", "#191e1b")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#dedede", "#1c1c1c")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#a3a3a3", "#1c1c1c")).toBeGreaterThanOrEqual(4.5); }); test("dark chrome uses workspace tokens instead of leftover blue-slate", () => { const css = readFileSync(new URL("../styles/globals.css", import.meta.url), "utf8"); - expect(css).toContain("--tooltip-bg: #2c3330;"); - expect(css).toContain("--scrollbar-thumb: rgb(137 150 142 / 0.38);"); + expect(css).toContain("--tooltip-bg: #2c2c2c;"); + expect(css).toContain("--scrollbar-thumb: rgb(145 145 145 / 0.38);"); expect(css).toContain("--search-match: rgb(22 160 110 / 0.32);"); expect(css).toContain(":root.dark .ProseMirror .edgeever-mermaid-preview"); expect(css).toContain("background: var(--workspace-editor);"); @@ -97,9 +98,9 @@ describe("dark theme contracts", () => { const { tokens } = readDarkThemeTokens(theme); expect(tokens.bg).toBe("var(--workspace-editor)"); - expect(contrastRatio(tokens.text, "#191e1b")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio(tokens.heading, "#191e1b")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio(tokens.accent, "#191e1b")).toBeGreaterThanOrEqual(3); + expect(contrastRatio(tokens.text, "#1c1c1c")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio(tokens.heading, "#1c1c1c")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio(tokens.accent, "#1c1c1c")).toBeGreaterThanOrEqual(3); expect(contrastRatio(tokens.muted, tokens.soft)).toBeGreaterThanOrEqual(4.5); expect(contrastRatio(tokens["code-text"], tokens["code-bg"])).toBeGreaterThanOrEqual(4.5); } diff --git a/apps/web/src/lib/ui-palette.test.mjs b/apps/web/src/lib/ui-palette.test.mjs index 779561fd..57d3c653 100644 --- a/apps/web/src/lib/ui-palette.test.mjs +++ b/apps/web/src/lib/ui-palette.test.mjs @@ -27,7 +27,7 @@ describe("application color system", () => { expect(globals).not.toContain("--accent-foreground: 158 70% 25%;"); expect(globals).toContain("--switch-track-on: #525252;"); expect(globals).toContain("--checkbox-on: #525252;"); - expect(globals).toContain("--switch-track-on: #e7ebe8;"); + expect(globals).toContain("--switch-track-on: #e8e8e8;"); expect(switchSource).toContain("data-[state=checked]:bg-[var(--switch-track-on)]"); expect(switchSource).not.toContain("bg-emerald-500"); expect(checkbox).toContain("data-[state=checked]:bg-[var(--checkbox-on)]"); @@ -35,7 +35,7 @@ describe("application color system", () => { expect(settings).not.toContain("text-emerald-"); expect(contrastRatio("#ffffff", "#525252")).toBeGreaterThanOrEqual(4.5); expect(contrastRatio("#ffffff", "#1a1d21")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio("#101311", "#e7ebe8")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#101010", "#e8e8e8")).toBeGreaterThanOrEqual(4.5); }); test("keeps the light workspace on a cool gray palette while preserving text hierarchy", () => { @@ -62,15 +62,17 @@ describe("application color system", () => { expect(contrastRatio("#737373", "#f8fafb")).toBeGreaterThanOrEqual(4.5); }); - test("keeps dark workspace surfaces distinct without blue-black color casts", () => { - expect(globals).toContain("--workspace-canvas: #101311;"); - expect(globals).toContain("--workspace-sidebar: #121612;"); - expect(globals).toContain("--workspace-memo-list: #151a17;"); - expect(globals).toContain("--workspace-editor: #191e1b;"); + test("keeps dark workspace surfaces distinct and neutral", () => { + expect(globals).toContain("--workspace-canvas: #101010;"); + expect(globals).toContain("--workspace-sidebar: #141414;"); + expect(globals).toContain("--workspace-memo-list: #181818;"); + expect(globals).toContain("--workspace-editor: #1c1c1c;"); + expect(globals).toContain("--foreground: 0 0% 87%;"); + expect(globals).toContain("--border: 0 0% 23%;"); expect(globals).toContain("--amber-300-rgb: 180 83 9;"); expect(globals).not.toContain("scrollbar-color: rgba(100, 116, 139, 0.18)"); - expect(contrastRatio("#cad4ce", "#191e1b")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio("#9aa9a0", "#191e1b")).toBeGreaterThanOrEqual(4.5); - expect(contrastRatio("#84948a", "#191e1b")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#dedede", "#1c1c1c")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#a3a3a3", "#1c1c1c")).toBeGreaterThanOrEqual(4.5); + expect(contrastRatio("#a0a0a0", "#1c1c1c")).toBeGreaterThanOrEqual(4.5); }); }); diff --git a/apps/web/src/styles/editor-themes/minimal-emerald.css b/apps/web/src/styles/editor-themes/minimal-emerald.css index a640fbdd..69065a99 100644 --- a/apps/web/src/styles/editor-themes/minimal-emerald.css +++ b/apps/web/src/styles/editor-themes/minimal-emerald.css @@ -16,13 +16,13 @@ :root.dark .edgeever-editor[data-editor-theme="minimal-emerald"]:not([data-editor-theme="default"]) { --editor-theme-bg: var(--workspace-editor); - --editor-theme-text: #d8e0db; - --editor-theme-muted: #97a59c; - --editor-theme-heading: #f0f4f1; + --editor-theme-text: #dedede; + --editor-theme-muted: #a3a3a3; + --editor-theme-heading: #f2f2f2; --editor-theme-accent: #4fd1a1; - --editor-theme-soft: #202923; - --editor-theme-border: #314039; - --editor-theme-code-bg: #111713; + --editor-theme-soft: #252525; + --editor-theme-border: #3b3b3b; + --editor-theme-code-bg: #151515; --editor-theme-code-text: #7ee0bc; } diff --git a/apps/web/src/styles/editor-themes/modern-mint.css b/apps/web/src/styles/editor-themes/modern-mint.css index 6404ba7b..744711f3 100644 --- a/apps/web/src/styles/editor-themes/modern-mint.css +++ b/apps/web/src/styles/editor-themes/modern-mint.css @@ -16,13 +16,13 @@ :root.dark .edgeever-editor[data-editor-theme="modern-mint"]:not([data-editor-theme="default"]) { --editor-theme-bg: var(--workspace-editor); - --editor-theme-text: #d2ded9; - --editor-theme-muted: #90a49b; - --editor-theme-heading: #eff6f3; + --editor-theme-text: #dcdcdc; + --editor-theme-muted: #a1a1a1; + --editor-theme-heading: #f1f1f1; --editor-theme-accent: #2dc9ac; - --editor-theme-soft: #1b2b25; - --editor-theme-border: #2f473e; - --editor-theme-code-bg: #101916; + --editor-theme-soft: #242424; + --editor-theme-border: #3c3c3c; + --editor-theme-code-bg: #141414; --editor-theme-code-text: #66e5c7; } diff --git a/apps/web/src/styles/editor-themes/outline-emerald.css b/apps/web/src/styles/editor-themes/outline-emerald.css index a16d7c53..95bbb8db 100644 --- a/apps/web/src/styles/editor-themes/outline-emerald.css +++ b/apps/web/src/styles/editor-themes/outline-emerald.css @@ -16,14 +16,14 @@ :root.dark .edgeever-editor[data-editor-theme="outline-emerald"]:not([data-editor-theme="default"]) { --editor-theme-bg: var(--workspace-editor); - --editor-theme-text: #d3dcd6; - --editor-theme-muted: #8f9e95; - --editor-theme-heading: #f3f6f4; + --editor-theme-text: #dcdcdc; + --editor-theme-muted: #a0a0a0; + --editor-theme-heading: #f3f3f3; --editor-theme-accent: #66d6ae; - --editor-theme-soft: #1d2822; - --editor-theme-border: #36463d; - --editor-theme-code-bg: #0f1411; - --editor-theme-code-text: #dbe6df; + --editor-theme-soft: #242424; + --editor-theme-border: #404040; + --editor-theme-code-bg: #141414; + --editor-theme-code-text: #e2e2e2; } .edgeever-editor[data-editor-theme="outline-emerald"]:not([data-editor-theme="default"]) .ProseMirror { diff --git a/apps/web/src/styles/editor-themes/wechat-green.css b/apps/web/src/styles/editor-themes/wechat-green.css index 335924e4..0e5f9b1d 100644 --- a/apps/web/src/styles/editor-themes/wechat-green.css +++ b/apps/web/src/styles/editor-themes/wechat-green.css @@ -16,13 +16,13 @@ :root.dark .edgeever-editor[data-editor-theme="wechat-green"]:not([data-editor-theme="default"]) { --editor-theme-bg: var(--workspace-editor); - --editor-theme-text: #d7ded9; - --editor-theme-muted: #9aa69e; - --editor-theme-heading: #f5f7f5; + --editor-theme-text: #dedede; + --editor-theme-muted: #a3a3a3; + --editor-theme-heading: #f5f5f5; --editor-theme-accent: #3ecf78; - --editor-theme-soft: #1c2a21; - --editor-theme-border: #314439; - --editor-theme-code-bg: #111a15; + --editor-theme-soft: #252525; + --editor-theme-border: #3b3b3b; + --editor-theme-code-bg: #151515; --editor-theme-code-text: #70dfa0; } diff --git a/apps/web/src/styles/globals.css b/apps/web/src/styles/globals.css index d86a78b4..a351a374 100644 --- a/apps/web/src/styles/globals.css +++ b/apps/web/src/styles/globals.css @@ -369,58 +369,58 @@ :root.dark { color-scheme: dark; - --background: 150 8% 8%; - --foreground: 144 9% 88%; - --card: 150 10% 13%; - --card-foreground: 144 9% 88%; - --popover: 150 10% 14%; - --popover-foreground: 144 9% 88%; - --primary: 140 10% 92%; - --primary-foreground: 150 12% 8%; - --secondary: 150 8% 18%; - --secondary-foreground: 140 10% 90%; - --muted: 150 8% 18%; - --muted-foreground: 145 8% 62%; - --accent: 140 8% 18%; - --accent-foreground: 140 10% 93%; + --background: 0 0% 7%; + --foreground: 0 0% 87%; + --card: 0 0% 12%; + --card-foreground: 0 0% 87%; + --popover: 0 0% 13%; + --popover-foreground: 0 0% 87%; + --primary: 0 0% 92%; + --primary-foreground: 0 0% 7%; + --secondary: 0 0% 18%; + --secondary-foreground: 0 0% 90%; + --muted: 0 0% 18%; + --muted-foreground: 0 0% 63%; + --accent: 0 0% 18%; + --accent-foreground: 0 0% 93%; --destructive: 0 72% 51%; - --destructive-foreground: 144 12% 96%; - --border: 150 10% 23%; - --input: 150 10% 23%; - --ring: 140 8% 75%; - --workspace-canvas: #101311; - --workspace-sidebar: #121612; - --workspace-memo-list: #151a17; - --workspace-editor: #191e1b; - --workspace-divider: #2a312d; - --workspace-memo-divider: #3b4540; - --workspace-selection: #1d3028; + --destructive-foreground: 0 0% 96%; + --border: 0 0% 23%; + --input: 0 0% 23%; + --ring: 0 0% 75%; + --workspace-canvas: #101010; + --workspace-sidebar: #141414; + --workspace-memo-list: #181818; + --workspace-editor: #1c1c1c; + --workspace-divider: #303030; + --workspace-memo-divider: #404040; + --workspace-selection: #303030; --workspace-hover: color-mix(in srgb, var(--workspace-sidebar) 82%, white); - --memo-content-divider-color: #e7ebe8; - --tooltip-bg: #2c3330; - --tooltip-fg: #d7dfda; - --tooltip-border: #3e4944; + --memo-content-divider-color: #e8e8e8; + --tooltip-bg: #2c2c2c; + --tooltip-fg: #dedede; + --tooltip-border: #454545; --tooltip-shadow: 0 1px 2px rgb(0 0 0 / 0.28), 0 8px 20px rgb(0 0 0 / 0.32); - --scrollbar-thumb: rgb(137 150 142 / 0.38); - --scrollbar-thumb-hover: rgb(137 150 142 / 0.55); + --scrollbar-thumb: rgb(145 145 145 / 0.38); + --scrollbar-thumb-hover: rgb(145 145 145 / 0.55); --search-match: rgb(22 160 110 / 0.32); --search-match-active: rgb(36 185 134 / 0.48); - --switch-thumb: #eef2ef; - --switch-track-on: #e7ebe8; - --switch-thumb-on: #101311; - --checkbox-on: #e7ebe8; - --checkbox-mark: #101311; - --slate-50-rgb: 15 20 17; - --slate-100-rgb: 21 28 24; - --slate-200-rgb: 38 49 43; - --slate-300-rgb: 110 124 116; - --slate-400-rgb: 132 148 138; - --slate-500-rgb: 154 169 160; - --slate-600-rgb: 182 195 187; - --slate-700-rgb: 202 212 206; - --slate-800-rgb: 221 229 224; - --slate-900-rgb: 233 239 235; - --slate-950-rgb: 238 243 240; + --switch-thumb: #f0f0f0; + --switch-track-on: #e8e8e8; + --switch-thumb-on: #101010; + --checkbox-on: #e8e8e8; + --checkbox-mark: #101010; + --slate-50-rgb: 17 17 17; + --slate-100-rgb: 25 25 25; + --slate-200-rgb: 43 43 43; + --slate-300-rgb: 116 116 116; + --slate-400-rgb: 140 140 140; + --slate-500-rgb: 161 161 161; + --slate-600-rgb: 188 188 188; + --slate-700-rgb: 208 208 208; + --slate-800-rgb: 226 226 226; + --slate-900-rgb: 238 238 238; + --slate-950-rgb: 244 244 244; --amber-50-rgb: 69 26 3; --amber-100-rgb: 80 30 5; --amber-200-rgb: 146 64 14; @@ -439,7 +439,7 @@ --rose-800-rgb: 254 205 211; --rose-950-rgb: 255 241 242; --blue-600-rgb: 147 197 253; - --dark-surface-rgb: 25 30 27; + --dark-surface-rgb: 28 28 28; --brand-green: #16a06e; --brand-green-hover: #24b986; --brand-green-muted: #183a31;