move to v2

Kujtim Hoxha created

Change summary

cmd/root.go                                       |   5 
go.mod                                            |  21 
go.sum                                            |  47 +-
internal/diff/diff.go                             |  20 
internal/format/spinner.go                        |   4 
internal/tui/components/chat/chat.go              |   2 
internal/tui/components/chat/editor.go            |  41 +
internal/tui/components/chat/list.go              |  24 
internal/tui/components/chat/message.go           |  34 -
internal/tui/components/chat/sidebar.go           |   7 
internal/tui/components/core/status.go            |   6 
internal/tui/components/dialog/arguments.go       |  50 +-
internal/tui/components/dialog/commands.go        |   8 
internal/tui/components/dialog/complete.go        |  10 
internal/tui/components/dialog/custom_commands.go |   2 
internal/tui/components/dialog/filepicker.go      |  26 
internal/tui/components/dialog/help.go            |  13 
internal/tui/components/dialog/init.go            |   6 
internal/tui/components/dialog/models.go          |   9 
internal/tui/components/dialog/permission.go      |  37 
internal/tui/components/dialog/quit.go            |  10 
internal/tui/components/dialog/session.go         |  11 
internal/tui/components/dialog/theme.go           |   9 
internal/tui/components/logs/details.go           |  23 
internal/tui/components/logs/table.go             |  11 
internal/tui/components/util/simple-list.go       |   9 
internal/tui/image/images.go                      |   5 
internal/tui/layout/container.go                  |  16 
internal/tui/layout/layout.go                     |   4 
internal/tui/layout/overlay.go                    |   4 
internal/tui/layout/split.go                      |  10 
internal/tui/page/chat.go                         |  12 
internal/tui/page/logs.go                         |   9 
internal/tui/styles/background.go                 | 123 ------
internal/tui/styles/markdown.go                   | 120 ++--
internal/tui/styles/styles.go                     |  40 
internal/tui/theme/catppuccin.go                  | 346 ++++++----------
internal/tui/theme/dracula.go                     | 272 ++----------
internal/tui/theme/flexoki.go                     | 340 ++++++----------
internal/tui/theme/gruvbox.go                     | 334 ++++++----------
internal/tui/theme/monokai.go                     | 334 ++++++----------
internal/tui/theme/onedark.go                     | 334 ++++++----------
internal/tui/theme/opencode.go                    | 343 ++++++----------
internal/tui/theme/theme.go                       | 325 +++++++--------
internal/tui/theme/tokyonight.go                  | 334 ++++++----------
internal/tui/theme/tron.go                        | 334 ++++++----------
internal/tui/tui.go                               |  26 
internal/tui/util/util.go                         |   7 
48 files changed, 1,591 insertions(+), 2,526 deletions(-)

Detailed changes

cmd/root.go 🔗

@@ -7,8 +7,7 @@ import (
 	"sync"
 	"time"
 
-	tea "github.com/charmbracelet/bubbletea"
-	zone "github.com/lrstanley/bubblezone"
+	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/db"
@@ -114,9 +113,7 @@ to assist developers in writing, debugging, and understanding code directly from
 			return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
 		}
 
-		// Interactive mode
 		// Set up the TUI
