summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSuad Wolgram <[email protected]>2026-01-21 22:34:27 +0100
committerGitHub <[email protected]>2026-01-21 15:34:27 -0600
commit936f3ebe95c39e2f1e77c2db349c9349276e6cac (patch)
treea225200c26933a593bc08e4106810533aa49284c
parent23daac21703f9d67a62b7438e6dd1e5fed5ca559 (diff)
downloadopencode-936f3ebe95c39e2f1e77c2db349c9349276e6cac.tar.gz
opencode-936f3ebe95c39e2f1e77c2db349c9349276e6cac.zip
feat(ui): add gruvbox theme (Web/App) (#9855)
-rw-r--r--packages/opencode/src/cli/cmd/tui/context/theme/gruvbox.json245
-rw-r--r--packages/ui/src/theme/default-themes.ts3
-rw-r--r--packages/ui/src/theme/themes/gruvbox.json132
3 files changed, 331 insertions, 49 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/context/theme/gruvbox.json b/packages/opencode/src/cli/cmd/tui/context/theme/gruvbox.json
index c3101b565..dcae30258 100644
--- a/packages/opencode/src/cli/cmd/tui/context/theme/gruvbox.json
+++ b/packages/opencode/src/cli/cmd/tui/context/theme/gruvbox.json
@@ -38,58 +38,205 @@
"lightOrange": "#af3a03"
},
"theme": {
- "primary": { "dark": "darkBlueBright", "light": "lightBlue" },
- "secondary": { "dark": "darkPurpleBright", "light": "lightPurple" },
- "accent": { "dark": "darkAquaBright", "light": "lightAqua" },
- "error": { "dark": "darkRedBright", "light": "lightRed" },
- "warning": { "dark": "darkOrangeBright", "light": "lightOrange" },
- "success": { "dark": "darkGreenBright", "light": "lightGreen" },
- "info": { "dark": "darkYellowBright", "light": "lightYellow" },
- "text": { "dark": "darkFg1", "light": "lightFg1" },
- "textMuted": { "dark": "darkGray", "light": "lightGray" },
- "background": { "dark": "darkBg0", "light": "lightBg0" },
- "backgroundPanel": { "dark": "darkBg1", "light": "lightBg1" },
- "backgroundElement": { "dark": "darkBg2", "light": "lightBg2" },
- "border": { "dark": "darkBg3", "light": "lightBg3" },
- "borderActive": { "dark": "darkFg1", "light": "lightFg1" },
- "borderSubtle": { "dark": "darkBg2", "light": "lightBg2" },
- "diffAdded": { "dark": "darkGreen", "light": "lightGreen" },
- "diffRemoved": { "dark": "darkRed", "light": "lightRed" },
- "diffContext": { "dark": "darkGray", "light": "lightGray" },
- "diffHunkHeader": { "dark": "darkAqua", "light": "lightAqua" },
- "diffHighlightAdded": { "dark": "darkGreenBright", "light": "lightGreen" },
- "diffHighlightRemoved": { "dark": "darkRedBright", "light": "lightRed" },
- "diffAddedBg": { "dark": "#32302f", "light": "#e2e0b5" },
- "diffRemovedBg": { "dark": "#322929", "light": "#e9d8d5" },
- "diffContextBg": { "dark": "darkBg1", "light": "lightBg1" },
- "diffLineNumber": { "dark": "darkBg3", "light": "lightBg3" },
- "diffAddedLineNumberBg": { "dark": "#2a2827", "light": "#d4d2a9" },
- "diffRemovedLineNumberBg": { "dark": "#2a2222", "light": "#d8cbc8" },
- "markdownText": { "dark": "darkFg1", "light": "lightFg1" },
- "markdownHeading": { "dark": "darkBlueBright", "light": "lightBlue" },
- "markdownLink": { "dark": "darkAquaBright", "light": "lightAqua" },
- "markdownLinkText": { "dark": "darkGreenBright", "light": "lightGreen" },
- "markdownCode": { "dark": "darkYellowBright", "light": "lightYellow" },
- "markdownBlockQuote": { "dark": "darkGray", "light": "lightGray" },
- "markdownEmph": { "dark": "darkPurpleBright", "light": "lightPurple" },
- "markdownStrong": { "dark": "darkOrangeBright", "light": "lightOrange" },
- "markdownHorizontalRule": { "dark": "darkGray", "light": "lightGray" },
- "markdownListItem": { "dark": "darkBlueBright", "light": "lightBlue" },
+ "primary": {
+ "dark": "darkBlueBright",
+ "light": "lightBlue"
+ },
+ "secondary": {
+ "dark": "darkPurpleBright",
+ "light": "lightPurple"
+ },
+ "accent": {
+ "dark": "darkAquaBright",
+ "light": "lightAqua"
+ },
+ "error": {
+ "dark": "darkRedBright",
+ "light": "lightRed"
+ },
+ "warning": {
+ "dark": "darkOrangeBright",
+ "light": "lightOrange"
+ },
+ "success": {
+ "dark": "darkGreenBright",
+ "light": "lightGreen"
+ },
+ "info": {
+ "dark": "darkYellowBright",
+ "light": "lightYellow"
+ },
+ "text": {
+ "dark": "darkFg1",
+ "light": "lightFg1"
+ },
+ "textMuted": {
+ "dark": "darkGray",
+ "light": "lightGray"
+ },
+ "background": {
+ "dark": "darkBg0",
+ "light": "lightBg0"
+ },
+ "backgroundPanel": {
+ "dark": "darkBg1",
+ "light": "lightBg1"
+ },
+ "backgroundElement": {
+ "dark": "darkBg2",
+ "light": "lightBg2"
+ },
+ "border": {
+ "dark": "darkBg3",
+ "light": "lightBg3"
+ },
+ "borderActive": {
+ "dark": "darkFg1",
+ "light": "lightFg1"
+ },
+ "borderSubtle": {
+ "dark": "darkBg2",
+ "light": "lightBg2"
+ },
+ "diffAdded": {
+ "dark": "darkGreen",
+ "light": "lightGreen"
+ },
+ "diffRemoved": {
+ "dark": "darkRed",
+ "light": "lightRed"
+ },
+ "diffContext": {
+ "dark": "darkGray",
+ "light": "lightGray"
+ },
+ "diffHunkHeader": {
+ "dark": "darkAqua",
+ "light": "lightAqua"
+ },
+ "diffHighlightAdded": {
+ "dark": "darkGreenBright",
+ "light": "lightGreen"
+ },
+ "diffHighlightRemoved": {
+ "dark": "darkRedBright",
+ "light": "lightRed"
+ },
+ "diffAddedBg": {
+ "dark": "#32302f",
+ "light": "#dcd8a4"
+ },
+ "diffRemovedBg": {
+ "dark": "#322929",
+ "light": "#e2c7c3"
+ },
+ "diffContextBg": {
+ "dark": "darkBg1",
+ "light": "lightBg1"
+ },
+ "diffLineNumber": {
+ "dark": "darkBg3",
+ "light": "lightBg3"
+ },
+ "diffAddedLineNumberBg": {
+ "dark": "#2a2827",
+ "light": "#cec99e"
+ },
+ "diffRemovedLineNumberBg": {
+ "dark": "#2a2222",
+ "light": "#d3bdb9"
+ },
+ "markdownText": {
+ "dark": "darkFg1",
+ "light": "lightFg1"
+ },
+ "markdownHeading": {
+ "dark": "darkBlueBright",
+ "light": "lightBlue"
+ },
+ "markdownLink": {
+ "dark": "darkAquaBright",
+ "light": "lightAqua"
+ },
+ "markdownLinkText": {
+ "dark": "darkGreenBright",
+ "light": "lightGreen"
+ },
+ "markdownCode": {
+ "dark": "darkYellowBright",
+ "light": "lightYellow"
+ },
+ "markdownBlockQuote": {
+ "dark": "darkGray",
+ "light": "lightGray"
+ },
+ "markdownEmph": {
+ "dark": "darkPurpleBright",
+ "light": "lightPurple"
+ },
+ "markdownStrong": {
+ "dark": "darkOrangeBright",
+ "light": "lightOrange"
+ },
+ "markdownHorizontalRule": {
+ "dark": "darkGray",
+ "light": "lightGray"
+ },
+ "markdownListItem": {
+ "dark": "darkBlueBright",
+ "light": "lightBlue"
+ },
"markdownListEnumeration": {
"dark": "darkAquaBright",
"light": "lightAqua"
},
- "markdownImage": { "dark": "darkAquaBright", "light": "lightAqua" },
- "markdownImageText": { "dark": "darkGreenBright", "light": "lightGreen" },
- "markdownCodeBlock": { "dark": "darkFg1", "light": "lightFg1" },
- "syntaxComment": { "dark": "darkGray", "light": "lightGray" },
- "syntaxKeyword": { "dark": "darkRedBright", "light": "lightRed" },
- "syntaxFunction": { "dark": "darkGreenBright", "light": "lightGreen" },
- "syntaxVariable": { "dark": "darkBlueBright", "light": "lightBlue" },
- "syntaxString": { "dark": "darkYellowBright", "light": "lightYellow" },
- "syntaxNumber": { "dark": "darkPurpleBright", "light": "lightPurple" },
- "syntaxType": { "dark": "darkAquaBright", "light": "lightAqua" },
- "syntaxOperator": { "dark": "darkOrangeBright", "light": "lightOrange" },
- "syntaxPunctuation": { "dark": "darkFg1", "light": "lightFg1" }
+ "markdownImage": {
+ "dark": "darkAquaBright",
+ "light": "lightAqua"
+ },
+ "markdownImageText": {
+ "dark": "darkGreenBright",
+ "light": "lightGreen"
+ },
+ "markdownCodeBlock": {
+ "dark": "darkFg1",
+ "light": "lightFg1"
+ },
+ "syntaxComment": {
+ "dark": "darkGray",
+ "light": "lightGray"
+ },
+ "syntaxKeyword": {
+ "dark": "darkRedBright",
+ "light": "lightRed"
+ },
+ "syntaxFunction": {
+ "dark": "darkGreenBright",
+ "light": "lightGreen"
+ },
+ "syntaxVariable": {
+ "dark": "darkBlueBright",
+ "light": "lightBlue"
+ },
+ "syntaxString": {
+ "dark": "darkYellowBright",
+ "light": "lightYellow"
+ },
+ "syntaxNumber": {
+ "dark": "darkPurpleBright",
+ "light": "lightPurple"
+ },
+ "syntaxType": {
+ "dark": "darkAquaBright",
+ "light": "lightAqua"
+ },
+ "syntaxOperator": {
+ "dark": "darkOrangeBright",
+ "light": "lightOrange"
+ },
+ "syntaxPunctuation": {
+ "dark": "darkFg1",
+ "light": "lightFg1"
+ }
}
}
diff --git a/packages/ui/src/theme/default-themes.ts b/packages/ui/src/theme/default-themes.ts
index e90892a8e..d2c40c28d 100644
--- a/packages/ui/src/theme/default-themes.ts
+++ b/packages/ui/src/theme/default-themes.ts
@@ -12,6 +12,7 @@ import shadesOfPurpleThemeJson from "./themes/shadesofpurple.json"
import nightowlThemeJson from "./themes/nightowl.json"
import vesperThemeJson from "./themes/vesper.json"
import carbonfoxThemeJson from "./themes/carbonfox.json"
+import gruvboxThemeJson from "./themes/gruvbox.json"
export const oc1Theme = oc1ThemeJson as DesktopTheme
export const tokyonightTheme = tokyoThemeJson as DesktopTheme
@@ -26,6 +27,7 @@ export const shadesOfPurpleTheme = shadesOfPurpleThemeJson as DesktopTheme
export const nightowlTheme = nightowlThemeJson as DesktopTheme
export const vesperTheme = vesperThemeJson as DesktopTheme
export const carbonfoxTheme = carbonfoxThemeJson as DesktopTheme
+export const gruvboxTheme = gruvboxThemeJson as DesktopTheme
export const DEFAULT_THEMES: Record<string, DesktopTheme> = {
"oc-1": oc1Theme,
@@ -41,4 +43,5 @@ export const DEFAULT_THEMES: Record<string, DesktopTheme> = {
nightowl: nightowlTheme,
vesper: vesperTheme,
carbonfox: carbonfoxTheme,
+ gruvbox: gruvboxTheme,
}
diff --git a/packages/ui/src/theme/themes/gruvbox.json b/packages/ui/src/theme/themes/gruvbox.json
new file mode 100644
index 000000000..cf87ccd55
--- /dev/null
+++ b/packages/ui/src/theme/themes/gruvbox.json
@@ -0,0 +1,132 @@
+{
+ "$schema": "https://opencode.ai/desktop-theme.json",
+ "name": "Gruvbox",
+ "id": "gruvbox",
+ "light": {
+ "seeds": {
+ "neutral": "#fbf1c7",
+ "primary": "#076678",
+ "success": "#79740e",
+ "warning": "#b57614",
+ "error": "#9d0006",
+ "info": "#8f3f71",
+ "interactive": "#076678",
+ "diffAdd": "#79740e",
+ "diffDelete": "#9d0006"
+ },
+ "overrides": {
+ "background-base": "#fbf1c7",
+ "background-weak": "#f2e5bc",
+ "background-strong": "#f9f5d7",
+ "background-stronger": "#fdf9e8",
+ "surface-raised-stronger-non-alpha": "#fbfaf5",
+ "border-weak-base": "#d5c4a1",
+ "border-weak-hover": "#c9b897",
+ "border-weak-active": "#bdae93",
+ "border-weak-selected": "#b0a285",
+ "border-weak-disabled": "#f0e4b8",
+ "border-weak-focus": "#c4b590",
+ "border-base": "#bdae93",
+ "border-hover": "#b0a285",
+ "border-active": "#a89984",
+ "border-selected": "#928374",
+ "border-disabled": "#e5d9ad",
+ "border-focus": "#a89984",
+ "border-strong-base": "#7c6f64",
+ "border-strong-hover": "#6e6259",
+ "border-strong-active": "#665c54",
+ "border-strong-selected": "#5a524b",
+ "border-strong-disabled": "#c9bda1",
+ "border-strong-focus": "#665c54",
+ "surface-diff-add-base": "#dde3b1",
+ "surface-diff-delete-base": "#e8c7c3",
+ "surface-diff-hidden-base": "#ebdfb5",
+ "text-base": "#3c3836",
+ "text-weak": "#7c6f64",
+ "text-strong": "#282828",
+ "syntax-string": "#79740e",
+ "syntax-primitive": "#9d0006",
+ "syntax-property": "#076678",
+ "syntax-type": "#b57614",
+ "syntax-constant": "#8f3f71",
+ "syntax-info": "#427b58",
+ "markdown-heading": "#076678",
+ "markdown-text": "#3c3836",
+ "markdown-link": "#076678",
+ "markdown-link-text": "#427b58",
+ "markdown-code": "#79740e",
+ "markdown-block-quote": "#928374",
+ "markdown-emph": "#8f3f71",
+ "markdown-strong": "#af3a03",
+ "markdown-horizontal-rule": "#d5c4a1",
+ "markdown-list-item": "#076678",
+ "markdown-list-enumeration": "#427b58",
+ "markdown-image": "#076678",
+ "markdown-image-text": "#427b58",
+ "markdown-code-block": "#3c3836"
+ }
+ },
+ "dark": {
+ "seeds": {
+ "neutral": "#282828",
+ "primary": "#83a598",
+ "success": "#b8bb26",
+ "warning": "#fabd2f",
+ "error": "#fb4934",
+ "info": "#d3869b",
+ "interactive": "#83a598",
+ "diffAdd": "#b8bb26",
+ "diffDelete": "#fb4934"
+ },
+ "overrides": {
+ "background-base": "#282828",
+ "background-weak": "#32302f",
+ "background-strong": "#1d2021",
+ "background-stronger": "#141617",
+ "border-weak-base": "#504945",
+ "border-weak-hover": "#5a524b",
+ "border-weak-active": "#665c54",
+ "border-weak-selected": "#70665d",
+ "border-weak-disabled": "#1e1d1c",
+ "border-weak-focus": "#5e5650",
+ "border-base": "#665c54",
+ "border-hover": "#70665d",
+ "border-active": "#7c6f64",
+ "border-selected": "#928374",
+ "border-disabled": "#2a2827",
+ "border-focus": "#7c6f64",
+ "border-strong-base": "#928374",
+ "border-strong-hover": "#9d8e7f",
+ "border-strong-active": "#a89984",
+ "border-strong-selected": "#b3a48f",
+ "border-strong-disabled": "#3c3836",
+ "border-strong-focus": "#a89984",
+ "surface-diff-add-base": "#2a3325",
+ "surface-diff-delete-base": "#3c2222",
+ "surface-diff-hidden-base": "#32302f",
+ "text-base": "#ebdbb2",
+ "text-weak": "#a89984",
+ "text-strong": "#fbf1c7",
+ "syntax-string": "#b8bb26",
+ "syntax-primitive": "#fb4934",
+ "syntax-property": "#83a598",
+ "syntax-type": "#fabd2f",
+ "syntax-constant": "#d3869b",
+ "syntax-info": "#8ec07c",
+ "markdown-heading": "#83a598",
+ "markdown-text": "#ebdbb2",
+ "markdown-link": "#83a598",
+ "markdown-link-text": "#8ec07c",
+ "markdown-code": "#b8bb26",
+ "markdown-block-quote": "#928374",
+ "markdown-emph": "#d3869b",
+ "markdown-strong": "#fe8019",
+ "markdown-horizontal-rule": "#504945",
+ "markdown-list-item": "#83a598",
+ "markdown-list-enumeration": "#8ec07c",
+ "markdown-image": "#83a598",
+ "markdown-image-text": "#8ec07c",
+ "markdown-code-block": "#ebdbb2"
+ }
+ }
+}