-		zone.NewGlobal()
 		program := tea.NewProgram(
 			tui.New(app),
 			tea.WithAltScreen(),

go.mod 🔗

@@ -11,15 +11,14 @@ require (
 	github.com/aymanbagabas/go-udiff v0.2.0
 	github.com/bmatcuk/doublestar/v4 v4.8.1
 	github.com/catppuccin/go v0.3.0
-	github.com/charmbracelet/bubbles v0.21.0
-	github.com/charmbracelet/bubbletea v1.3.5
-	github.com/charmbracelet/glamour v0.9.1
-	github.com/charmbracelet/lipgloss v1.1.0
-	github.com/charmbracelet/x/ansi v0.8.0
+	github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1
+	github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1
+	github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6
+	github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40
+	github.com/charmbracelet/x/ansi v0.9.2
 	github.com/fsnotify/fsnotify v1.8.0
 	github.com/go-logfmt/logfmt v0.6.0
 	github.com/google/uuid v1.6.0
-	github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
 	github.com/mark3labs/mcp-go v0.17.0
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
 	github.com/muesli/reflow v0.3.0
@@ -58,13 +57,15 @@ require (
 	github.com/aws/smithy-go v1.20.3 // indirect
 	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
 	github.com/aymerick/douceur v0.2.0 // indirect
-	github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
-	github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
+	github.com/charmbracelet/colorprofile v0.3.0 // indirect
+	github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da // indirect
+	github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect
+	github.com/charmbracelet/x/input v0.3.4 // indirect
 	github.com/charmbracelet/x/term v0.2.1 // indirect
+	github.com/charmbracelet/x/windows v0.2.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/disintegration/imaging v1.6.2
 	github.com/dlclark/regexp2 v1.11.4 // indirect
-	github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
@@ -81,7 +82,6 @@ require (
 	github.com/lithammer/fuzzysearch v1.1.8
 	github.com/lucasb-eyer/go-colorful v1.2.0
 	github.com/mattn/go-isatty v0.0.20 // indirect
-	github.com/mattn/go-localereader v0.0.1 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/mfridman/interpolate v0.0.2 // indirect
 	github.com/microcosm-cc/bluemonday v1.0.27 // indirect
@@ -119,7 +119,6 @@ require (
 	golang.org/x/net v0.39.0 // indirect
 	golang.org/x/sync v0.13.0 // indirect
 	golang.org/x/sys v0.32.0 // indirect
-	golang.org/x/term v0.31.0 // indirect
 	golang.org/x/text v0.24.0 // indirect
 	google.golang.org/genai v1.3.0
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect

go.sum 🔗

@@ -68,24 +68,30 @@ github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR
 github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
 github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
 github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
-github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
-github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
-github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
-github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
-github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
-github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
-github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
-github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
-github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
-github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
-github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
-github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1 h1:swACzss0FjnyPz1enfX56GKkLiuKg5FlyVmOLIlU2kE=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1 h1:yaxFt97mvofGY7bYZn8U/aSVoamXGE3O4AEvWhshUDI=
+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1/go.mod h1:qbcZLI5z8R49v9xBdU5V5Dh5D2uccx8wSwBqxQyErqc=
+github.com/charmbracelet/colorprofile v0.3.0 h1:KtLh9uuu1RCt+Hml4s6Hz+kB1PfV3wi++1h5ia65yKQ=
+github.com/charmbracelet/colorprofile v0.3.0/go.mod h1:oHJ340RS2nmG1zRGPmhJKJ/jf4FPNNk0P39/wBPA1G0=
+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6 h1:AKhOV8dSRU3KpqMgpGME9JU7ouumB2S6hMmD6PRJeTc=
+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6/go.mod h1:7xBAUTCSADx9mHG0uBf4NDoVpYxMzIQ2j/NMLGdFsFM=
+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40 h1:SxOUomYAVo5zh+6WCH1bGshlAnSKP0ZeovI0FHAl9kg=
+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40/go.mod h1:tRlx/Hu0lo/j9viunCN2H+Ze6JrmdjQlXUQvvArgaOc=
+github.com/charmbracelet/x/ansi v0.9.2 h1:92AGsQmNTRMzuzHEYfCdjQeUzTrgE1vfO5/7fEVoXdY=
+github.com/charmbracelet/x/ansi v0.9.2/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da h1:8MGKD5WBtuzfXglq0CnyzVSwGojv57X+H46OL9OUyRA=
+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a h1:FsHEJ52OC4VuTzU8t+n5frMjLvpYWEznSr/u8tnkCYw=
+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=
+github.com/charmbracelet/x/input v0.3.4 h1:Mujmnv/4DaitU0p+kIsrlfZl/UlmeLKw1wAP3e1fMN0=
+github.com/charmbracelet/x/input v0.3.4/go.mod h1:JI8RcvdZWQIhn09VzeK3hdp4lTz7+yhiEdpEQtZN+2c=
 github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
 github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/charmbracelet/x/windows v0.2.0 h1:ilXA1GJjTNkgOm94CLPeSz7rar54jtFatdmoiONPuEw=
+github.com/charmbracelet/x/windows v0.2.0/go.mod h1:ZibNFR49ZFqCXgP76sYanisxRyC+EYrBE7TTknD8s1s=
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -96,8 +102,6 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA
 github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
-github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
@@ -146,16 +150,12 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
 github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
-github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231 h1:9rjt7AfnrXKNSZhp36A3/4QAZAwGGCGD/p8Bse26zms=
-github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231/go.mod h1:S5etECMx+sZnW0Gm100Ma9J1PgVCTgNyFaqGu2b08b4=
 github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
 github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
 github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
-github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -297,7 +297,6 @@ golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -318,8 +317,6 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
 golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
-golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
-golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=

internal/diff/diff.go 🔗

@@ -3,6 +3,7 @@ package diff
 import (
 	"bytes"
 	"fmt"
+	"image/color"
 	"io"
 	"regexp"
 	"strconv"
@@ -13,7 +14,7 @@ import (
 	"github.com/alecthomas/chroma/v2/lexers"
 	"github.com/alecthomas/chroma/v2/styles"
 	"github.com/aymanbagabas/go-udiff"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/charmbracelet/x/ansi"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
@@ -323,7 +324,7 @@ func pairLines(lines []DiffLine) []linePair {
 // -------------------------------------------------------------------------
 
 // SyntaxHighlight applies syntax highlighting to text based on file extension
-func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipgloss.TerminalColor) error {
+func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg color.Color) error {
 	t := theme.CurrentTheme()
 
 	// Determine the language lexer to use
@@ -531,16 +532,13 @@ func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipglos
 	return f.Format(w, s, it)
 }
 
-// getColor returns the appropriate hex color string based on terminal background
-func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
-	if lipgloss.HasDarkBackground() {
-		return adaptiveColor.Dark
-	}
-	return adaptiveColor.Light
+func getColor(c color.Color) string {
+	rgba := color.RGBAModel.Convert(c).(color.RGBA)
+	return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
 }
 
 // highlightLine applies syntax highlighting to a single line
-func highlightLine(fileName string, line string, bg lipgloss.TerminalColor) string {
+func highlightLine(fileName string, line string, bg color.Color) string {
 	var buf bytes.Buffer
 	err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
 	if err != nil {
@@ -563,7 +561,7 @@ func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, contextLineS
 // Rendering Functions
 // -------------------------------------------------------------------------
 
-func lipglossToHex(color lipgloss.Color) string {
+func lipglossToHex(color color.Color) string {
 	r, g, b, a := color.RGBA()
 
 	// Scale uint32 values (0-65535) to uint8 (0-255).
@@ -576,7 +574,7 @@ func lipglossToHex(color lipgloss.Color) string {
 }
 
 // applyHighlighting applies intra-line highlighting to a piece of text
-func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg lipgloss.AdaptiveColor) string {
+func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg color.Color) string {
 	// Find all ANSI sequences in the content
 	ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
 	ansiMatches := ansiRegex.FindAllStringIndex(content, -1)

internal/format/spinner.go 🔗

@@ -5,8 +5,8 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/charmbracelet/bubbles/spinner"
-	tea "github.com/charmbracelet/bubbletea"
+	"github.com/charmbracelet/bubbles/v2/spinner"
+	tea "github.com/charmbracelet/bubbletea/v2"
 )
 
 // Spinner wraps the bubbles spinner for non-interactive mode

internal/tui/components/chat/chat.go 🔗

@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"sort"
 
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/charmbracelet/x/ansi"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/message"

internal/tui/components/chat/editor.go 🔗

@@ -8,10 +8,10 @@ import (
 	"strings"
 	"unicode"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/textarea"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/textarea"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/logging"
 	"github.com/opencode-ai/opencode/internal/message"
@@ -162,7 +162,7 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			return m, cmd
 		}
 		m.attachments = append(m.attachments, msg.Attachment)
-	case tea.KeyMsg:
+	case tea.KeyPressMsg:
 		if key.Matches(msg, DeleteKeyMaps.AttachmentDeleteMode) {
 			m.deleteMode = true
 			return m, nil
@@ -172,8 +172,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			m.attachments = nil
 			return m, nil
 		}
-		if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
-			num := int(msg.Runes[0] - '0')
+		rune := msg.Code
+		if m.deleteMode && unicode.IsDigit(rune) {
+			num := int(rune - '0')
 			m.deleteMode = false
 			if num < 10 && len(m.attachments) > num {
 				if num == 0 {
@@ -286,14 +287,22 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
 	textMutedColor := t.TextMuted()
 
 	ta := textarea.New()
-	ta.BlurredStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
-	ta.BlurredStyle.CursorLine = styles.BaseStyle().Background(bgColor)
-	ta.BlurredStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
-	ta.BlurredStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
-	ta.FocusedStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
-	ta.FocusedStyle.CursorLine = styles.BaseStyle().Background(bgColor)
-	ta.FocusedStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
-	ta.FocusedStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+	s := textarea.DefaultDarkStyles()
+	b := s.Blurred
+	b.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+	b.CursorLine = styles.BaseStyle().Background(bgColor)
+	b.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
+	b.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+
+	f := s.Focused
+	f.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+	f.CursorLine = styles.BaseStyle().Background(bgColor)
+	f.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
+	f.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+
+	s.Focused = f
+	s.Blurred = b
+	ta.Styles = s
 
 	ta.Prompt = " "
 	ta.ShowLineNumbers = false
@@ -309,7 +318,7 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
 	return ta
 }
 
-func NewEditorCmp(app *app.App) tea.Model {
+func NewEditorCmp(app *app.App) util.Model {
 	ta := CreateTextArea(nil)
 	return &editorCmp{
 		app:      app,

internal/tui/components/chat/list.go 🔗

@@ -5,11 +5,11 @@ import (
 	"fmt"
 	"math"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/spinner"
-	"github.com/charmbracelet/bubbles/viewport"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/spinner"
+	"github.com/charmbracelet/bubbles/v2/viewport"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/message"
 	"github.com/opencode-ai/opencode/internal/pubsub"
@@ -426,10 +426,10 @@ func (m *messagesCmp) SetSize(width, height int) tea.Cmd {
 	}
 	m.width = width
 	m.height = height
-	m.viewport.Width = width
-	m.viewport.Height = height - 2
-	m.attachments.Width = width + 40
-	m.attachments.Height = 3
+	m.viewport.SetWidth(width)
+	m.viewport.SetHeight(height - 2)
+	m.attachments.SetWidth(width + 40)
+	m.attachments.SetHeight(3)
 	m.rerender()
 	return nil
 }
@@ -468,11 +468,11 @@ func (m *messagesCmp) BindingKeys() []key.Binding {
 	}
 }
 
-func NewMessagesCmp(app *app.App) tea.Model {
+func NewMessagesCmp(app *app.App) util.Model {
 	s := spinner.New()
 	s.Spinner = spinner.Pulse
-	vp := viewport.New(0, 0)
-	attachmets := viewport.New(0, 0)
+	vp := viewport.New()
+	attachmets := viewport.New()
 	vp.KeyMap.PageUp = messageKeys.PageUp
 	vp.KeyMap.PageDown = messageKeys.PageDown
 	vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp

internal/tui/components/chat/message.go 🔗

@@ -8,7 +8,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/charmbracelet/x/ansi"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/diff"
@@ -60,7 +60,7 @@ func renderMessage(msg string, isUser bool, isFocused bool, width int, info ...s
 
 	// Apply markdown formatting and handle background color
 	parts := []string{
-		styles.ForceReplaceBackgroundWithLipgloss(toMarkdown(msg, isFocused, width), t.Background()),
+		toMarkdown(msg, isFocused, width),
 	}
 
 	// Remove newline at the end
@@ -454,16 +454,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
 	resultContent := truncateHeight(response.Content, maxResultHeight)
 	switch toolCall.Name {
 	case agent.AgentToolName:
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, false, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, false, width)
 	case tools.BashToolName:
 		resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, true, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, true, width)
 	case tools.EditToolName:
 		metadata := tools.EditResponseMetadata{}
 		json.Unmarshal([]byte(response.Metadata), &metadata)
@@ -481,10 +475,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
 			mdFormat = "html"
 		}
 		resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, true, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, true, width)
 	case tools.GlobToolName:
 		return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
 	case tools.GrepToolName:
@@ -503,10 +494,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
 			ext = strings.ToLower(ext[1:])
 		}
 		resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, true, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, true, width)
 	case tools.WriteToolName:
 		params := tools.WriteParams{}
 		json.Unmarshal([]byte(toolCall.Input), &params)
@@ -519,16 +507,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
 			ext = strings.ToLower(ext[1:])
 		}
 		resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, true, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, true, width)
 	default:
 		resultContent = fmt.Sprintf("```text\n%s\n```", resultContent)
-		return styles.ForceReplaceBackgroundWithLipgloss(
-			toMarkdown(resultContent, true, width),
-			t.Background(),
-		)
+		return toMarkdown(resultContent, true, width)
 	}
 }
 

internal/tui/components/chat/sidebar.go 🔗

@@ -6,8 +6,8 @@ import (
 	"sort"
 	"strings"
 
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/diff"
 	"github.com/opencode-ai/opencode/internal/history"
@@ -15,6 +15,7 @@ import (
 	"github.com/opencode-ai/opencode/internal/session"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type sidebarCmp struct {
@@ -235,7 +236,7 @@ func (m *sidebarCmp) GetSize() (int, int) {
 	return m.width, m.height
 }
 
-func NewSidebarCmp(session session.Session, history history.Service) tea.Model {
+func NewSidebarCmp(session session.Session, history history.Service) util.Model {
 	return &sidebarCmp{
 		session: session,
 		history: history,

internal/tui/components/core/status.go 🔗

@@ -5,8 +5,8 @@ import (
 	"strings"
 	"time"
 
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/llm/models"
 	"github.com/opencode-ai/opencode/internal/lsp"
@@ -20,7 +20,7 @@ import (
 )
 
 type StatusCmp interface {
-	tea.Model
+	util.Model
 }
 
 type statusCmp struct {

internal/tui/components/dialog/arguments.go 🔗

@@ -2,10 +2,11 @@ package dialog
 
 import (
 	"fmt"
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/textinput"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/textinput"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
@@ -70,17 +71,18 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
 	for i, name := range argNames {
 		ti := textinput.New()
 		ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
-		ti.Width = 40
+		ti.SetWidth(40)
 		ti.Prompt = ""
-		ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background())
-		ti.PromptStyle = ti.PromptStyle.Background(t.Background())
-		ti.TextStyle = ti.TextStyle.Background(t.Background())
-		
+		ti.Styles.Focused.Placeholder = ti.Styles.Focused.Placeholder.Background(t.Background())
+		ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background())
+		ti.Styles.Focused.Suggestion = ti.Styles.Focused.Suggestion.Background(t.Background()).Foreground(t.Primary())
+		ti.Styles.Blurred.Suggestion = ti.Styles.Blurred.Suggestion.Background(t.Background())
+		ti.Styles.Focused.Text = ti.Styles.Focused.Text.Background(t.Background()).Foreground(t.Primary())
+		ti.Styles.Blurred.Text = ti.Styles.Blurred.Text.Background(t.Background())
+
 		// Only focus the first input initially
 		if i == 0 {
 			ti.Focus()
-			ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
-			ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
 		} else {
 			ti.Blur()
 		}
@@ -89,11 +91,11 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
 	}
 
 	return MultiArgumentsDialogCmp{
-		inputs:    inputs,
-		keys:      argumentsDialogKeyMap{},
-		commandID: commandID,
-		content:   content,
-		argNames:  argNames,
+		inputs:     inputs,
+		keys:       argumentsDialogKeyMap{},
+		commandID:  commandID,
+		content:    content,
+		argNames:   argNames,
 		focusIndex: 0,
 	}
 }
@@ -108,15 +110,13 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
 			m.inputs[i].Blur()
 		}
 	}
-	
+
 	return textinput.Blink
 }
 
 // Update implements tea.Model.
 func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	var cmds []tea.Cmd
-	t := theme.CurrentTheme()
-
 	switch msg := msg.(type) {
 	case tea.KeyMsg:
 		switch {
@@ -145,22 +145,16 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			m.inputs[m.focusIndex].Blur()
 			m.focusIndex++
 			m.inputs[m.focusIndex].Focus()
-			m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
-			m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
 		case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
 			// Move to the next input
 			m.inputs[m.focusIndex].Blur()
 			m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
 			m.inputs[m.focusIndex].Focus()
-			m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
-			m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
 		case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
 			// Move to the previous input
 			m.inputs[m.focusIndex].Blur()
 			m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
 			m.inputs[m.focusIndex].Focus()
-			m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
-			m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
 		}
 	case tea.WindowSizeMsg:
 		m.width = msg.Width
@@ -206,13 +200,13 @@ func (m MultiArgumentsDialogCmp) View() string {
 			Width(maxWidth).
 			Padding(1, 1, 0, 1).
 			Background(t.Background())
-			
+
 		if i == m.focusIndex {
 			labelStyle = labelStyle.Foreground(t.Primary()).Bold(true)
 		} else {
 			labelStyle = labelStyle.Foreground(t.TextMuted())
 		}
-		
+
 		label := labelStyle.Render(m.argNames[i] + ":")
 
 		field := lipgloss.NewStyle().
@@ -254,4 +248,4 @@ func (m *MultiArgumentsDialogCmp) SetSize(width, height int) {
 // Bindings implements layout.Bindings.
 func (m MultiArgumentsDialogCmp) Bindings() []key.Binding {
 	return m.keys.ShortHelp()
-}
+}

internal/tui/components/dialog/commands.go 🔗

@@ -1,9 +1,9 @@
 package dialog
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
@@ -56,7 +56,7 @@ type CloseCommandDialogMsg struct{}
 
 // CommandDialog interface for the command selection dialog
 type CommandDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 	SetCommands(commands []Command)
 }

internal/tui/components/dialog/complete.go 🔗

@@ -1,10 +1,10 @@
 package dialog
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/textarea"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/textarea"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/logging"
 	utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
@@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct {
 type CompletionDialogCloseMsg struct{}
 
 type CompletionDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 	SetWidth(width int)
 }

internal/tui/components/dialog/custom_commands.go 🔗

@@ -7,7 +7,7 @@ import (
 	"regexp"
 	"strings"
 
-	tea "github.com/charmbracelet/bubbletea"
+	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/tui/util"
 )

internal/tui/components/dialog/filepicker.go 🔗

@@ -9,11 +9,11 @@ import (
 	"strings"
 	"time"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/textinput"
-	"github.com/charmbracelet/bubbles/viewport"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/textinput"
+	"github.com/charmbracelet/bubbles/v2/viewport"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/logging"
@@ -122,8 +122,8 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	case tea.WindowSizeMsg:
 		f.width = 60
 		f.height = 20
-		f.viewport.Width = 80
-		f.viewport.Height = 22
+		f.viewport.SetWidth(80)
+		f.viewport.SetHeight(22)
 		f.cursor = 0
 		f.getCurrentFileBelowCursor()
 	case tea.KeyMsg:
@@ -319,7 +319,7 @@ func (f *filepickerCmp) View() string {
 		Render(f.cwd.View())
 
 	viewportstyle := lipgloss.NewStyle().
-		Width(f.viewport.Width).
+		Width(f.viewport.Width()).
 		Background(t.Background()).
 		Border(lipgloss.RoundedBorder()).
 		BorderForeground(t.TextMuted()).
@@ -353,7 +353,7 @@ func (f *filepickerCmp) View() string {
 }
 
 type FilepickerCmp interface {
-	tea.Model
+	util.Model
 	ToggleFilepicker(showFilepicker bool)
 	IsCWDFocused() bool
 }
@@ -374,11 +374,11 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp {
 	}
 	baseDir := DirNode{parent: nil, directory: homepath}
 	dirs := readDir(homepath, false)
-	viewport := viewport.New(0, 0)
+	viewport := viewport.New()
 	currentDirectory := textinput.New()
 	currentDirectory.CharLimit = 200
-	currentDirectory.Width = 44
-	currentDirectory.Cursor.Blink = true
+	currentDirectory.SetWidth(44)
+	currentDirectory.Cursor().Blink = true
 	currentDirectory.SetValue(baseDir.directory)
 	return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
 }
@@ -396,7 +396,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() {
 		fullPath := f.cwdDetails.directory + "/" + dir.Name()
 
 		go func() {
-			imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath)
+			imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath)
 			if err != nil {
 				logging.Error(err.Error())
 				f.viewport.SetContent("Preview unavailable")

internal/tui/components/dialog/help.go 🔗

@@ -3,11 +3,12 @@ package dialog
 import (
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type helpCmp struct {
@@ -134,7 +135,7 @@ func (h *helpCmp) render() string {
 		pairs = append(pairs, pair)
 	}
 
-	// https://github.com/charmbracelet/lipgloss/issues/209
+	// https://github.com/charmbracelet/lipgloss/v2/issues/209
 	if len(pairs) > 1 {
 		prefix := pairs[:len(pairs)-1]
 		lastPair := pairs[len(pairs)-1]
@@ -144,7 +145,7 @@ func (h *helpCmp) render() string {
 			lipgloss.Left,              // x
 			lipgloss.Top,               // y
 			lastPair,                   // content
-			lipgloss.WithWhitespaceBackground(t.Background()),
+			lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
 		))
 		content := baseStyle.Width(h.width).Render(
 			lipgloss.JoinHorizontal(
@@ -191,7 +192,7 @@ func (h *helpCmp) View() string {
 }
 
 type HelpCmp interface {
-	tea.Model
+	util.Model
 	SetBindings([]key.Binding)
 }
 

internal/tui/components/dialog/init.go 🔗

@@ -1,9 +1,9 @@
 package dialog
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"

internal/tui/components/dialog/models.go 🔗

@@ -5,9 +5,9 @@ import (
 	"slices"
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/llm/models"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
@@ -31,7 +31,7 @@ type CloseModelDialogMsg struct{}
 
 // ModelDialog interface for the model selection dialog
 type ModelDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 }
 
@@ -281,7 +281,6 @@ func (m *modelDialogCmp) setupModels() {
 }
 
 func GetSelectedModel(cfg *config.Config) models.Model {
-
 	agentCfg := cfg.Agents[config.AgentCoder]
 	selectedModelId := agentCfg.Model
 	return models.SupportedModels[selectedModelId]

internal/tui/components/dialog/permission.go 🔗

@@ -4,10 +4,10 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/viewport"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/viewport"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/diff"
 	"github.com/opencode-ai/opencode/internal/llm/tools"
 	"github.com/opencode-ai/opencode/internal/permission"
@@ -34,7 +34,7 @@ type PermissionResponseMsg struct {
 
 // PermissionDialogCmp interface for permission dialog component
 type PermissionDialogCmp interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 	SetPermissions(permission permission.PermissionRequest) tea.Cmd
 }
@@ -268,7 +268,6 @@ func (p *permissionDialogCmp) renderHeader() string {
 }
 
 func (p *permissionDialogCmp) renderBashContent() string {
-	t := theme.CurrentTheme()
 	baseStyle := styles.BaseStyle()
 
 	if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
@@ -278,11 +277,11 @@ func (p *permissionDialogCmp) renderBashContent() string {
 		renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
 			r := styles.GetMarkdownRenderer(p.width - 10)
 			s, err := r.Render(content)
-			return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
+			return s, err
 		})
 
 		finalContent := baseStyle.
-			Width(p.contentViewPort.Width).
+			Width(p.contentViewPort.Width()).
 			Render(renderedContent)
 		p.contentViewPort.SetContent(finalContent)
 		return p.styleViewport()
@@ -293,7 +292,7 @@ func (p *permissionDialogCmp) renderBashContent() string {
 func (p *permissionDialogCmp) renderEditContent() string {
 	if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
 		diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
-			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
+			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
 		})
 
 		p.contentViewPort.SetContent(diff)
@@ -305,7 +304,7 @@ func (p *permissionDialogCmp) renderEditContent() string {
 func (p *permissionDialogCmp) renderPatchContent() string {
 	if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
 		diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
-			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
+			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
 		})
 
 		p.contentViewPort.SetContent(diff)
@@ -318,7 +317,7 @@ func (p *permissionDialogCmp) renderWriteContent() string {
 	if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
 		// Use the cache for diff rendering
 		diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
-			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
+			return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
 		})
 
 		p.contentViewPort.SetContent(diff)
@@ -328,7 +327,6 @@ func (p *permissionDialogCmp) renderWriteContent() string {
 }
 
 func (p *permissionDialogCmp) renderFetchContent() string {
-	t := theme.CurrentTheme()
 	baseStyle := styles.BaseStyle()
 
 	if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
@@ -338,11 +336,11 @@ func (p *permissionDialogCmp) renderFetchContent() string {
 		renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
 			r := styles.GetMarkdownRenderer(p.width - 10)
 			s, err := r.Render(content)
-			return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
+			return s, err
 		})
 
 		finalContent := baseStyle.
-			Width(p.contentViewPort.Width).
+			Width(p.contentViewPort.Width()).
 			Render(renderedContent)
 		p.contentViewPort.SetContent(finalContent)
 		return p.styleViewport()
@@ -351,7 +349,6 @@ func (p *permissionDialogCmp) renderFetchContent() string {
 }
 
 func (p *permissionDialogCmp) renderDefaultContent() string {
-	t := theme.CurrentTheme()
 	baseStyle := styles.BaseStyle()
 
 	content := p.permission.Description
@@ -360,11 +357,11 @@ func (p *permissionDialogCmp) renderDefaultContent() string {
 	renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
 		r := styles.GetMarkdownRenderer(p.width - 10)
 		s, err := r.Render(content)
-		return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
+		return s, err
 	})
 
 	finalContent := baseStyle.
-		Width(p.contentViewPort.Width).
+		Width(p.contentViewPort.Width()).
 		Render(renderedContent)
 	p.contentViewPort.SetContent(finalContent)
 
@@ -398,8 +395,8 @@ func (p *permissionDialogCmp) render() string {
 	buttons := p.renderButtons()
 
 	// Calculate content height dynamically based on window size
-	p.contentViewPort.Height = p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title)
-	p.contentViewPort.Width = p.width - 4
+	p.contentViewPort.SetHeight(p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title))
+	p.contentViewPort.SetWidth(p.width - 4)
 
 	// Render content based on tool type
 	var contentFinal string
@@ -511,7 +508,7 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str
 
 func NewPermissionDialogCmp() PermissionDialogCmp {
 	// Create viewport for content
-	contentViewport := viewport.New(0, 0)
+	contentViewport := viewport.New()
 
 	return &permissionDialogCmp{
 		contentViewPort: contentViewport,

internal/tui/components/dialog/quit.go 🔗

@@ -3,9 +3,9 @@ package dialog
 import (
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
@@ -17,7 +17,7 @@ const question = "Are you sure you want to quit?"
 type CloseQuitMsg struct{}
 
 type QuitDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 }
 
@@ -84,7 +84,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 func (q *quitDialogCmp) View() string {
 	t := theme.CurrentTheme()
 	baseStyle := styles.BaseStyle()
-	
+
 	yesStyle := baseStyle
 	noStyle := baseStyle
 	spacerStyle := baseStyle.Background(t.Background())

internal/tui/components/dialog/session.go 🔗

@@ -1,9 +1,9 @@
 package dialog
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/session"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
@@ -21,7 +21,7 @@ type CloseSessionDialogMsg struct{}
 
 // SessionDialog interface for the session switching dialog
 type SessionDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 	SetSessions(sessions []session.Session)
 	SetSelectedSession(sessionID string)
@@ -108,7 +108,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 func (s *sessionDialogCmp) View() string {
 	t := theme.CurrentTheme()
 	baseStyle := styles.BaseStyle()
-	
+
 	if len(s.sessions) == 0 {
 		return baseStyle.Padding(1, 2).
 			Border(lipgloss.RoundedBorder()).
@@ -181,7 +181,6 @@ func (s *sessionDialogCmp) View() string {
 		Border(lipgloss.RoundedBorder()).
 		BorderBackground(t.Background()).
 		BorderForeground(t.TextMuted()).
-		Width(lipgloss.Width(content) + 4).
 		Render(content)
 }
 

internal/tui/components/dialog/theme.go 🔗

@@ -1,9 +1,9 @@
 package dialog
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
@@ -20,7 +20,7 @@ type CloseThemeDialogMsg struct{}
 
 // ThemeDialog interface for the theme switching dialog
 type ThemeDialog interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 }
 
@@ -195,4 +195,3 @@ func NewThemeDialogCmp() ThemeDialog {
 		currentTheme: "",
 	}
 }
-

internal/tui/components/logs/details.go 🔗

@@ -5,18 +5,18 @@ import (
 	"strings"
 	"time"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/viewport"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/viewport"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/logging"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
-	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type DetailComponent interface {
-	tea.Model
+	util.Model
 	layout.Sizeable
 	layout.Bindings
 }
@@ -99,7 +99,7 @@ func (i *detailCmp) updateContent() {
 func getLevelStyle(level string) lipgloss.Style {
 	style := lipgloss.NewStyle().Bold(true)
 	t := theme.CurrentTheme()
-	
+
 	switch strings.ToLower(level) {
 	case "info":
 		return style.Foreground(t.Info())
@@ -115,8 +115,7 @@ func getLevelStyle(level string) lipgloss.Style {
 }
 
 func (i *detailCmp) View() string {
-	t := theme.CurrentTheme()
-	return styles.ForceReplaceBackgroundWithLipgloss(i.viewport.View(), t.Background())
+	return i.viewport.View()
 }
 
 func (i *detailCmp) GetSize() (int, int) {
@@ -126,8 +125,8 @@ func (i *detailCmp) GetSize() (int, int) {
 func (i *detailCmp) SetSize(width int, height int) tea.Cmd {
 	i.width = width
 	i.height = height
-	i.viewport.Width = i.width
-	i.viewport.Height = i.height
+	i.viewport.SetWidth(i.width)
+	i.viewport.SetHeight(i.height)
 	i.updateContent()
 	return nil
 }
@@ -138,6 +137,6 @@ func (i *detailCmp) BindingKeys() []key.Binding {
 
 func NewLogsDetails() DetailComponent {
 	return &detailCmp{
-		viewport: viewport.New(0, 0),
+		viewport: viewport.New(),
 	}
 }

internal/tui/components/logs/table.go 🔗

@@ -4,19 +4,18 @@ import (
 	"encoding/json"
 	"slices"
 
-	"github.com/charmbracelet/bubbles/key"
-	"github.com/charmbracelet/bubbles/table"
-	tea "github.com/charmbracelet/bubbletea"
+	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/table"
+	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/opencode-ai/opencode/internal/logging"
 	"github.com/opencode-ai/opencode/internal/pubsub"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
-	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
 	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type TableComponent interface {
-	tea.Model
+	util.Model
 	layout.Sizeable
 	layout.Bindings
 }
@@ -66,7 +65,7 @@ func (i *tableCmp) View() string {
 	defaultStyles := table.DefaultStyles()
 	defaultStyles.Selected = defaultStyles.Selected.Foreground(t.Primary())
 	i.table.SetStyles(defaultStyles)
-	return styles.ForceReplaceBackgroundWithLipgloss(i.table.View(), t.Background())
+	return i.table.View()
 }
 
 func (i *tableCmp) GetSize() (int, int) {

internal/tui/components/util/simple-list.go 🔗

@@ -1,12 +1,13 @@
 package utilComponents
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type SimpleListItem interface {
@@ -14,7 +15,7 @@ type SimpleListItem interface {
 }
 
 type SimpleList[T SimpleListItem] interface {
-	tea.Model
+	util.Model
 	layout.Bindings
 	SetMaxWidth(maxWidth int)
 	GetSelectedItem() (item T, idx int)

internal/tui/image/images.go 🔗

@@ -3,10 +3,11 @@ package image
 import (
 	"fmt"
 	"image"
+	"image/color"
 	"os"
 	"strings"
 
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/disintegration/imaging"
 	"github.com/lucasb-eyer/go-colorful"
 )
@@ -36,7 +37,7 @@ func ToString(width int, img image.Image) string {
 			c1, _ := colorful.MakeColor(img.At(x, heightCounter))
 			color1 := lipgloss.Color(c1.Hex())
 
-			var color2 lipgloss.Color
+			var color2 color.Color
 			if heightCounter+1 < h {
 				c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
 				color2 = lipgloss.Color(c2.Hex())

internal/tui/layout/container.go 🔗

@@ -1,14 +1,15 @@
 package layout
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type Container interface {
-	tea.Model
+	util.Model
 	Sizeable
 	Bindings
 }
@@ -16,7 +17,7 @@ type container struct {
 	width  int
 	height int
 
-	content tea.Model
+	content util.Model
 
 	// Style options
 	paddingTop    int
@@ -37,7 +38,7 @@ func (c *container) Init() tea.Cmd {
 
 func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	u, cmd := c.content.Update(msg)
-	c.content = u
+	c.content = u.(util.Model)
 	return c, cmd
 }
 
@@ -123,8 +124,7 @@ func (c *container) BindingKeys() []key.Binding {
 
 type ContainerOption func(*container)
 
-func NewContainer(content tea.Model, options ...ContainerOption) Container {
-
+func NewContainer(content util.Model, options ...ContainerOption) Container {
 	c := &container{
 		content:     content,
 		borderStyle: lipgloss.NormalBorder(),

internal/tui/layout/layout.go 🔗

@@ -3,8 +3,8 @@ package layout
 import (
 	"reflect"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
 )
 
 type Focusable interface {

internal/tui/layout/overlay.go 🔗

@@ -3,7 +3,7 @@ package layout
 import (
 	"strings"
 
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 	chAnsi "github.com/charmbracelet/x/ansi"
 	"github.com/muesli/ansi"
 	"github.com/muesli/reflow/truncate"
@@ -14,7 +14,7 @@ import (
 )
 
 // Most of this code is borrowed from
-// https://github.com/charmbracelet/lipgloss/pull/102
+// https://github.com/charmbracelet/lipgloss/v2/pull/102
 // as well as the lipgloss library, with some modification for what I needed.
 
 // Split a string into lines, additionally returning the size of the widest

internal/tui/layout/split.go 🔗

@@ -1,14 +1,15 @@
 package layout
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 type SplitPaneLayout interface {
-	tea.Model
+	util.Model
 	Sizeable
 	Bindings
 	SetLeftPanel(panel Container) tea.Cmd
@@ -241,7 +242,6 @@ func (s *splitPaneLayout) BindingKeys() []key.Binding {
 }
 
 func NewSplitPane(options ...SplitPaneOption) SplitPaneLayout {
-
 	layout := &splitPaneLayout{
 		ratio:         0.7,
 		verticalRatio: 0.9, // Default 90% for top section, 10% for bottom

internal/tui/page/chat.go 🔗

@@ -4,9 +4,9 @@ import (
 	"context"
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/completions"
 	"github.com/opencode-ai/opencode/internal/message"
@@ -76,7 +76,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		if p.app.CoderAgent.IsBusy() {
 			return p, util.ReportWarn("Agent is busy, please wait before executing a command...")
 		}
-		
+
 		// Process the command content with arguments if any
 		content := msg.Content
 		if msg.Args != nil {
@@ -86,7 +86,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 				content = strings.ReplaceAll(content, placeholder, value)
 			}
 		}
-		
+
 		// Handle custom command execution
 		cmd := p.sendMessage(content, nil)
 		if cmd != nil {
@@ -212,7 +212,7 @@ func (p *chatPage) BindingKeys() []key.Binding {
 	return bindings
 }
 
-func NewChatPage(app *app.App) tea.Model {
+func NewChatPage(app *app.App) util.Model {
 	cg := completions.NewFileAndFolderContextGroup()
 	completionDialog := dialog.NewCompletionDialogCmp(cg)
 

internal/tui/page/logs.go 🔗

@@ -1,18 +1,19 @@
 package page
 
 import (
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/components/logs"
 	"github.com/opencode-ai/opencode/internal/tui/layout"
 	"github.com/opencode-ai/opencode/internal/tui/styles"
+	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
 var LogsPage PageID = "logs"
 
 type LogPage interface {
-	tea.Model
+	util.Model
 	layout.Sizeable
 	layout.Bindings
 }

internal/tui/styles/background.go 🔗

@@ -1,123 +0,0 @@
-package styles
-
-import (
-	"fmt"
-	"regexp"
-	"strings"
-
-	"github.com/charmbracelet/lipgloss"
-)
-
-var ansiEscape = regexp.MustCompile("\x1b\\[[0-9;]*m")
-
-func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
-	r, g, b, a := c.RGBA()
-
-	// Un-premultiply alpha if needed
-	if a > 0 && a < 0xffff {
-		r = (r * 0xffff) / a
-		g = (g * 0xffff) / a
-		b = (b * 0xffff) / a
-	}
-
-	// Convert from 16-bit to 8-bit color
-	return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
-}
-
-// ForceReplaceBackgroundWithLipgloss replaces any ANSI background color codes
-// in `input` with a single 24‑bit background (48;2;R;G;B).
-func ForceReplaceBackgroundWithLipgloss(input string, newBgColor lipgloss.TerminalColor) string {
-	// Precompute our new-bg sequence once
-	r, g, b := getColorRGB(newBgColor)
-	newBg := fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
-
-	return ansiEscape.ReplaceAllStringFunc(input, func(seq string) string {
-		const (
-			escPrefixLen = 2 // "\x1b["
-			escSuffixLen = 1 // "m"
-		)
-
-		raw := seq
-		start := escPrefixLen
-		end := len(raw) - escSuffixLen
-
-		var sb strings.Builder
-		// reserve enough space: original content minus bg codes + our newBg
-		sb.Grow((end - start) + len(newBg) + 2)
-
-		// scan from start..end, token by token
-		for i := start; i < end; {
-			// find the next ';' or end
-			j := i
-			for j < end && raw[j] != ';' {
-				j++
-			}
-			token := raw[i:j]
-
-			// fast‑path: skip "48;5;N" or "48;2;R;G;B"
-			if len(token) == 2 && token[0] == '4' && token[1] == '8' {
-				k := j + 1
-				if k < end {
-					// find next token
-					l := k
-					for l < end && raw[l] != ';' {
-						l++
-					}
-					next := raw[k:l]
-					if next == "5" {
-						// skip "48;5;N"
-						m := l + 1
-						for m < end && raw[m] != ';' {
-							m++
-						}
-						i = m + 1
-						continue
-					} else if next == "2" {
-						// skip "48;2;R;G;B"
-						m := l + 1
-						for count := 0; count < 3 && m < end; count++ {
-							for m < end && raw[m] != ';' {
-								m++
-							}
-							m++
-						}
-						i = m
-						continue
-					}
-				}
-			}
-
-			// decide whether to keep this token
-			// manually parse ASCII digits to int
-			isNum := true
-			val := 0
-			for p := i; p < j; p++ {
-				c := raw[p]
-				if c < '0' || c > '9' {
-					isNum = false
-					break
-				}
-				val = val*10 + int(c-'0')
-			}
-			keep := !isNum ||
-				((val < 40 || val > 47) && (val < 100 || val > 107) && val != 49)
-
-			if keep {
-				if sb.Len() > 0 {
-					sb.WriteByte(';')
-				}
-				sb.WriteString(token)
-			}
-			// advance past this token (and the semicolon)
-			i = j + 1
-		}
-
-		// append our new background
-		if sb.Len() > 0 {
-			sb.WriteByte(';')
-		}
-		sb.WriteString(newBg)
-
-		return "\x1b[" + sb.String() + "m"
-	})
-}

internal/tui/styles/markdown.go 🔗

@@ -1,9 +1,11 @@
 package styles
 
 import (
-	"github.com/charmbracelet/glamour"
-	"github.com/charmbracelet/glamour/ansi"
-	"github.com/charmbracelet/lipgloss"
+	"fmt"
+	"image/color"
+
+	"github.com/charmbracelet/glamour/v2"
+	"github.com/charmbracelet/glamour/v2/ansi"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
 )
 
@@ -33,13 +35,13 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
 			StylePrimitive: ansi.StylePrimitive{
 				BlockPrefix: "",
 				BlockSuffix: "",
-				Color:       stringPtr(adaptiveColorToString(t.MarkdownText())),
+				Color:       stringPtr(colorToString(t.MarkdownText())),
 			},
 			Margin: uintPtr(defaultMargin),
 		},
 		BlockQuote: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
+				Color:  stringPtr(colorToString(t.MarkdownBlockQuote())),
 				Italic: boolPtr(true),
 				Prefix: "┃ ",
 			},
@@ -51,82 +53,82 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
 			StyleBlock: ansi.StyleBlock{
 				IndentToken: stringPtr(BaseStyle().Render(" ")),
 				StylePrimitive: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+					Color: stringPtr(colorToString(t.MarkdownText())),
 				},
 			},
 		},
 		Heading: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				BlockSuffix: "\n",
-				Color:       stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:       stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:        boolPtr(true),
 			},
 		},
 		H1: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "# ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		H2: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "## ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		H3: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "### ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		H4: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "#### ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		H5: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "##### ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		H6: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
 				Prefix: "###### ",
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+				Color:  stringPtr(colorToString(t.MarkdownHeading())),
 				Bold:   boolPtr(true),
 			},
 		},
 		Strikethrough: ansi.StylePrimitive{
 			CrossedOut: boolPtr(true),
-			Color:      stringPtr(adaptiveColorToString(t.TextMuted())),
+			Color:      stringPtr(colorToString(t.TextMuted())),
 		},
 		Emph: ansi.StylePrimitive{
-			Color:  stringPtr(adaptiveColorToString(t.MarkdownEmph())),
+			Color:  stringPtr(colorToString(t.MarkdownEmph())),
 			Italic: boolPtr(true),
 		},
 		Strong: ansi.StylePrimitive{
 			Bold:  boolPtr(true),
-			Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
+			Color: stringPtr(colorToString(t.MarkdownStrong())),
 		},
 		HorizontalRule: ansi.StylePrimitive{
-			Color:  stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
+			Color:  stringPtr(colorToString(t.MarkdownHorizontalRule())),
 			Format: "\n─────────────────────────────────────────\n",
 		},
 		Item: ansi.StylePrimitive{
 			BlockPrefix: "• ",
-			Color:       stringPtr(adaptiveColorToString(t.MarkdownListItem())),
+			Color:       stringPtr(colorToString(t.MarkdownListItem())),
 		},
 		Enumeration: ansi.StylePrimitive{
 			BlockPrefix: ". ",
-			Color:       stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
+			Color:       stringPtr(colorToString(t.MarkdownListEnumeration())),
 		},
 		Task: ansi.StyleTask{
 			StylePrimitive: ansi.StylePrimitive{},
@@ -134,25 +136,25 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
 			Unticked:       "[ ] ",
 		},
 		Link: ansi.StylePrimitive{
-			Color:     stringPtr(adaptiveColorToString(t.MarkdownLink())),
+			Color:     stringPtr(colorToString(t.MarkdownLink())),
 			Underline: boolPtr(true),
 		},
 		LinkText: ansi.StylePrimitive{
-			Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
+			Color: stringPtr(colorToString(t.MarkdownLinkText())),
 			Bold:  boolPtr(true),
 		},
 		Image: ansi.StylePrimitive{
-			Color:     stringPtr(adaptiveColorToString(t.MarkdownImage())),
+			Color:     stringPtr(colorToString(t.MarkdownImage())),
 			Underline: boolPtr(true),
 			Format:    "🖼 {{.text}}",
 		},
 		ImageText: ansi.StylePrimitive{
-			Color:  stringPtr(adaptiveColorToString(t.MarkdownImageText())),
+			Color:  stringPtr(colorToString(t.MarkdownImageText())),
 			Format: "{{.text}}",
 		},
 		Code: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
-				Color:  stringPtr(adaptiveColorToString(t.MarkdownCode())),
+				Color:  stringPtr(colorToString(t.MarkdownCode())),
 				Prefix: "",
 				Suffix: "",
 			},
@@ -161,90 +163,90 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
 			StyleBlock: ansi.StyleBlock{
 				StylePrimitive: ansi.StylePrimitive{
 					Prefix: " ",
-					Color:  stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
+					Color:  stringPtr(colorToString(t.MarkdownCodeBlock())),
 				},
 				Margin: uintPtr(defaultMargin),
 			},
 			Chroma: &ansi.Chroma{
 				Text: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+					Color: stringPtr(colorToString(t.MarkdownText())),
 				},
 				Error: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.Error())),
+					Color: stringPtr(colorToString(t.Error())),
 				},
 				Comment: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
+					Color: stringPtr(colorToString(t.SyntaxComment())),
 				},
 				CommentPreproc: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				Keyword: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				KeywordReserved: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				KeywordNamespace: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				KeywordType: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
+					Color: stringPtr(colorToString(t.SyntaxType())),
 				},
 				Operator: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
+					Color: stringPtr(colorToString(t.SyntaxOperator())),
 				},
 				Punctuation: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
+					Color: stringPtr(colorToString(t.SyntaxPunctuation())),
 				},
 				Name: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+					Color: stringPtr(colorToString(t.SyntaxVariable())),
 				},
 				NameBuiltin: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+					Color: stringPtr(colorToString(t.SyntaxVariable())),
 				},
 				NameTag: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				NameAttribute: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+					Color: stringPtr(colorToString(t.SyntaxFunction())),
 				},
 				NameClass: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
+					Color: stringPtr(colorToString(t.SyntaxType())),
 				},
 				NameConstant: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+					Color: stringPtr(colorToString(t.SyntaxVariable())),
 				},
 				NameDecorator: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+					Color: stringPtr(colorToString(t.SyntaxFunction())),
 				},
 				NameFunction: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+					Color: stringPtr(colorToString(t.SyntaxFunction())),
 				},
 				LiteralNumber: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
+					Color: stringPtr(colorToString(t.SyntaxNumber())),
 				},
 				LiteralString: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
+					Color: stringPtr(colorToString(t.SyntaxString())),
 				},
 				LiteralStringEscape: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+					Color: stringPtr(colorToString(t.SyntaxKeyword())),
 				},
 				GenericDeleted: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
+					Color: stringPtr(colorToString(t.DiffRemoved())),
 				},
 				GenericEmph: ansi.StylePrimitive{
-					Color:  stringPtr(adaptiveColorToString(t.MarkdownEmph())),
+					Color:  stringPtr(colorToString(t.MarkdownEmph())),
 					Italic: boolPtr(true),
 				},
 				GenericInserted: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
+					Color: stringPtr(colorToString(t.DiffAdded())),
 				},
 				GenericStrong: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
+					Color: stringPtr(colorToString(t.MarkdownStrong())),
 					Bold:  boolPtr(true),
 				},
 				GenericSubheading: ansi.StylePrimitive{
-					Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+					Color: stringPtr(colorToString(t.MarkdownHeading())),
 				},
 			},
 		},
@@ -261,24 +263,20 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
 		},
 		DefinitionDescription: ansi.StylePrimitive{
 			BlockPrefix: "\n ❯ ",
-			Color:       stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
+			Color:       stringPtr(colorToString(t.MarkdownLinkText())),
 		},
 		Text: ansi.StylePrimitive{
-			Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+			Color: stringPtr(colorToString(t.MarkdownText())),
 		},
 		Paragraph: ansi.StyleBlock{
 			StylePrimitive: ansi.StylePrimitive{
-				Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+				Color: stringPtr(colorToString(t.MarkdownText())),
 			},
 		},
 	}
 }
 
-// adaptiveColorToString converts a lipgloss.AdaptiveColor to the appropriate
-// hex color string based on the current terminal background
-func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
-	if lipgloss.HasDarkBackground() {
-		return color.Dark
-	}
-	return color.Light
+func colorToString(c color.Color) string {
+	rgba := color.RGBAModel.Convert(c).(color.RGBA)
+	return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
 }

internal/tui/styles/styles.go 🔗

@@ -1,13 +1,13 @@
 package styles
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"image/color"
+
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/tui/theme"
 )
 
-var (
-	ImageBakcground = "#212121"
-)
+var ImageBakcground = "#212121"
 
 // Style generation functions that use the current theme
 
@@ -75,81 +75,81 @@ func DimBorder() lipgloss.Style {
 }
 
 // PrimaryColor returns the primary color from the current theme
-func PrimaryColor() lipgloss.AdaptiveColor {
+func PrimaryColor() color.Color {
 	return theme.CurrentTheme().Primary()
 }
 
 // SecondaryColor returns the secondary color from the current theme
-func SecondaryColor() lipgloss.AdaptiveColor {
+func SecondaryColor() color.Color {
 	return theme.CurrentTheme().Secondary()
 }
 
 // AccentColor returns the accent color from the current theme
-func AccentColor() lipgloss.AdaptiveColor {
+func AccentColor() color.Color {
 	return theme.CurrentTheme().Accent()
 }
 
 // ErrorColor returns the error color from the current theme
-func ErrorColor() lipgloss.AdaptiveColor {
+func ErrorColor() color.Color {
 	return theme.CurrentTheme().Error()
 }
 
 // WarningColor returns the warning color from the current theme
-func WarningColor() lipgloss.AdaptiveColor {
+func WarningColor() color.Color {
 	return theme.CurrentTheme().Warning()
 }
 
 // SuccessColor returns the success color from the current theme
-func SuccessColor() lipgloss.AdaptiveColor {
+func SuccessColor() color.Color {
 	return theme.CurrentTheme().Success()
 }
 
 // InfoColor returns the info color from the current theme
-func InfoColor() lipgloss.AdaptiveColor {
+func InfoColor() color.Color {
 	return theme.CurrentTheme().Info()
 }
 
 // TextColor returns the text color from the current theme
-func TextColor() lipgloss.AdaptiveColor {
+func TextColor() color.Color {
 	return theme.CurrentTheme().Text()
 }
 
 // TextMutedColor returns the muted text color from the current theme
-func TextMutedColor() lipgloss.AdaptiveColor {
+func TextMutedColor() color.Color {
 	return theme.CurrentTheme().TextMuted()
 }
 
 // TextEmphasizedColor returns the emphasized text color from the current theme
-func TextEmphasizedColor() lipgloss.AdaptiveColor {
+func TextEmphasizedColor() color.Color {
 	return theme.CurrentTheme().TextEmphasized()
 }
 
 // BackgroundColor returns the background color from the current theme
-func BackgroundColor() lipgloss.AdaptiveColor {
+func BackgroundColor() color.Color {
 	return theme.CurrentTheme().Background()
 }
 
 // BackgroundSecondaryColor returns the secondary background color from the current theme
-func BackgroundSecondaryColor() lipgloss.AdaptiveColor {
+func BackgroundSecondaryColor() color.Color {
 	return theme.CurrentTheme().BackgroundSecondary()
 }
 
 // BackgroundDarkerColor returns the darker background color from the current theme
-func BackgroundDarkerColor() lipgloss.AdaptiveColor {
+func BackgroundDarkerColor() color.Color {
 	return theme.CurrentTheme().BackgroundDarker()
 }
 
 // BorderNormalColor returns the normal border color from the current theme
-func BorderNormalColor() lipgloss.AdaptiveColor {
+func BorderNormalColor() color.Color {
 	return theme.CurrentTheme().BorderNormal()
 }
 
 // BorderFocusedColor returns the focused border color from the current theme
-func BorderFocusedColor() lipgloss.AdaptiveColor {
+func BorderFocusedColor() color.Color {
 	return theme.CurrentTheme().BorderFocused()
 }
 
 // BorderDimColor returns the dim border color from the current theme
-func BorderDimColor() lipgloss.AdaptiveColor {
+func BorderDimColor() color.Color {
 	return theme.CurrentTheme().BorderDim()
 }

internal/tui/theme/catppuccin.go 🔗

@@ -2,7 +2,7 @@ package theme
 
 import (
 	catppuccin "github.com/catppuccin/go"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // CatppuccinTheme implements the Theme interface with Catppuccin colors.
@@ -11,238 +11,162 @@ type CatppuccinTheme struct {
 	BaseTheme
 }
 
-// NewCatppuccinTheme creates a new instance of the Catppuccin theme.
-func NewCatppuccinTheme() *CatppuccinTheme {
-	// Get the Catppuccin palettes
+// NewCatppuccinMochaTheme creates a new instance of the Catppuccin Mocha theme.
+func NewCatppuccinMochaTheme() *CatppuccinTheme {
+	// Get the Catppuccin palette
 	mocha := catppuccin.Mocha
+
+	theme := &CatppuccinTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(mocha.Blue().Hex)
+	theme.SecondaryColor = lipgloss.Color(mocha.Mauve().Hex)
+	theme.AccentColor = lipgloss.Color(mocha.Peach().Hex)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(mocha.Red().Hex)
+	theme.WarningColor = lipgloss.Color(mocha.Peach().Hex)
+	theme.SuccessColor = lipgloss.Color(mocha.Green().Hex)
+	theme.InfoColor = lipgloss.Color(mocha.Blue().Hex)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(mocha.Text().Hex)
+	theme.TextMutedColor = lipgloss.Color(mocha.Subtext0().Hex)
+	theme.TextEmphasizedColor = lipgloss.Color(mocha.Lavender().Hex)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color("#212121")          // From existing styles
+	theme.BackgroundSecondaryColor = lipgloss.Color("#2c2c2c") // From existing styles
+	theme.BackgroundDarkerColor = lipgloss.Color("#181818")    // From existing styles
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color("#4b4c5c") // From existing styles
+	theme.BorderFocusedColor = lipgloss.Color(mocha.Blue().Hex)
+	theme.BorderDimColor = lipgloss.Color(mocha.Surface0().Hex)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color("#478247")               // From existing diff.go
+	theme.DiffRemovedColor = lipgloss.Color("#7C4444")             // From existing diff.go
+	theme.DiffContextColor = lipgloss.Color("#a0a0a0")             // From existing diff.go
+	theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")          // From existing diff.go
+	theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA")      // From existing diff.go
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD")    // From existing diff.go
+	theme.DiffAddedBgColor = lipgloss.Color("#303A30")             // From existing diff.go
+	theme.DiffRemovedBgColor = lipgloss.Color("#3A3030")           // From existing diff.go
+	theme.DiffContextBgColor = lipgloss.Color("#212121")           // From existing diff.go
+	theme.DiffLineNumberColor = lipgloss.Color("#888888")          // From existing diff.go
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229")   // From existing diff.go
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929") // From existing diff.go
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(mocha.Text().Hex)
+	theme.MarkdownHeadingColor = lipgloss.Color(mocha.Mauve().Hex)
+	theme.MarkdownLinkColor = lipgloss.Color(mocha.Sky().Hex)
+	theme.MarkdownLinkTextColor = lipgloss.Color(mocha.Pink().Hex)
+	theme.MarkdownCodeColor = lipgloss.Color(mocha.Green().Hex)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(mocha.Yellow().Hex)
+	theme.MarkdownEmphColor = lipgloss.Color(mocha.Yellow().Hex)
+	theme.MarkdownStrongColor = lipgloss.Color(mocha.Peach().Hex)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(mocha.Overlay0().Hex)
+	theme.MarkdownListItemColor = lipgloss.Color(mocha.Blue().Hex)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(mocha.Sky().Hex)
+	theme.MarkdownImageColor = lipgloss.Color(mocha.Sapphire().Hex)
+	theme.MarkdownImageTextColor = lipgloss.Color(mocha.Pink().Hex)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(mocha.Text().Hex)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(mocha.Overlay1().Hex)
+	theme.SyntaxKeywordColor = lipgloss.Color(mocha.Pink().Hex)
+	theme.SyntaxFunctionColor = lipgloss.Color(mocha.Green().Hex)
+	theme.SyntaxVariableColor = lipgloss.Color(mocha.Sky().Hex)
+	theme.SyntaxStringColor = lipgloss.Color(mocha.Yellow().Hex)
+	theme.SyntaxNumberColor = lipgloss.Color(mocha.Teal().Hex)
+	theme.SyntaxTypeColor = lipgloss.Color(mocha.Sky().Hex)
+	theme.SyntaxOperatorColor = lipgloss.Color(mocha.Pink().Hex)
+	theme.SyntaxPunctuationColor = lipgloss.Color(mocha.Text().Hex)
+
+	return theme
+}
+
+// NewCatppuccinLatteTheme creates a new instance of the Catppuccin Latte theme.
+func NewCatppuccinLatteTheme() *CatppuccinTheme {
+	// Get the Catppuccin palette
 	latte := catppuccin.Latte
 
 	theme := &CatppuccinTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Blue().Hex,
-		Light: latte.Blue().Hex,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Mauve().Hex,
-		Light: latte.Mauve().Hex,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Peach().Hex,
-		Light: latte.Peach().Hex,
-	}
+	theme.PrimaryColor = lipgloss.Color(latte.Blue().Hex)
+	theme.SecondaryColor = lipgloss.Color(latte.Mauve().Hex)
+	theme.AccentColor = lipgloss.Color(latte.Peach().Hex)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Red().Hex,
-		Light: latte.Red().Hex,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Peach().Hex,
-		Light: latte.Peach().Hex,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Green().Hex,
-		Light: latte.Green().Hex,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Blue().Hex,
-		Light: latte.Blue().Hex,
-	}
+	theme.ErrorColor = lipgloss.Color(latte.Red().Hex)
+	theme.WarningColor = lipgloss.Color(latte.Peach().Hex)
+	theme.SuccessColor = lipgloss.Color(latte.Green().Hex)
+	theme.InfoColor = lipgloss.Color(latte.Blue().Hex)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Text().Hex,
-		Light: latte.Text().Hex,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Subtext0().Hex,
-		Light: latte.Subtext0().Hex,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Lavender().Hex,
-		Light: latte.Lavender().Hex,
-	}
+	theme.TextColor = lipgloss.Color(latte.Text().Hex)
+	theme.TextMutedColor = lipgloss.Color(latte.Subtext0().Hex)
+	theme.TextEmphasizedColor = lipgloss.Color(latte.Lavender().Hex)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  "#212121", // From existing styles
-		Light: "#EEEEEE", // Light equivalent
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  "#2c2c2c", // From existing styles
-		Light: "#E0E0E0", // Light equivalent
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#181818", // From existing styles
-		Light: "#F5F5F5", // Light equivalent
-	}
+	theme.BackgroundColor = lipgloss.Color("#EEEEEE")          // Light equivalent
+	theme.BackgroundSecondaryColor = lipgloss.Color("#E0E0E0") // Light equivalent
+	theme.BackgroundDarkerColor = lipgloss.Color("#F5F5F5")    // Light equivalent
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  "#4b4c5c", // From existing styles
-		Light: "#BDBDBD", // Light equivalent
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Blue().Hex,
-		Light: latte.Blue().Hex,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Surface0().Hex,
-		Light: latte.Surface0().Hex,
-	}
+	theme.BorderNormalColor = lipgloss.Color("#BDBDBD") // Light equivalent
+	theme.BorderFocusedColor = lipgloss.Color(latte.Blue().Hex)
+	theme.BorderDimColor = lipgloss.Color(latte.Surface0().Hex)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#478247", // From existing diff.go
-		Light: "#2E7D32", // Light equivalent
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#7C4444", // From existing diff.go
-		Light: "#C62828", // Light equivalent
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0", // From existing diff.go
-		Light: "#757575", // Light equivalent
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0", // From existing diff.go
-		Light: "#757575", // Light equivalent
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#DAFADA", // From existing diff.go
-		Light: "#A5D6A7", // Light equivalent
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#FADADD", // From existing diff.go
-		Light: "#EF9A9A", // Light equivalent
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#303A30", // From existing diff.go
-		Light: "#E8F5E9", // Light equivalent
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3A3030", // From existing diff.go
-		Light: "#FFEBEE", // Light equivalent
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#212121", // From existing diff.go
-		Light: "#F5F5F5", // Light equivalent
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  "#888888", // From existing diff.go
-		Light: "#9E9E9E", // Light equivalent
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#293229", // From existing diff.go
-		Light: "#C8E6C9", // Light equivalent
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#332929", // From existing diff.go
-		Light: "#FFCDD2", // Light equivalent
-	}
+	theme.DiffAddedColor = lipgloss.Color("#2E7D32")               // Light equivalent
+	theme.DiffRemovedColor = lipgloss.Color("#C62828")             // Light equivalent
+	theme.DiffContextColor = lipgloss.Color("#757575")             // Light equivalent
+	theme.DiffHunkHeaderColor = lipgloss.Color("#757575")          // Light equivalent
+	theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")      // Light equivalent
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")    // Light equivalent
+	theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")             // Light equivalent
+	theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")           // Light equivalent
+	theme.DiffContextBgColor = lipgloss.Color("#F5F5F5")           // Light equivalent
+	theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")          // Light equivalent
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")   // Light equivalent
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2") // Light equivalent
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Text().Hex,
-		Light: latte.Text().Hex,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Mauve().Hex,
-		Light: latte.Mauve().Hex,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Sky().Hex,
-		Light: latte.Sky().Hex,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Pink().Hex,
-		Light: latte.Pink().Hex,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Green().Hex,
-		Light: latte.Green().Hex,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Yellow().Hex,
-		Light: latte.Yellow().Hex,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Yellow().Hex,
-		Light: latte.Yellow().Hex,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Peach().Hex,
-		Light: latte.Peach().Hex,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Overlay0().Hex,
-		Light: latte.Overlay0().Hex,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Blue().Hex,
-		Light: latte.Blue().Hex,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Sky().Hex,
-		Light: latte.Sky().Hex,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Sapphire().Hex,
-		Light: latte.Sapphire().Hex,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Pink().Hex,
-		Light: latte.Pink().Hex,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Text().Hex,
-		Light: latte.Text().Hex,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(latte.Text().Hex)
+	theme.MarkdownHeadingColor = lipgloss.Color(latte.Mauve().Hex)
+	theme.MarkdownLinkColor = lipgloss.Color(latte.Sky().Hex)
+	theme.MarkdownLinkTextColor = lipgloss.Color(latte.Pink().Hex)
+	theme.MarkdownCodeColor = lipgloss.Color(latte.Green().Hex)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(latte.Yellow().Hex)
+	theme.MarkdownEmphColor = lipgloss.Color(latte.Yellow().Hex)
+	theme.MarkdownStrongColor = lipgloss.Color(latte.Peach().Hex)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(latte.Overlay0().Hex)
+	theme.MarkdownListItemColor = lipgloss.Color(latte.Blue().Hex)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(latte.Sky().Hex)
+	theme.MarkdownImageColor = lipgloss.Color(latte.Sapphire().Hex)
+	theme.MarkdownImageTextColor = lipgloss.Color(latte.Pink().Hex)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(latte.Text().Hex)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Overlay1().Hex,
-		Light: latte.Overlay1().Hex,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Pink().Hex,
-		Light: latte.Pink().Hex,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Green().Hex,
-		Light: latte.Green().Hex,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Sky().Hex,
-		Light: latte.Sky().Hex,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Yellow().Hex,
-		Light: latte.Yellow().Hex,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Teal().Hex,
-		Light: latte.Teal().Hex,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Sky().Hex,
-		Light: latte.Sky().Hex,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Pink().Hex,
-		Light: latte.Pink().Hex,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  mocha.Text().Hex,
-		Light: latte.Text().Hex,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(latte.Overlay1().Hex)
+	theme.SyntaxKeywordColor = lipgloss.Color(latte.Pink().Hex)
+	theme.SyntaxFunctionColor = lipgloss.Color(latte.Green().Hex)
+	theme.SyntaxVariableColor = lipgloss.Color(latte.Sky().Hex)
+	theme.SyntaxStringColor = lipgloss.Color(latte.Yellow().Hex)
+	theme.SyntaxNumberColor = lipgloss.Color(latte.Teal().Hex)
+	theme.SyntaxTypeColor = lipgloss.Color(latte.Sky().Hex)
+	theme.SyntaxOperatorColor = lipgloss.Color(latte.Pink().Hex)
+	theme.SyntaxPunctuationColor = lipgloss.Color(latte.Text().Hex)
 
 	return theme
 }
 
 func init() {
-	// Register the Catppuccin theme with the theme manager
-	RegisterTheme("catppuccin", NewCatppuccinTheme())
-}
+	// Register the Catppuccin themes with the theme manager
+	RegisterTheme("catppuccin-mocha", NewCatppuccinMochaTheme())
+	RegisterTheme("catppuccin-latte", NewCatppuccinLatteTheme())
+}

internal/tui/theme/dracula.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // DraculaTheme implements the Theme interface with Dracula colors.
@@ -28,242 +28,74 @@ func NewDraculaTheme() *DraculaTheme {
 	darkYellow := "#f1fa8c"
 	darkBorder := "#44475a"
 
-	// Light mode approximation (Dracula is primarily a dark theme)
-	lightBackground := "#f8f8f2"
-	lightCurrentLine := "#e6e6e6"
-	lightSelection := "#d8d8d8"
-	lightForeground := "#282a36"
-	lightComment := "#6272a4"
-	lightCyan := "#0097a7"
-	lightGreen := "#388e3c"
-	lightOrange := "#f57c00"
-	lightPink := "#d81b60"
-	lightPurple := "#7e57c2"
-	lightRed := "#e53935"
-	lightYellow := "#fbc02d"
-	lightBorder := "#d8d8d8"
-
 	theme := &DraculaTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPink,
-		Light: lightPink,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
+	theme.PrimaryColor = lipgloss.Color(darkPurple)
+	theme.SecondaryColor = lipgloss.Color(darkPink)
+	theme.AccentColor = lipgloss.Color(darkCyan)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkCyan)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#21222c", // Slightly darker than background
-		Light: "#ffffff", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#21222c") // Slightly darker than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkPurple)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#50fa7b",
-		Light: "#a5d6a7",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#ff5555",
-		Light: "#ef9a9a",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#2c3b2c",
-		Light: "#e8f5e9",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3b2c2c",
-		Light: "#ffebee",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#253025",
-		Light: "#c8e6c9",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#302525",
-		Light: "#ffcdd2",
-	}
+	theme.DiffAddedColor = lipgloss.Color(darkGreen)
+	theme.DiffRemovedColor = lipgloss.Color(darkRed)
+	theme.DiffContextColor = lipgloss.Color(darkComment)
+	theme.DiffHunkHeaderColor = lipgloss.Color(darkPurple)
+	theme.DiffHighlightAddedColor = lipgloss.Color("#50fa7b")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#ff5555")
+	theme.DiffAddedBgColor = lipgloss.Color("#2c3b2c")
+	theme.DiffRemovedBgColor = lipgloss.Color("#3b2c2c")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color(darkComment)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#253025")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#302525")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkPink,
-		Light: lightPink,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkPink)
+	theme.MarkdownLinkColor = lipgloss.Color(darkPurple)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkPurple)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageColor = lipgloss.Color(darkPurple)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkPink,
-		Light: lightPink,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkPink,
-		Light: lightPink,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkPink)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
+	theme.SyntaxVariableColor = lipgloss.Color(darkOrange)
+	theme.SyntaxStringColor = lipgloss.Color(darkYellow)
+	theme.SyntaxNumberColor = lipgloss.Color(darkPurple)
+	theme.SyntaxTypeColor = lipgloss.Color(darkCyan)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkPink)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
 
 	return theme
 }

internal/tui/theme/flexoki.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // Flexoki color palette constants
@@ -49,234 +49,156 @@ type FlexokiTheme struct {
 	BaseTheme
 }
 
-// NewFlexokiTheme creates a new instance of the Flexoki theme.
-func NewFlexokiTheme() *FlexokiTheme {
+// NewFlexokiDarkTheme creates a new instance of the Flexoki Dark theme.
+func NewFlexokiDarkTheme() *FlexokiTheme {
 	theme := &FlexokiTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlue400,
-		Light: flexokiBlue600,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiPurple400,
-		Light: flexokiPurple600,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiOrange400,
-		Light: flexokiOrange600,
-	}
+	theme.PrimaryColor = lipgloss.Color(flexokiBlue400)
+	theme.SecondaryColor = lipgloss.Color(flexokiPurple400)
+	theme.AccentColor = lipgloss.Color(flexokiOrange400)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiRed400,
-		Light: flexokiRed600,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiYellow400,
-		Light: flexokiYellow600,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiGreen400,
-		Light: flexokiGreen600,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiCyan400,
-		Light: flexokiCyan600,
-	}
+	theme.ErrorColor = lipgloss.Color(flexokiRed400)
+	theme.WarningColor = lipgloss.Color(flexokiYellow400)
+	theme.SuccessColor = lipgloss.Color(flexokiGreen400)
+	theme.InfoColor = lipgloss.Color(flexokiCyan400)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase300,
-		Light: flexokiBase600,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase700,
-		Light: flexokiBase500,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiYellow400,
-		Light: flexokiYellow600,
-	}
+	theme.TextColor = lipgloss.Color(flexokiBase300)
+	theme.TextMutedColor = lipgloss.Color(flexokiBase700)
+	theme.TextEmphasizedColor = lipgloss.Color(flexokiYellow400)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlack,
-		Light: flexokiPaper,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase950,
-		Light: flexokiBase50,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase900,
-		Light: flexokiBase100,
-	}
+	theme.BackgroundColor = lipgloss.Color(flexokiBlack)
+	theme.BackgroundSecondaryColor = lipgloss.Color(flexokiBase950)
+	theme.BackgroundDarkerColor = lipgloss.Color(flexokiBase900)
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase900,
-		Light: flexokiBase100,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlue400,
-		Light: flexokiBlue600,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase850,
-		Light: flexokiBase150,
-	}
+	theme.BorderNormalColor = lipgloss.Color(flexokiBase900)
+	theme.BorderFocusedColor = lipgloss.Color(flexokiBlue400)
+	theme.BorderDimColor = lipgloss.Color(flexokiBase850)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiGreen400,
-		Light: flexokiGreen600,
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiRed400,
-		Light: flexokiRed600,
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase700,
-		Light: flexokiBase500,
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase700,
-		Light: flexokiBase500,
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiGreen400,
-		Light: flexokiGreen600,
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiRed400,
-		Light: flexokiRed600,
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#1D2419", // Darker green background
-		Light: "#EFF2E2", // Light green background
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#241919", // Darker red background
-		Light: "#F2E2E2", // Light red background
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlack,
-		Light: flexokiPaper,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase700,
-		Light: flexokiBase500,
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#1A2017", // Slightly darker green
-		Light: "#E5EBD9", // Light green
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#201717", // Slightly darker red
-		Light: "#EBD9D9", // Light red
-	}
+	theme.DiffAddedColor = lipgloss.Color(flexokiGreen400)
+	theme.DiffRemovedColor = lipgloss.Color(flexokiRed400)
+	theme.DiffContextColor = lipgloss.Color(flexokiBase700)
+	theme.DiffHunkHeaderColor = lipgloss.Color(flexokiBase700)
+	theme.DiffHighlightAddedColor = lipgloss.Color(flexokiGreen400)
+	theme.DiffHighlightRemovedColor = lipgloss.Color(flexokiRed400)
+	theme.DiffAddedBgColor = lipgloss.Color("#1D2419") // Darker green background
+	theme.DiffRemovedBgColor = lipgloss.Color("#241919") // Darker red background
+	theme.DiffContextBgColor = lipgloss.Color(flexokiBlack)
+	theme.DiffLineNumberColor = lipgloss.Color(flexokiBase700)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#1A2017") // Slightly darker green
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#201717") // Slightly darker red
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase300,
-		Light: flexokiBase600,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiYellow400,
-		Light: flexokiYellow600,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiCyan400,
-		Light: flexokiCyan600,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiMagenta400,
-		Light: flexokiMagenta600,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiGreen400,
-		Light: flexokiGreen600,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiCyan400,
-		Light: flexokiCyan600,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiYellow400,
-		Light: flexokiYellow600,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiOrange400,
-		Light: flexokiOrange600,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase800,
-		Light: flexokiBase200,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlue400,
-		Light: flexokiBlue600,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlue400,
-		Light: flexokiBlue600,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiPurple400,
-		Light: flexokiPurple600,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiMagenta400,
-		Light: flexokiMagenta600,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase300,
-		Light: flexokiBase600,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(flexokiBase300)
+	theme.MarkdownHeadingColor = lipgloss.Color(flexokiYellow400)
+	theme.MarkdownLinkColor = lipgloss.Color(flexokiCyan400)
+	theme.MarkdownLinkTextColor = lipgloss.Color(flexokiMagenta400)
+	theme.MarkdownCodeColor = lipgloss.Color(flexokiGreen400)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(flexokiCyan400)
+	theme.MarkdownEmphColor = lipgloss.Color(flexokiYellow400)
+	theme.MarkdownStrongColor = lipgloss.Color(flexokiOrange400)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(flexokiBase800)
+	theme.MarkdownListItemColor = lipgloss.Color(flexokiBlue400)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(flexokiBlue400)
+	theme.MarkdownImageColor = lipgloss.Color(flexokiPurple400)
+	theme.MarkdownImageTextColor = lipgloss.Color(flexokiMagenta400)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(flexokiBase300)
 
 	// Syntax highlighting colors (based on Flexoki's mappings)
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase700, // tx-3
-		Light: flexokiBase300, // tx-3
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiGreen400, // gr
-		Light: flexokiGreen600, // gr
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiOrange400, // or
-		Light: flexokiOrange600, // or
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBlue400, // bl
-		Light: flexokiBlue600, // bl
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiCyan400, // cy
-		Light: flexokiCyan600, // cy
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiPurple400, // pu
-		Light: flexokiPurple600, // pu
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiYellow400, // ye
-		Light: flexokiYellow600, // ye
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase500, // tx-2
-		Light: flexokiBase500, // tx-2
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  flexokiBase500, // tx-2
-		Light: flexokiBase500, // tx-2
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(flexokiBase700) // tx-3
+	theme.SyntaxKeywordColor = lipgloss.Color(flexokiGreen400) // gr
+	theme.SyntaxFunctionColor = lipgloss.Color(flexokiOrange400) // or
+	theme.SyntaxVariableColor = lipgloss.Color(flexokiBlue400) // bl
+	theme.SyntaxStringColor = lipgloss.Color(flexokiCyan400) // cy
+	theme.SyntaxNumberColor = lipgloss.Color(flexokiPurple400) // pu
+	theme.SyntaxTypeColor = lipgloss.Color(flexokiYellow400) // ye
+	theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
+	theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
+
+	return theme
+}
+
+// NewFlexokiLightTheme creates a new instance of the Flexoki Light theme.
+func NewFlexokiLightTheme() *FlexokiTheme {
+	theme := &FlexokiTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(flexokiBlue600)
+	theme.SecondaryColor = lipgloss.Color(flexokiPurple600)
+	theme.AccentColor = lipgloss.Color(flexokiOrange600)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(flexokiRed600)
+	theme.WarningColor = lipgloss.Color(flexokiYellow600)
+	theme.SuccessColor = lipgloss.Color(flexokiGreen600)
+	theme.InfoColor = lipgloss.Color(flexokiCyan600)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(flexokiBase600)
+	theme.TextMutedColor = lipgloss.Color(flexokiBase500)
+	theme.TextEmphasizedColor = lipgloss.Color(flexokiYellow600)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(flexokiPaper)
+	theme.BackgroundSecondaryColor = lipgloss.Color(flexokiBase50)
+	theme.BackgroundDarkerColor = lipgloss.Color(flexokiBase100)
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(flexokiBase100)
+	theme.BorderFocusedColor = lipgloss.Color(flexokiBlue600)
+	theme.BorderDimColor = lipgloss.Color(flexokiBase150)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color(flexokiGreen600)
+	theme.DiffRemovedColor = lipgloss.Color(flexokiRed600)
+	theme.DiffContextColor = lipgloss.Color(flexokiBase500)
+	theme.DiffHunkHeaderColor = lipgloss.Color(flexokiBase500)
+	theme.DiffHighlightAddedColor = lipgloss.Color(flexokiGreen600)
+	theme.DiffHighlightRemovedColor = lipgloss.Color(flexokiRed600)
+	theme.DiffAddedBgColor = lipgloss.Color("#EFF2E2") // Light green background
+	theme.DiffRemovedBgColor = lipgloss.Color("#F2E2E2") // Light red background
+	theme.DiffContextBgColor = lipgloss.Color(flexokiPaper)
+	theme.DiffLineNumberColor = lipgloss.Color(flexokiBase500)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#E5EBD9") // Light green
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#EBD9D9") // Light red
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(flexokiBase600)
+	theme.MarkdownHeadingColor = lipgloss.Color(flexokiYellow600)
+	theme.MarkdownLinkColor = lipgloss.Color(flexokiCyan600)
+	theme.MarkdownLinkTextColor = lipgloss.Color(flexokiMagenta600)
+	theme.MarkdownCodeColor = lipgloss.Color(flexokiGreen600)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(flexokiCyan600)
+	theme.MarkdownEmphColor = lipgloss.Color(flexokiYellow600)
+	theme.MarkdownStrongColor = lipgloss.Color(flexokiOrange600)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(flexokiBase200)
+	theme.MarkdownListItemColor = lipgloss.Color(flexokiBlue600)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(flexokiBlue600)
+	theme.MarkdownImageColor = lipgloss.Color(flexokiPurple600)
+	theme.MarkdownImageTextColor = lipgloss.Color(flexokiMagenta600)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(flexokiBase600)
+
+	// Syntax highlighting colors (based on Flexoki's mappings)
+	theme.SyntaxCommentColor = lipgloss.Color(flexokiBase300) // tx-3
+	theme.SyntaxKeywordColor = lipgloss.Color(flexokiGreen600) // gr
+	theme.SyntaxFunctionColor = lipgloss.Color(flexokiOrange600) // or
+	theme.SyntaxVariableColor = lipgloss.Color(flexokiBlue600) // bl
+	theme.SyntaxStringColor = lipgloss.Color(flexokiCyan600) // cy
+	theme.SyntaxNumberColor = lipgloss.Color(flexokiPurple600) // pu
+	theme.SyntaxTypeColor = lipgloss.Color(flexokiYellow600) // ye
+	theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
+	theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
 
 	return theme
 }
 
 func init() {
-	// Register the Flexoki theme with the theme manager
-	RegisterTheme("flexoki", NewFlexokiTheme())
+	// Register the Flexoki themes with the theme manager
+	RegisterTheme("flexoki-dark", NewFlexokiDarkTheme())
+	RegisterTheme("flexoki-light", NewFlexokiLightTheme())
 }

internal/tui/theme/gruvbox.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // Gruvbox color palette constants
@@ -74,229 +74,151 @@ func NewGruvboxTheme() *GruvboxTheme {
 	theme := &GruvboxTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkPurpleBright,
-		Light: gruvboxLightPurpleBright,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkOrangeBright,
-		Light: gruvboxLightOrangeBright,
-	}
+	theme.PrimaryColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.SecondaryColor = lipgloss.Color(gruvboxDarkPurpleBright)
+	theme.AccentColor = lipgloss.Color(gruvboxDarkOrangeBright)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkRedBright,
-		Light: gruvboxLightRedBright,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellowBright,
-		Light: gruvboxLightYellowBright,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGreenBright,
-		Light: gruvboxLightGreenBright,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
+	theme.ErrorColor = lipgloss.Color(gruvboxDarkRedBright)
+	theme.WarningColor = lipgloss.Color(gruvboxDarkYellowBright)
+	theme.SuccessColor = lipgloss.Color(gruvboxDarkGreenBright)
+	theme.InfoColor = lipgloss.Color(gruvboxDarkBlueBright)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg1,
-		Light: gruvboxLightFg1,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg4,
-		Light: gruvboxLightFg4,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellowBright,
-		Light: gruvboxLightYellowBright,
-	}
+	theme.TextColor = lipgloss.Color(gruvboxDarkFg1)
+	theme.TextMutedColor = lipgloss.Color(gruvboxDarkFg4)
+	theme.TextEmphasizedColor = lipgloss.Color(gruvboxDarkYellowBright)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg0,
-		Light: gruvboxLightBg0,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg1,
-		Light: gruvboxLightBg1,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg0Soft,
-		Light: gruvboxLightBg0Soft,
-	}
+	theme.BackgroundColor = lipgloss.Color(gruvboxDarkBg0)
+	theme.BackgroundSecondaryColor = lipgloss.Color(gruvboxDarkBg1)
+	theme.BackgroundDarkerColor = lipgloss.Color(gruvboxDarkBg0Soft)
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg2,
-		Light: gruvboxLightBg2,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg1,
-		Light: gruvboxLightBg1,
-	}
+	theme.BorderNormalColor = lipgloss.Color(gruvboxDarkBg2)
+	theme.BorderFocusedColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.BorderDimColor = lipgloss.Color(gruvboxDarkBg1)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGreenBright,
-		Light: gruvboxLightGreenBright,
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkRedBright,
-		Light: gruvboxLightRedBright,
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg4,
-		Light: gruvboxLightFg4,
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg3,
-		Light: gruvboxLightFg3,
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGreenBright,
-		Light: gruvboxLightGreenBright,
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkRedBright,
-		Light: gruvboxLightRedBright,
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3C4C3C",  // Darker green background
-		Light: "#E8F5E9", // Light green background
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#4C3C3C",  // Darker red background
-		Light: "#FFEBEE", // Light red background
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg0,
-		Light: gruvboxLightBg0,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg4,
-		Light: gruvboxLightFg4,
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#32432F",   // Slightly darker green
-		Light: "#C8E6C9", // Light green
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#43322F",   // Slightly darker red
-		Light: "#FFCDD2", // Light red
-	}
+	theme.DiffAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
+	theme.DiffRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
+	theme.DiffContextColor = lipgloss.Color(gruvboxDarkFg4)
+	theme.DiffHunkHeaderColor = lipgloss.Color(gruvboxDarkFg3)
+	theme.DiffHighlightAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
+	theme.DiffHighlightRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
+	theme.DiffAddedBgColor = lipgloss.Color("#3C4C3C")  // Darker green background
+	theme.DiffRemovedBgColor = lipgloss.Color("#4C3C3C")  // Darker red background
+	theme.DiffContextBgColor = lipgloss.Color(gruvboxDarkBg0)
+	theme.DiffLineNumberColor = lipgloss.Color(gruvboxDarkFg4)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#32432F")   // Slightly darker green
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#43322F")   // Slightly darker red
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg1,
-		Light: gruvboxLightFg1,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellowBright,
-		Light: gruvboxLightYellowBright,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkAquaBright,
-		Light: gruvboxLightAquaBright,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGreenBright,
-		Light: gruvboxLightGreenBright,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkAquaBright,
-		Light: gruvboxLightAquaBright,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellowBright,
-		Light: gruvboxLightYellowBright,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkOrangeBright,
-		Light: gruvboxLightOrangeBright,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBg3,
-		Light: gruvboxLightBg3,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkPurpleBright,
-		Light: gruvboxLightPurpleBright,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkAquaBright,
-		Light: gruvboxLightAquaBright,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg1,
-		Light: gruvboxLightFg1,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(gruvboxDarkFg1)
+	theme.MarkdownHeadingColor = lipgloss.Color(gruvboxDarkYellowBright)
+	theme.MarkdownLinkColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.MarkdownLinkTextColor = lipgloss.Color(gruvboxDarkAquaBright)
+	theme.MarkdownCodeColor = lipgloss.Color(gruvboxDarkGreenBright)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(gruvboxDarkAquaBright)
+	theme.MarkdownEmphColor = lipgloss.Color(gruvboxDarkYellowBright)
+	theme.MarkdownStrongColor = lipgloss.Color(gruvboxDarkOrangeBright)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(gruvboxDarkBg3)
+	theme.MarkdownListItemColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.MarkdownImageColor = lipgloss.Color(gruvboxDarkPurpleBright)
+	theme.MarkdownImageTextColor = lipgloss.Color(gruvboxDarkAquaBright)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(gruvboxDarkFg1)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGray,
-		Light: gruvboxLightGray,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkRedBright,
-		Light: gruvboxLightRedBright,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkGreenBright,
-		Light: gruvboxLightGreenBright,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkBlueBright,
-		Light: gruvboxLightBlueBright,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellowBright,
-		Light: gruvboxLightYellowBright,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkPurpleBright,
-		Light: gruvboxLightPurpleBright,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkYellow,
-		Light: gruvboxLightYellow,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkAquaBright,
-		Light: gruvboxLightAquaBright,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  gruvboxDarkFg1,
-		Light: gruvboxLightFg1,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(gruvboxDarkGray)
+	theme.SyntaxKeywordColor = lipgloss.Color(gruvboxDarkRedBright)
+	theme.SyntaxFunctionColor = lipgloss.Color(gruvboxDarkGreenBright)
+	theme.SyntaxVariableColor = lipgloss.Color(gruvboxDarkBlueBright)
+	theme.SyntaxStringColor = lipgloss.Color(gruvboxDarkYellowBright)
+	theme.SyntaxNumberColor = lipgloss.Color(gruvboxDarkPurpleBright)
+	theme.SyntaxTypeColor = lipgloss.Color(gruvboxDarkYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(gruvboxDarkAquaBright)
+	theme.SyntaxPunctuationColor = lipgloss.Color(gruvboxDarkFg1)
+
+	return theme
+}
+
+// NewGruvboxLightTheme creates a new instance of the Gruvbox Light theme.
+func NewGruvboxLightTheme() *GruvboxTheme {
+	theme := &GruvboxTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.SecondaryColor = lipgloss.Color(gruvboxLightPurpleBright)
+	theme.AccentColor = lipgloss.Color(gruvboxLightOrangeBright)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(gruvboxLightRedBright)
+	theme.WarningColor = lipgloss.Color(gruvboxLightYellowBright)
+	theme.SuccessColor = lipgloss.Color(gruvboxLightGreenBright)
+	theme.InfoColor = lipgloss.Color(gruvboxLightBlueBright)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(gruvboxLightFg1)
+	theme.TextMutedColor = lipgloss.Color(gruvboxLightFg4)
+	theme.TextEmphasizedColor = lipgloss.Color(gruvboxLightYellowBright)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(gruvboxLightBg0)
+	theme.BackgroundSecondaryColor = lipgloss.Color(gruvboxLightBg1)
+	theme.BackgroundDarkerColor = lipgloss.Color(gruvboxLightBg0Soft)
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(gruvboxLightBg2)
+	theme.BorderFocusedColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.BorderDimColor = lipgloss.Color(gruvboxLightBg1)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color(gruvboxLightGreenBright)
+	theme.DiffRemovedColor = lipgloss.Color(gruvboxLightRedBright)
+	theme.DiffContextColor = lipgloss.Color(gruvboxLightFg4)
+	theme.DiffHunkHeaderColor = lipgloss.Color(gruvboxLightFg3)
+	theme.DiffHighlightAddedColor = lipgloss.Color(gruvboxLightGreenBright)
+	theme.DiffHighlightRemovedColor = lipgloss.Color(gruvboxLightRedBright)
+	theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9") // Light green background
+	theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE") // Light red background
+	theme.DiffContextBgColor = lipgloss.Color(gruvboxLightBg0)
+	theme.DiffLineNumberColor = lipgloss.Color(gruvboxLightFg4)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9") // Light green
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2") // Light red
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(gruvboxLightFg1)
+	theme.MarkdownHeadingColor = lipgloss.Color(gruvboxLightYellowBright)
+	theme.MarkdownLinkColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.MarkdownLinkTextColor = lipgloss.Color(gruvboxLightAquaBright)
+	theme.MarkdownCodeColor = lipgloss.Color(gruvboxLightGreenBright)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(gruvboxLightAquaBright)
+	theme.MarkdownEmphColor = lipgloss.Color(gruvboxLightYellowBright)
+	theme.MarkdownStrongColor = lipgloss.Color(gruvboxLightOrangeBright)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(gruvboxLightBg3)
+	theme.MarkdownListItemColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.MarkdownImageColor = lipgloss.Color(gruvboxLightPurpleBright)
+	theme.MarkdownImageTextColor = lipgloss.Color(gruvboxLightAquaBright)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(gruvboxLightFg1)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(gruvboxLightGray)
+	theme.SyntaxKeywordColor = lipgloss.Color(gruvboxLightRedBright)
+	theme.SyntaxFunctionColor = lipgloss.Color(gruvboxLightGreenBright)
+	theme.SyntaxVariableColor = lipgloss.Color(gruvboxLightBlueBright)
+	theme.SyntaxStringColor = lipgloss.Color(gruvboxLightYellowBright)
+	theme.SyntaxNumberColor = lipgloss.Color(gruvboxLightPurpleBright)
+	theme.SyntaxTypeColor = lipgloss.Color(gruvboxLightYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(gruvboxLightAquaBright)
+	theme.SyntaxPunctuationColor = lipgloss.Color(gruvboxLightFg1)
 
 	return theme
 }
 
 func init() {
-	// Register the Gruvbox theme with the theme manager
+	// Register the Gruvbox themes with the theme manager
 	RegisterTheme("gruvbox", NewGruvboxTheme())
+	RegisterTheme("gruvbox-light", NewGruvboxLightTheme())
 }

internal/tui/theme/monokai.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // MonokaiProTheme implements the Theme interface with Monokai Pro colors.
@@ -27,6 +27,80 @@ func NewMonokaiProTheme() *MonokaiProTheme {
 	darkPurple := "#ab9df2"
 	darkBorder := "#403e41"
 
+	theme := &MonokaiProTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(darkCyan)
+	theme.SecondaryColor = lipgloss.Color(darkPurple)
+	theme.AccentColor = lipgloss.Color(darkOrange)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkBlue)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#221f22") // Slightly darker than background
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkCyan)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color("#a9dc76")
+	theme.DiffRemovedColor = lipgloss.Color("#ff6188")
+	theme.DiffContextColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#c2e7a9")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#ff8ca6")
+	theme.DiffAddedBgColor = lipgloss.Color("#3a4a35")
+	theme.DiffRemovedBgColor = lipgloss.Color("#4a3439")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#888888")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#2d3a28")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#3d2a2e")
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(darkCyan)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkBlue)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkCyan)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkBlue)
+	theme.MarkdownImageColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkBlue)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkRed)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
+	theme.SyntaxVariableColor = lipgloss.Color(darkForeground)
+	theme.SyntaxStringColor = lipgloss.Color(darkYellow)
+	theme.SyntaxNumberColor = lipgloss.Color(darkPurple)
+	theme.SyntaxTypeColor = lipgloss.Color(darkBlue)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
+
+	return theme
+}
+
+// NewMonokaiProLightTheme creates a new instance of the Monokai Pro Light theme.
+func NewMonokaiProLightTheme() *MonokaiProTheme {
 	// Light mode colors (adapted from dark)
 	lightBackground := "#fafafa"
 	lightCurrentLine := "#f0f0f0"
@@ -45,229 +119,77 @@ func NewMonokaiProTheme() *MonokaiProTheme {
 	theme := &MonokaiProTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
+	theme.PrimaryColor = lipgloss.Color(lightCyan)
+	theme.SecondaryColor = lipgloss.Color(lightPurple)
+	theme.AccentColor = lipgloss.Color(lightOrange)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
+	theme.ErrorColor = lipgloss.Color(lightRed)
+	theme.WarningColor = lipgloss.Color(lightOrange)
+	theme.SuccessColor = lipgloss.Color(lightGreen)
+	theme.InfoColor = lipgloss.Color(lightBlue)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(lightForeground)
+	theme.TextMutedColor = lipgloss.Color(lightComment)
+	theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#221f22", // Slightly darker than background
-		Light: "#ffffff", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(lightBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(lightBorder)
+	theme.BorderFocusedColor = lipgloss.Color(lightCyan)
+	theme.BorderDimColor = lipgloss.Color(lightSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#a9dc76",
-		Light: "#9bca65",
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#ff6188",
-		Light: "#f92672",
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#c2e7a9",
-		Light: "#c5e0b4",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#ff8ca6",
-		Light: "#ffb3c8",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3a4a35",
-		Light: "#e8f5e9",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#4a3439",
-		Light: "#ffebee",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  "#888888",
-		Light: "#9e9e9e",
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#2d3a28",
-		Light: "#c8e6c9",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3d2a2e",
-		Light: "#ffcdd2",
-	}
+	theme.DiffAddedColor = lipgloss.Color("#9bca65")
+	theme.DiffRemovedColor = lipgloss.Color("#f92672")
+	theme.DiffContextColor = lipgloss.Color("#757575")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#c5e0b4")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#ffb3c8")
+	theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
+	theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
+	theme.DiffContextBgColor = lipgloss.Color(lightBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#9e9e9e")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(lightForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(lightCyan)
+	theme.MarkdownLinkTextColor = lipgloss.Color(lightBlue)
+	theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
+	theme.MarkdownListItemColor = lipgloss.Color(lightCyan)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(lightBlue)
+	theme.MarkdownImageColor = lipgloss.Color(lightCyan)
+	theme.MarkdownImageTextColor = lipgloss.Color(lightBlue)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(lightComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(lightRed)
+	theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
+	theme.SyntaxVariableColor = lipgloss.Color(lightForeground)
+	theme.SyntaxStringColor = lipgloss.Color(lightYellow)
+	theme.SyntaxNumberColor = lipgloss.Color(lightPurple)
+	theme.SyntaxTypeColor = lipgloss.Color(lightBlue)
+	theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
 
 	return theme
 }
 
 func init() {
-	// Register the Monokai Pro theme with the theme manager
+	// Register the Monokai Pro themes with the theme manager
 	RegisterTheme("monokai", NewMonokaiProTheme())
+	RegisterTheme("monokai-light", NewMonokaiProLightTheme())
 }

internal/tui/theme/onedark.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // OneDarkTheme implements the Theme interface with Atom's One Dark colors.
@@ -28,6 +28,80 @@ func NewOneDarkTheme() *OneDarkTheme {
 	darkPurple := "#c678dd"
 	darkBorder := "#3b4048"
 
+	theme := &OneDarkTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(darkBlue)
+	theme.SecondaryColor = lipgloss.Color(darkPurple)
+	theme.AccentColor = lipgloss.Color(darkOrange)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkBlue)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#21252b") // Slightly darker than background
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkBlue)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color("#478247")
+	theme.DiffRemovedColor = lipgloss.Color("#7C4444")
+	theme.DiffContextColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD")
+	theme.DiffAddedBgColor = lipgloss.Color("#303A30")
+	theme.DiffRemovedBgColor = lipgloss.Color("#3A3030")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#888888")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929")
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageColor = lipgloss.Color(darkBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkPurple)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkBlue)
+	theme.SyntaxVariableColor = lipgloss.Color(darkRed)
+	theme.SyntaxStringColor = lipgloss.Color(darkGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(darkOrange)
+	theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
+
+	return theme
+}
+
+// NewOneLightTheme creates a new instance of the One Light theme.
+func NewOneLightTheme() *OneDarkTheme {
 	// Light mode colors from Atom One Light
 	lightBackground := "#fafafa"
 	lightCurrentLine := "#f0f0f0"
@@ -46,229 +120,77 @@ func NewOneDarkTheme() *OneDarkTheme {
 	theme := &OneDarkTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
+	theme.PrimaryColor = lipgloss.Color(lightBlue)
+	theme.SecondaryColor = lipgloss.Color(lightPurple)
+	theme.AccentColor = lipgloss.Color(lightOrange)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
+	theme.ErrorColor = lipgloss.Color(lightRed)
+	theme.WarningColor = lipgloss.Color(lightOrange)
+	theme.SuccessColor = lipgloss.Color(lightGreen)
+	theme.InfoColor = lipgloss.Color(lightBlue)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(lightForeground)
+	theme.TextMutedColor = lipgloss.Color(lightComment)
+	theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#21252b", // Slightly darker than background
-		Light: "#ffffff", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(lightBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(lightBorder)
+	theme.BorderFocusedColor = lipgloss.Color(lightBlue)
+	theme.BorderDimColor = lipgloss.Color(lightSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#478247",
-		Light: "#2E7D32",
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#7C4444",
-		Light: "#C62828",
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#DAFADA",
-		Light: "#A5D6A7",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#FADADD",
-		Light: "#EF9A9A",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#303A30",
-		Light: "#E8F5E9",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3A3030",
-		Light: "#FFEBEE",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  "#888888",
-		Light: "#9E9E9E",
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#293229",
-		Light: "#C8E6C9",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#332929",
-		Light: "#FFCDD2",
-	}
+	theme.DiffAddedColor = lipgloss.Color("#2E7D32")
+	theme.DiffRemovedColor = lipgloss.Color("#C62828")
+	theme.DiffContextColor = lipgloss.Color("#757575")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
+	theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
+	theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
+	theme.DiffContextBgColor = lipgloss.Color(lightBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(lightForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
+	theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
+	theme.MarkdownImageColor = lipgloss.Color(lightBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(lightComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
+	theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
+	theme.SyntaxVariableColor = lipgloss.Color(lightRed)
+	theme.SyntaxStringColor = lipgloss.Color(lightGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
+	theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
 
 	return theme
 }
 
 func init() {
-	// Register the One Dark theme with the theme manager
+	// Register the One Dark and One Light themes with the theme manager
 	RegisterTheme("onedark", NewOneDarkTheme())
+	RegisterTheme("onelight", NewOneLightTheme())
 }

internal/tui/theme/opencode.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // OpenCodeTheme implements the Theme interface with OpenCode brand colors.
@@ -10,8 +10,8 @@ type OpenCodeTheme struct {
 	BaseTheme
 }
 
-// NewOpenCodeTheme creates a new instance of the OpenCode theme.
-func NewOpenCodeTheme() *OpenCodeTheme {
+// NewOpenCodeDarkTheme creates a new instance of the OpenCode Dark theme.
+func NewOpenCodeDarkTheme() *OpenCodeTheme {
 	// OpenCode color palette
 	// Dark mode colors
 	darkBackground := "#212121"
@@ -29,6 +29,80 @@ func NewOpenCodeTheme() *OpenCodeTheme {
 	darkYellow := "#e5c07b"    // Emphasized text
 	darkBorder := "#4b4c5c"    // Border color
 
+	theme := &OpenCodeTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(darkPrimary)
+	theme.SecondaryColor = lipgloss.Color(darkSecondary)
+	theme.AccentColor = lipgloss.Color(darkAccent)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkCyan)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#121212") // Slightly darker than background
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkPrimary)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color("#478247")
+	theme.DiffRemovedColor = lipgloss.Color("#7C4444")
+	theme.DiffContextColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD")
+	theme.DiffAddedBgColor = lipgloss.Color("#303A30")
+	theme.DiffRemovedBgColor = lipgloss.Color("#3A3030")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#888888")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929")
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkSecondary)
+	theme.MarkdownLinkColor = lipgloss.Color(darkPrimary)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkAccent)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkPrimary)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageColor = lipgloss.Color(darkPrimary)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkSecondary)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkPrimary)
+	theme.SyntaxVariableColor = lipgloss.Color(darkRed)
+	theme.SyntaxStringColor = lipgloss.Color(darkGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(darkAccent)
+	theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
+
+	return theme
+}
+
+// NewOpenCodeLightTheme creates a new instance of the OpenCode Light theme.
+func NewOpenCodeLightTheme() *OpenCodeTheme {
 	// Light mode colors
 	lightBackground := "#f8f8f8"
 	lightCurrentLine := "#f0f0f0"
@@ -48,230 +122,77 @@ func NewOpenCodeTheme() *OpenCodeTheme {
 	theme := &OpenCodeTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkSecondary,
-		Light: lightSecondary,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkAccent,
-		Light: lightAccent,
-	}
+	theme.PrimaryColor = lipgloss.Color(lightPrimary)
+	theme.SecondaryColor = lipgloss.Color(lightSecondary)
+	theme.AccentColor = lipgloss.Color(lightAccent)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
+	theme.ErrorColor = lipgloss.Color(lightRed)
+	theme.WarningColor = lipgloss.Color(lightOrange)
+	theme.SuccessColor = lipgloss.Color(lightGreen)
+	theme.InfoColor = lipgloss.Color(lightCyan)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(lightForeground)
+	theme.TextMutedColor = lipgloss.Color(lightComment)
+	theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#121212", // Slightly darker than background
-		Light: "#ffffff", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(lightBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(lightBorder)
+	theme.BorderFocusedColor = lipgloss.Color(lightPrimary)
+	theme.BorderDimColor = lipgloss.Color(lightSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#478247",
-		Light: "#2E7D32",
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#7C4444",
-		Light: "#C62828",
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  "#a0a0a0",
-		Light: "#757575",
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#DAFADA",
-		Light: "#A5D6A7",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#FADADD",
-		Light: "#EF9A9A",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#303A30",
-		Light: "#E8F5E9",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#3A3030",
-		Light: "#FFEBEE",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  "#888888",
-		Light: "#9E9E9E",
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#293229",
-		Light: "#C8E6C9",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#332929",
-		Light: "#FFCDD2",
-	}
+	theme.DiffAddedColor = lipgloss.Color("#2E7D32")
+	theme.DiffRemovedColor = lipgloss.Color("#C62828")
+	theme.DiffContextColor = lipgloss.Color("#757575")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
+	theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
+	theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
+	theme.DiffContextBgColor = lipgloss.Color(lightBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkSecondary,
-		Light: lightSecondary,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkAccent,
-		Light: lightAccent,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(lightForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(lightSecondary)
+	theme.MarkdownLinkColor = lipgloss.Color(lightPrimary)
+	theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(lightAccent)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
+	theme.MarkdownListItemColor = lipgloss.Color(lightPrimary)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
+	theme.MarkdownImageColor = lipgloss.Color(lightPrimary)
+	theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkSecondary,
-		Light: lightSecondary,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkPrimary,
-		Light: lightPrimary,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkAccent,
-		Light: lightAccent,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(lightComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(lightSecondary)
+	theme.SyntaxFunctionColor = lipgloss.Color(lightPrimary)
+	theme.SyntaxVariableColor = lipgloss.Color(lightRed)
+	theme.SyntaxStringColor = lipgloss.Color(lightGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(lightAccent)
+	theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
 
 	return theme
 }
 
 func init() {
-	// Register the OpenCode theme with the theme manager
-	RegisterTheme("opencode", NewOpenCodeTheme())
-}
-
+	// Register the OpenCode themes with the theme manager
+	RegisterTheme("opencode-dark", NewOpenCodeDarkTheme())
+	RegisterTheme("opencode-light", NewOpenCodeLightTheme())
+}

internal/tui/theme/theme.go 🔗

@@ -1,208 +1,205 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"image/color"
 )
 
-// Theme defines the interface for all UI themes in the application.
-// All colors must be defined as lipgloss.AdaptiveColor to support
-// both light and dark terminal backgrounds.
 type Theme interface {
 	// Base colors
-	Primary() lipgloss.AdaptiveColor
-	Secondary() lipgloss.AdaptiveColor
-	Accent() lipgloss.AdaptiveColor
+	Primary() color.Color
+	Secondary() color.Color
+	Accent() color.Color
 
 	// Status colors
-	Error() lipgloss.AdaptiveColor
-	Warning() lipgloss.AdaptiveColor
-	Success() lipgloss.AdaptiveColor
-	Info() lipgloss.AdaptiveColor
+	Error() color.Color
+	Warning() color.Color
+	Success() color.Color
+	Info() color.Color
 
 	// Text colors
-	Text() lipgloss.AdaptiveColor
-	TextMuted() lipgloss.AdaptiveColor
-	TextEmphasized() lipgloss.AdaptiveColor
+	Text() color.Color
+	TextMuted() color.Color
+	TextEmphasized() color.Color
 
 	// Background colors
-	Background() lipgloss.AdaptiveColor
-	BackgroundSecondary() lipgloss.AdaptiveColor
-	BackgroundDarker() lipgloss.AdaptiveColor
+	Background() color.Color
+	BackgroundSecondary() color.Color
+	BackgroundDarker() color.Color
 
 	// Border colors
-	BorderNormal() lipgloss.AdaptiveColor
-	BorderFocused() lipgloss.AdaptiveColor
-	BorderDim() lipgloss.AdaptiveColor
+	BorderNormal() color.Color
+	BorderFocused() color.Color
+	BorderDim() color.Color
 
 	// Diff view colors
-	DiffAdded() lipgloss.AdaptiveColor
-	DiffRemoved() lipgloss.AdaptiveColor
-	DiffContext() lipgloss.AdaptiveColor
-	DiffHunkHeader() lipgloss.AdaptiveColor
-	DiffHighlightAdded() lipgloss.AdaptiveColor
-	DiffHighlightRemoved() lipgloss.AdaptiveColor
-	DiffAddedBg() lipgloss.AdaptiveColor
-	DiffRemovedBg() lipgloss.AdaptiveColor
-	DiffContextBg() lipgloss.AdaptiveColor
-	DiffLineNumber() lipgloss.AdaptiveColor
-	DiffAddedLineNumberBg() lipgloss.AdaptiveColor
-	DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
+	DiffAdded() color.Color
+	DiffRemoved() color.Color
+	DiffContext() color.Color
+	DiffHunkHeader() color.Color
+	DiffHighlightAdded() color.Color
+	DiffHighlightRemoved() color.Color
+	DiffAddedBg() color.Color
+	DiffRemovedBg() color.Color
+	DiffContextBg() color.Color
+	DiffLineNumber() color.Color
+	DiffAddedLineNumberBg() color.Color
+	DiffRemovedLineNumberBg() color.Color
 
 	// Markdown colors
-	MarkdownText() lipgloss.AdaptiveColor
-	MarkdownHeading() lipgloss.AdaptiveColor
-	MarkdownLink() lipgloss.AdaptiveColor
-	MarkdownLinkText() lipgloss.AdaptiveColor
-	MarkdownCode() lipgloss.AdaptiveColor
-	MarkdownBlockQuote() lipgloss.AdaptiveColor
-	MarkdownEmph() lipgloss.AdaptiveColor
-	MarkdownStrong() lipgloss.AdaptiveColor
-	MarkdownHorizontalRule() lipgloss.AdaptiveColor
-	MarkdownListItem() lipgloss.AdaptiveColor
-	MarkdownListEnumeration() lipgloss.AdaptiveColor
-	MarkdownImage() lipgloss.AdaptiveColor
-	MarkdownImageText() lipgloss.AdaptiveColor
-	MarkdownCodeBlock() lipgloss.AdaptiveColor
+	MarkdownText() color.Color
+	MarkdownHeading() color.Color
+	MarkdownLink() color.Color
+	MarkdownLinkText() color.Color
+	MarkdownCode() color.Color
+	MarkdownBlockQuote() color.Color
+	MarkdownEmph() color.Color
+	MarkdownStrong() color.Color
+	MarkdownHorizontalRule() color.Color
+	MarkdownListItem() color.Color
+	MarkdownListEnumeration() color.Color
+	MarkdownImage() color.Color
+	MarkdownImageText() color.Color
+	MarkdownCodeBlock() color.Color
 
 	// Syntax highlighting colors
-	SyntaxComment() lipgloss.AdaptiveColor
-	SyntaxKeyword() lipgloss.AdaptiveColor
-	SyntaxFunction() lipgloss.AdaptiveColor
-	SyntaxVariable() lipgloss.AdaptiveColor
-	SyntaxString() lipgloss.AdaptiveColor
-	SyntaxNumber() lipgloss.AdaptiveColor
-	SyntaxType() lipgloss.AdaptiveColor
-	SyntaxOperator() lipgloss.AdaptiveColor
-	SyntaxPunctuation() lipgloss.AdaptiveColor
+	SyntaxComment() color.Color
+	SyntaxKeyword() color.Color
+	SyntaxFunction() color.Color
+	SyntaxVariable() color.Color
+	SyntaxString() color.Color
+	SyntaxNumber() color.Color
+	SyntaxType() color.Color
+	SyntaxOperator() color.Color
+	SyntaxPunctuation() color.Color
 }
 
 // BaseTheme provides a default implementation of the Theme interface
 // that can be embedded in concrete theme implementations.
 type BaseTheme struct {
 	// Base colors
-	PrimaryColor       lipgloss.AdaptiveColor
-	SecondaryColor     lipgloss.AdaptiveColor
-	AccentColor        lipgloss.AdaptiveColor
+	PrimaryColor   color.Color
+	SecondaryColor color.Color
+	AccentColor    color.Color
 
 	// Status colors
-	ErrorColor         lipgloss.AdaptiveColor
-	WarningColor       lipgloss.AdaptiveColor
-	SuccessColor       lipgloss.AdaptiveColor
-	InfoColor          lipgloss.AdaptiveColor
+	ErrorColor   color.Color
+	WarningColor color.Color
+	SuccessColor color.Color
+	InfoColor    color.Color
 
 	// Text colors
-	TextColor          lipgloss.AdaptiveColor
-	TextMutedColor     lipgloss.AdaptiveColor
-	TextEmphasizedColor lipgloss.AdaptiveColor
+	TextColor           color.Color
+	TextMutedColor      color.Color
+	TextEmphasizedColor color.Color
 
 	// Background colors
-	BackgroundColor    lipgloss.AdaptiveColor
-	BackgroundSecondaryColor lipgloss.AdaptiveColor
-	BackgroundDarkerColor lipgloss.AdaptiveColor
+	BackgroundColor          color.Color
+	BackgroundSecondaryColor color.Color
+	BackgroundDarkerColor    color.Color
 
 	// Border colors
-	BorderNormalColor  lipgloss.AdaptiveColor
-	BorderFocusedColor lipgloss.AdaptiveColor
-	BorderDimColor     lipgloss.AdaptiveColor
+	BorderNormalColor  color.Color
+	BorderFocusedColor color.Color
+	BorderDimColor     color.Color
 
 	// Diff view colors
-	DiffAddedColor     lipgloss.AdaptiveColor
-	DiffRemovedColor   lipgloss.AdaptiveColor
-	DiffContextColor   lipgloss.AdaptiveColor
-	DiffHunkHeaderColor lipgloss.AdaptiveColor
-	DiffHighlightAddedColor lipgloss.AdaptiveColor
-	DiffHighlightRemovedColor lipgloss.AdaptiveColor
-	DiffAddedBgColor   lipgloss.AdaptiveColor
-	DiffRemovedBgColor lipgloss.AdaptiveColor
-	DiffContextBgColor lipgloss.AdaptiveColor
-	DiffLineNumberColor lipgloss.AdaptiveColor
-	DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
-	DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
+	DiffAddedColor               color.Color
+	DiffRemovedColor             color.Color
+	DiffContextColor             color.Color
+	DiffHunkHeaderColor          color.Color
+	DiffHighlightAddedColor      color.Color
+	DiffHighlightRemovedColor    color.Color
+	DiffAddedBgColor             color.Color
+	DiffRemovedBgColor           color.Color
+	DiffContextBgColor           color.Color
+	DiffLineNumberColor          color.Color
+	DiffAddedLineNumberBgColor   color.Color
+	DiffRemovedLineNumberBgColor color.Color
 
 	// Markdown colors
-	MarkdownTextColor  lipgloss.AdaptiveColor
-	MarkdownHeadingColor lipgloss.AdaptiveColor
-	MarkdownLinkColor  lipgloss.AdaptiveColor
-	MarkdownLinkTextColor lipgloss.AdaptiveColor
-	MarkdownCodeColor  lipgloss.AdaptiveColor
-	MarkdownBlockQuoteColor lipgloss.AdaptiveColor
-	MarkdownEmphColor  lipgloss.AdaptiveColor
-	MarkdownStrongColor lipgloss.AdaptiveColor
-	MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
-	MarkdownListItemColor lipgloss.AdaptiveColor
-	MarkdownListEnumerationColor lipgloss.AdaptiveColor
-	MarkdownImageColor lipgloss.AdaptiveColor
-	MarkdownImageTextColor lipgloss.AdaptiveColor
-	MarkdownCodeBlockColor lipgloss.AdaptiveColor
+	MarkdownTextColor            color.Color
+	MarkdownHeadingColor         color.Color
+	MarkdownLinkColor            color.Color
+	MarkdownLinkTextColor        color.Color
+	MarkdownCodeColor            color.Color
+	MarkdownBlockQuoteColor      color.Color
+	MarkdownEmphColor            color.Color
+	MarkdownStrongColor          color.Color
+	MarkdownHorizontalRuleColor  color.Color
+	MarkdownListItemColor        color.Color
+	MarkdownListEnumerationColor color.Color
+	MarkdownImageColor           color.Color
+	MarkdownImageTextColor       color.Color
+	MarkdownCodeBlockColor       color.Color
 
 	// Syntax highlighting colors
-	SyntaxCommentColor lipgloss.AdaptiveColor
-	SyntaxKeywordColor lipgloss.AdaptiveColor
-	SyntaxFunctionColor lipgloss.AdaptiveColor
-	SyntaxVariableColor lipgloss.AdaptiveColor
-	SyntaxStringColor  lipgloss.AdaptiveColor
-	SyntaxNumberColor  lipgloss.AdaptiveColor
-	SyntaxTypeColor    lipgloss.AdaptiveColor
-	SyntaxOperatorColor lipgloss.AdaptiveColor
-	SyntaxPunctuationColor lipgloss.AdaptiveColor
+	SyntaxCommentColor     color.Color
+	SyntaxKeywordColor     color.Color
+	SyntaxFunctionColor    color.Color
+	SyntaxVariableColor    color.Color
+	SyntaxStringColor      color.Color
+	SyntaxNumberColor      color.Color
+	SyntaxTypeColor        color.Color
+	SyntaxOperatorColor    color.Color
+	SyntaxPunctuationColor color.Color
 }
 
 // Implement the Theme interface for BaseTheme
-func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
-func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
-func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
-
-func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
-func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
-func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
-func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
-
-func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
-func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
-func (t *BaseTheme) TextEmphasized() lipgloss.AdaptiveColor { return t.TextEmphasizedColor }
-
-func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
-func (t *BaseTheme) BackgroundSecondary() lipgloss.AdaptiveColor { return t.BackgroundSecondaryColor }
-func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
-
-func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
-func (t *BaseTheme) BorderFocused() lipgloss.AdaptiveColor { return t.BorderFocusedColor }
-func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
-
-func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
-func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
-func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
-func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
-func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
-func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
-func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
-func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
-func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
-func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
-func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffAddedLineNumberBgColor }
-func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffRemovedLineNumberBgColor }
-
-func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
-func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
-func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
-func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
-func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
-func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
-func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
-func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
-func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor { return t.MarkdownHorizontalRuleColor }
-func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
-func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor { return t.MarkdownListEnumerationColor }
-func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
-func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
-func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
-
-func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
-func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
-func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
-func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
-func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
-func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
-func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
-func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
-func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
+func (t *BaseTheme) Primary() color.Color   { return t.PrimaryColor }
+func (t *BaseTheme) Secondary() color.Color { return t.SecondaryColor }
+func (t *BaseTheme) Accent() color.Color    { return t.AccentColor }
+
+func (t *BaseTheme) Error() color.Color   { return t.ErrorColor }
+func (t *BaseTheme) Warning() color.Color { return t.WarningColor }
+func (t *BaseTheme) Success() color.Color { return t.SuccessColor }
+func (t *BaseTheme) Info() color.Color    { return t.InfoColor }
+
+func (t *BaseTheme) Text() color.Color           { return t.TextColor }
+func (t *BaseTheme) TextMuted() color.Color      { return t.TextMutedColor }
+func (t *BaseTheme) TextEmphasized() color.Color { return t.TextEmphasizedColor }
+
+func (t *BaseTheme) Background() color.Color          { return t.BackgroundColor }
+func (t *BaseTheme) BackgroundSecondary() color.Color { return t.BackgroundSecondaryColor }
+func (t *BaseTheme) BackgroundDarker() color.Color    { return t.BackgroundDarkerColor }
+
+func (t *BaseTheme) BorderNormal() color.Color  { return t.BorderNormalColor }
+func (t *BaseTheme) BorderFocused() color.Color { return t.BorderFocusedColor }
+func (t *BaseTheme) BorderDim() color.Color     { return t.BorderDimColor }
+
+func (t *BaseTheme) DiffAdded() color.Color               { return t.DiffAddedColor }
+func (t *BaseTheme) DiffRemoved() color.Color             { return t.DiffRemovedColor }
+func (t *BaseTheme) DiffContext() color.Color             { return t.DiffContextColor }
+func (t *BaseTheme) DiffHunkHeader() color.Color          { return t.DiffHunkHeaderColor }
+func (t *BaseTheme) DiffHighlightAdded() color.Color      { return t.DiffHighlightAddedColor }
+func (t *BaseTheme) DiffHighlightRemoved() color.Color    { return t.DiffHighlightRemovedColor }
+func (t *BaseTheme) DiffAddedBg() color.Color             { return t.DiffAddedBgColor }
+func (t *BaseTheme) DiffRemovedBg() color.Color           { return t.DiffRemovedBgColor }
+func (t *BaseTheme) DiffContextBg() color.Color           { return t.DiffContextBgColor }
+func (t *BaseTheme) DiffLineNumber() color.Color          { return t.DiffLineNumberColor }
+func (t *BaseTheme) DiffAddedLineNumberBg() color.Color   { return t.DiffAddedLineNumberBgColor }
+func (t *BaseTheme) DiffRemovedLineNumberBg() color.Color { return t.DiffRemovedLineNumberBgColor }
+
+func (t *BaseTheme) MarkdownText() color.Color            { return t.MarkdownTextColor }
+func (t *BaseTheme) MarkdownHeading() color.Color         { return t.MarkdownHeadingColor }
+func (t *BaseTheme) MarkdownLink() color.Color            { return t.MarkdownLinkColor }
+func (t *BaseTheme) MarkdownLinkText() color.Color        { return t.MarkdownLinkTextColor }
+func (t *BaseTheme) MarkdownCode() color.Color            { return t.MarkdownCodeColor }
+func (t *BaseTheme) MarkdownBlockQuote() color.Color      { return t.MarkdownBlockQuoteColor }
+func (t *BaseTheme) MarkdownEmph() color.Color            { return t.MarkdownEmphColor }
+func (t *BaseTheme) MarkdownStrong() color.Color          { return t.MarkdownStrongColor }
+func (t *BaseTheme) MarkdownHorizontalRule() color.Color  { return t.MarkdownHorizontalRuleColor }
+func (t *BaseTheme) MarkdownListItem() color.Color        { return t.MarkdownListItemColor }
+func (t *BaseTheme) MarkdownListEnumeration() color.Color { return t.MarkdownListEnumerationColor }
+func (t *BaseTheme) MarkdownImage() color.Color           { return t.MarkdownImageColor }
+func (t *BaseTheme) MarkdownImageText() color.Color       { return t.MarkdownImageTextColor }
+func (t *BaseTheme) MarkdownCodeBlock() color.Color       { return t.MarkdownCodeBlockColor }
+
+func (t *BaseTheme) SyntaxComment() color.Color     { return t.SyntaxCommentColor }
+func (t *BaseTheme) SyntaxKeyword() color.Color     { return t.SyntaxKeywordColor }
+func (t *BaseTheme) SyntaxFunction() color.Color    { return t.SyntaxFunctionColor }
+func (t *BaseTheme) SyntaxVariable() color.Color    { return t.SyntaxVariableColor }
+func (t *BaseTheme) SyntaxString() color.Color      { return t.SyntaxStringColor }
+func (t *BaseTheme) SyntaxNumber() color.Color      { return t.SyntaxNumberColor }
+func (t *BaseTheme) SyntaxType() color.Color        { return t.SyntaxTypeColor }
+func (t *BaseTheme) SyntaxOperator() color.Color    { return t.SyntaxOperatorColor }
+func (t *BaseTheme) SyntaxPunctuation() color.Color { return t.SyntaxPunctuationColor }

internal/tui/theme/tokyonight.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // TokyoNightTheme implements the Theme interface with Tokyo Night colors.
@@ -28,6 +28,80 @@ func NewTokyoNightTheme() *TokyoNightTheme {
 	darkPurple := "#c099ff"
 	darkBorder := "#3b4261"
 
+	theme := &TokyoNightTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(darkBlue)
+	theme.SecondaryColor = lipgloss.Color(darkPurple)
+	theme.AccentColor = lipgloss.Color(darkOrange)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkBlue)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#191B29") // Darker background from palette
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkBlue)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color("#4fd6be") // teal from palette
+	theme.DiffRemovedColor = lipgloss.Color("#c53b53") // red1 from palette
+	theme.DiffContextColor = lipgloss.Color("#828bb8") // fg_dark from palette
+	theme.DiffHunkHeaderColor = lipgloss.Color("#828bb8") // fg_dark from palette
+	theme.DiffHighlightAddedColor = lipgloss.Color("#b8db87") // git.add from palette
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#e26a75") // git.delete from palette
+	theme.DiffAddedBgColor = lipgloss.Color("#20303b")
+	theme.DiffRemovedBgColor = lipgloss.Color("#37222c")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#545c7e") // dark3 from palette
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#1b2b34")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#2d1f26")
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageColor = lipgloss.Color(darkBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkPurple)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkBlue)
+	theme.SyntaxVariableColor = lipgloss.Color(darkRed)
+	theme.SyntaxStringColor = lipgloss.Color(darkGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(darkOrange)
+	theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
+
+	return theme
+}
+
+// NewTokyoNightDayTheme creates a new instance of the Tokyo Night Day theme.
+func NewTokyoNightDayTheme() *TokyoNightTheme {
 	// Light mode colors (Tokyo Night Day)
 	lightBackground := "#e1e2e7"
 	lightCurrentLine := "#d5d6db"
@@ -46,229 +120,77 @@ func NewTokyoNightTheme() *TokyoNightTheme {
 	theme := &TokyoNightTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
+	theme.PrimaryColor = lipgloss.Color(lightBlue)
+	theme.SecondaryColor = lipgloss.Color(lightPurple)
+	theme.AccentColor = lipgloss.Color(lightOrange)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
+	theme.ErrorColor = lipgloss.Color(lightRed)
+	theme.WarningColor = lipgloss.Color(lightOrange)
+	theme.SuccessColor = lipgloss.Color(lightGreen)
+	theme.InfoColor = lipgloss.Color(lightBlue)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(lightForeground)
+	theme.TextMutedColor = lipgloss.Color(lightComment)
+	theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#191B29", // Darker background from palette
-		Light: "#f0f0f5", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(lightBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#f0f0f5") // Slightly lighter than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(lightBorder)
+	theme.BorderFocusedColor = lipgloss.Color(lightBlue)
+	theme.BorderDimColor = lipgloss.Color(lightSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#4fd6be", // teal from palette
-		Light: "#1e725c",
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#c53b53", // red1 from palette
-		Light: "#c53b53",
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  "#828bb8", // fg_dark from palette
-		Light: "#7086b5",
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  "#828bb8", // fg_dark from palette
-		Light: "#7086b5",
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#b8db87", // git.add from palette
-		Light: "#4db380",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#e26a75", // git.delete from palette
-		Light: "#f52a65",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#20303b",
-		Light: "#d5e5d5",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#37222c",
-		Light: "#f7d8db",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  "#545c7e", // dark3 from palette
-		Light: "#848cb5",
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#1b2b34",
-		Light: "#c5d5c5",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#2d1f26",
-		Light: "#e7c8cb",
-	}
+	theme.DiffAddedColor = lipgloss.Color("#1e725c")
+	theme.DiffRemovedColor = lipgloss.Color("#c53b53")
+	theme.DiffContextColor = lipgloss.Color("#7086b5")
+	theme.DiffHunkHeaderColor = lipgloss.Color("#7086b5")
+	theme.DiffHighlightAddedColor = lipgloss.Color("#4db380")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#f52a65")
+	theme.DiffAddedBgColor = lipgloss.Color("#d5e5d5")
+	theme.DiffRemovedBgColor = lipgloss.Color("#f7d8db")
+	theme.DiffContextBgColor = lipgloss.Color(lightBackground)
+	theme.DiffLineNumberColor = lipgloss.Color("#848cb5")
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c5d5c5")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#e7c8cb")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(lightForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
+	theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
+	theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
+	theme.MarkdownImageColor = lipgloss.Color(lightBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(lightComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
+	theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
+	theme.SyntaxVariableColor = lipgloss.Color(lightRed)
+	theme.SyntaxStringColor = lipgloss.Color(lightGreen)
+	theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
+	theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
+	theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
+	theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
 
 	return theme
 }
 
 func init() {
-	// Register the Tokyo Night theme with the theme manager
+	// Register the Tokyo Night themes with the theme manager
 	RegisterTheme("tokyonight", NewTokyoNightTheme())
+	RegisterTheme("tokyonight-day", NewTokyoNightDayTheme())
 }

internal/tui/theme/tron.go 🔗

@@ -1,7 +1,7 @@
 package theme
 
 import (
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/lipgloss/v2"
 )
 
 // TronTheme implements the Theme interface with Tron-inspired colors.
@@ -29,6 +29,80 @@ func NewTronTheme() *TronTheme {
 	darkGreen := "#00ff8f"
 	darkBorder := "#1a2633"
 
+	theme := &TronTheme{}
+
+	// Base colors
+	theme.PrimaryColor = lipgloss.Color(darkCyan)
+	theme.SecondaryColor = lipgloss.Color(darkBlue)
+	theme.AccentColor = lipgloss.Color(darkOrange)
+
+	// Status colors
+	theme.ErrorColor = lipgloss.Color(darkRed)
+	theme.WarningColor = lipgloss.Color(darkOrange)
+	theme.SuccessColor = lipgloss.Color(darkGreen)
+	theme.InfoColor = lipgloss.Color(darkCyan)
+
+	// Text colors
+	theme.TextColor = lipgloss.Color(darkForeground)
+	theme.TextMutedColor = lipgloss.Color(darkComment)
+	theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
+
+	// Background colors
+	theme.BackgroundColor = lipgloss.Color(darkBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#070d14") // Slightly darker than background
+
+	// Border colors
+	theme.BorderNormalColor = lipgloss.Color(darkBorder)
+	theme.BorderFocusedColor = lipgloss.Color(darkCyan)
+	theme.BorderDimColor = lipgloss.Color(darkSelection)
+
+	// Diff view colors
+	theme.DiffAddedColor = lipgloss.Color(darkGreen)
+	theme.DiffRemovedColor = lipgloss.Color(darkRed)
+	theme.DiffContextColor = lipgloss.Color(darkComment)
+	theme.DiffHunkHeaderColor = lipgloss.Color(darkBlue)
+	theme.DiffHighlightAddedColor = lipgloss.Color("#00ff8f")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#ff3333")
+	theme.DiffAddedBgColor = lipgloss.Color("#0a2a1a")
+	theme.DiffRemovedBgColor = lipgloss.Color("#2a0a0a")
+	theme.DiffContextBgColor = lipgloss.Color(darkBackground)
+	theme.DiffLineNumberColor = lipgloss.Color(darkComment)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#082015")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#200808")
+
+	// Markdown colors
+	theme.MarkdownTextColor = lipgloss.Color(darkForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(darkCyan)
+	theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
+	theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
+	theme.MarkdownImageColor = lipgloss.Color(darkBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
+
+	// Syntax highlighting colors
+	theme.SyntaxCommentColor = lipgloss.Color(darkComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(darkCyan)
+	theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
+	theme.SyntaxVariableColor = lipgloss.Color(darkOrange)
+	theme.SyntaxStringColor = lipgloss.Color(darkYellow)
+	theme.SyntaxNumberColor = lipgloss.Color(darkBlue)
+	theme.SyntaxTypeColor = lipgloss.Color(darkPurple)
+	theme.SyntaxOperatorColor = lipgloss.Color(darkPink)
+	theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
+
+	return theme
+}
+
+// NewTronLightTheme creates a new instance of the Tron Light theme.
+func NewTronLightTheme() *TronTheme {
 	// Light mode approximation
 	lightBackground := "#f0f8ff"
 	lightCurrentLine := "#e0f0ff"
@@ -48,229 +122,77 @@ func NewTronTheme() *TronTheme {
 	theme := &TronTheme{}
 
 	// Base colors
-	theme.PrimaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.AccentColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
+	theme.PrimaryColor = lipgloss.Color(lightCyan)
+	theme.SecondaryColor = lipgloss.Color(lightBlue)
+	theme.AccentColor = lipgloss.Color(lightOrange)
 
 	// Status colors
-	theme.ErrorColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.WarningColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SuccessColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.InfoColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
+	theme.ErrorColor = lipgloss.Color(lightRed)
+	theme.WarningColor = lipgloss.Color(lightOrange)
+	theme.SuccessColor = lipgloss.Color(lightGreen)
+	theme.InfoColor = lipgloss.Color(lightCyan)
 
 	// Text colors
-	theme.TextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.TextMutedColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
+	theme.TextColor = lipgloss.Color(lightForeground)
+	theme.TextMutedColor = lipgloss.Color(lightComment)
+	theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
 
 	// Background colors
-	theme.BackgroundColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
-		Dark:  darkCurrentLine,
-		Light: lightCurrentLine,
-	}
-	theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
-		Dark:  "#070d14", // Slightly darker than background
-		Light: "#ffffff", // Slightly lighter than background
-	}
+	theme.BackgroundColor = lipgloss.Color(lightBackground)
+	theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
+	theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
 
 	// Border colors
-	theme.BorderNormalColor = lipgloss.AdaptiveColor{
-		Dark:  darkBorder,
-		Light: lightBorder,
-	}
-	theme.BorderFocusedColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.BorderDimColor = lipgloss.AdaptiveColor{
-		Dark:  darkSelection,
-		Light: lightSelection,
-	}
+	theme.BorderNormalColor = lipgloss.Color(lightBorder)
+	theme.BorderFocusedColor = lipgloss.Color(lightCyan)
+	theme.BorderDimColor = lipgloss.Color(lightSelection)
 
 	// Diff view colors
-	theme.DiffAddedColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.DiffRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  darkRed,
-		Light: lightRed,
-	}
-	theme.DiffContextColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
-		Dark:  "#00ff8f",
-		Light: "#a5d6a7",
-	}
-	theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
-		Dark:  "#ff3333",
-		Light: "#ef9a9a",
-	}
-	theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#0a2a1a",
-		Light: "#e8f5e9",
-	}
-	theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#2a0a0a",
-		Light: "#ffebee",
-	}
-	theme.DiffContextBgColor = lipgloss.AdaptiveColor{
-		Dark:  darkBackground,
-		Light: lightBackground,
-	}
-	theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#082015",
-		Light: "#c8e6c9",
-	}
-	theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
-		Dark:  "#200808",
-		Light: "#ffcdd2",
-	}
+	theme.DiffAddedColor = lipgloss.Color(lightGreen)
+	theme.DiffRemovedColor = lipgloss.Color(lightRed)
+	theme.DiffContextColor = lipgloss.Color(lightComment)
+	theme.DiffHunkHeaderColor = lipgloss.Color(lightBlue)
+	theme.DiffHighlightAddedColor = lipgloss.Color("#a5d6a7")
+	theme.DiffHighlightRemovedColor = lipgloss.Color("#ef9a9a")
+	theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
+	theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
+	theme.DiffContextBgColor = lipgloss.Color(lightBackground)
+	theme.DiffLineNumberColor = lipgloss.Color(lightComment)
+	theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
+	theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
 
 	// Markdown colors
-	theme.MarkdownTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
-	theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownImageColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.MarkdownTextColor = lipgloss.Color(lightForeground)
+	theme.MarkdownHeadingColor = lipgloss.Color(lightCyan)
+	theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
+	theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
+	theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
+	theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
+	theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
+	theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
+	theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
+	theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
+	theme.MarkdownImageColor = lipgloss.Color(lightBlue)
+	theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
+	theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
 
 	// Syntax highlighting colors
-	theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
-		Dark:  darkComment,
-		Light: lightComment,
-	}
-	theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
-		Dark:  darkCyan,
-		Light: lightCyan,
-	}
-	theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
-		Dark:  darkGreen,
-		Light: lightGreen,
-	}
-	theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
-		Dark:  darkOrange,
-		Light: lightOrange,
-	}
-	theme.SyntaxStringColor = lipgloss.AdaptiveColor{
-		Dark:  darkYellow,
-		Light: lightYellow,
-	}
-	theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
-		Dark:  darkBlue,
-		Light: lightBlue,
-	}
-	theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
-		Dark:  darkPurple,
-		Light: lightPurple,
-	}
-	theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
-		Dark:  darkPink,
-		Light: lightPink,
-	}
-	theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
-		Dark:  darkForeground,
-		Light: lightForeground,
-	}
+	theme.SyntaxCommentColor = lipgloss.Color(lightComment)
+	theme.SyntaxKeywordColor = lipgloss.Color(lightCyan)
+	theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
+	theme.SyntaxVariableColor = lipgloss.Color(lightOrange)
+	theme.SyntaxStringColor = lipgloss.Color(lightYellow)
+	theme.SyntaxNumberColor = lipgloss.Color(lightBlue)
+	theme.SyntaxTypeColor = lipgloss.Color(lightPurple)
+	theme.SyntaxOperatorColor = lipgloss.Color(lightPink)
+	theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
 
 	return theme
 }
 
 func init() {
-	// Register the Tron theme with the theme manager
+	// Register the Tron themes with the theme manager
 	RegisterTheme("tron", NewTronTheme())
+	RegisterTheme("tron-light", NewTronLightTheme())
 }

internal/tui/tui.go 🔗

@@ -5,9 +5,9 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/charmbracelet/bubbles/key"
-	tea "github.com/charmbracelet/bubbletea"
-	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/bubbles/v2/key"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/opencode-ai/opencode/internal/app"
 	"github.com/opencode-ai/opencode/internal/config"
 	"github.com/opencode-ai/opencode/internal/llm/agent"
@@ -99,7 +99,7 @@ type appModel struct {
 	width, height   int
 	currentPage     page.PageID
 	previousPage    page.PageID
-	pages           map[page.PageID]tea.Model
+	pages           map[page.PageID]util.Model
 	loadedPages     map[page.PageID]bool
 	status          core.StatusCmp
 	app             *app.App
@@ -143,6 +143,8 @@ type appModel struct {
 func (a appModel) Init() tea.Cmd {
 	var cmds []tea.Cmd
 	cmd := a.pages[a.currentPage].Init()
+	t := theme.CurrentTheme()
+	cmds = append(cmds, tea.SetBackgroundColor(t.Background()))
 	a.loadedPages[a.currentPage] = true
 	cmds = append(cmds, cmd)
 	cmd = a.status.Init()
@@ -189,7 +191,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 		s, _ := a.status.Update(msg)
 		a.status = s.(core.StatusCmp)
-		a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+		updated, cmd := a.pages[a.currentPage].Update(msg)
+		a.pages[a.currentPage] = updated.(util.Model)
 		cmds = append(cmds, cmd)
 
 		prm, permCmd := a.permissions.Update(msg)
@@ -348,9 +351,11 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		return a, nil
 
 	case dialog.ThemeChangedMsg:
-		a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+		updated, cmd := a.pages[a.currentPage].Update(msg)
+		a.pages[a.currentPage] = updated.(util.Model)
 		a.showThemeDialog = false
-		return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName))
+		t := theme.CurrentTheme()
+		return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName), tea.SetBackgroundColor(t.Background()))
 
 	case dialog.CloseModelDialogMsg:
 		a.showModelDialog = false
@@ -427,7 +432,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		// If submitted, replace all named arguments and run the command
 		if msg.Submit {
 			content := msg.Content
-			
+
 			// Replace each named argument with its value
 			for name, value := range msg.Args {
 				placeholder := "$" + name
@@ -658,7 +663,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 	s, _ := a.status.Update(msg)
 	a.status = s.(core.StatusCmp)
-	a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+	updated, cmd := a.pages[a.currentPage].Update(msg)
+	a.pages[a.currentPage] = updated.(util.Model)
 	cmds = append(cmds, cmd)
 	return a, tea.Batch(cmds...)
 }
@@ -914,7 +920,7 @@ func New(app *app.App) tea.Model {
 		themeDialog:   dialog.NewThemeDialogCmp(),
 		app:           app,
 		commands:      []dialog.Command{},
-		pages: map[page.PageID]tea.Model{
+		pages: map[page.PageID]util.Model{
 			page.ChatPage: page.NewChatPage(app),
 			page.LogsPage: page.NewLogsPage(),
 		},

internal/tui/util/util.go 🔗

@@ -3,9 +3,14 @@ package util
 import (
 	"time"
 
-	tea "github.com/charmbracelet/bubbletea"
+	tea "github.com/charmbracelet/bubbletea/v2"
 )
 
+type Model interface {
+	tea.Model
+	tea.ViewModel
+}
+
 func CmdHandler(msg tea.Msg) tea.Cmd {
 	return func() tea.Msg {
 		return msg