clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

feat: upgrade to bubbletea v2, bubbles v2, lipgloss v2

Dami committed 4603a95
Migrate to charm.land/bubbletea/v2 (RC2), charm.land/bubbles/v2 (RC1),
and charm.land/lipgloss/v2 (beta3).

Breaking API changes addressed:
- Import paths: github.com/charmbracelet/* -> charm.land/*/v2
- Root View() returns tea.View with AltScreen declared, sub-models
  keep returning string via game.Gamer interface
- lipgloss.AdaptiveColor -> compat.AdaptiveColor with lipgloss.Color()
  wrapped values for v2 color.Color interface compliance
- lipgloss.TerminalColor -> compat.AdaptiveColor (nonogram)
- viewport.New() now uses functional options (WithWidth/WithHeight)
- viewport Width/Height fields -> SetWidth()/SetHeight() methods
- tea.KeyMsg -> tea.KeyPressMsg in tests, Key struct fields changed
- WithAltScreen() program option -> declarative v.AltScreen in View()

When charmbracelet releases stable v2, update go.mod versions from
RC/beta to stable -- no code changes expected.
commit
4603a9566fa77edbd52d5042580bc759bd632cb8
parent
0cd14ad12c4221dbf67ca4be65481aa36bd1bcf3
author
Dami <dami.etoile@gmail.com>
53 files changed, +326 -286
Mcmd.go2+-
Mdaily/daily.go2+-
Mgame/border.go15++++--
Mgame/cursor.go4+-
Mgame/game_test.go18++++----
Mgame/gamer.go6+-
Mgame/keys.go2+-
Mgame/style.go21++++----
Mgo.mod32+++++++------
Mgo.sum67+++++++++++++++------------
Mhashiwokakero/Gamemode.go2+-
Mhashiwokakero/Model.go6+-
Mhashiwokakero/keys.go2+-
Mhashiwokakero/style.go33+++++++------
Mhitori/Gamemode.go2+-
Mhitori/Model.go6+-
Mhitori/keys.go2+-
Mhitori/style.go21++++----
Mkeys.go2+-
Mlightsout/Gamemode.go2+-
Mlightsout/Model.go6+-
Mlightsout/keys.go2+-
Mlightsout/style.go15+++---
Mmodel.go12++--
Mnonogram/Gamemode.go2+-
Mnonogram/Model.go6+-
Mnonogram/keys.go2+-
Mnonogram/style.go31++++++------
Mresolve/resolve.go2+-
Mresolve/resolve_test.go2+-
Mshikaku/Gamemode.go2+-
Mshikaku/Model.go6+-
Mshikaku/keys.go2+-
Mshikaku/style.go75+++++++++++++++---------------
Mspawn.go2+-
Msudoku/Gamemode.go2+-
Msudoku/Model.go6+-
Msudoku/keys.go2+-
Msudoku/style.go25+++++-----
Mtakuzu/Gamemode.go2+-
Mtakuzu/Model.go6+-
Mtakuzu/keys.go2+-
Mtakuzu/style.go19++++----
Mui/list.go7++-
Mui/style.go19++++---
Mui/table.go7++-
Mui/ui_test.go2+-
Mupdate.go12++--
Mview.go52++++++++++++--------
Mwordsearch/Gamemode.go2+-
Mwordsearch/Model.go4+-
Mwordsearch/keys.go2+-
Mwordsearch/style.go27++++++-----
M cmd.go +1 -1
M daily/daily.go +1 -1
M game/border.go +9 -6
M game/cursor.go +2 -2
M game/game_test.go +9 -9
@@ -4,7 +4,7 @@ import (
44 "strings"55 "testing"66 7- tea "github.com/charmbracelet/bubbletea"7+ tea "charm.land/bubbletea/v2"88 )99 1010 // --- Cursor.Move (P0) ---
@@ -12,11 +12,11 @@ import (
1212 func TestCursorMove(t *testing.T) {1313 keys := DefaultCursorKeyMap1414 15- keyMsg := func(k string) tea.KeyMsg {16- return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune(k)}15+ keyMsg := func(k string) tea.KeyPressMsg {16+ return tea.KeyPressMsg{Code: rune(k[0]), Text: k}1717 }18- specialKeyMsg := func(k tea.KeyType) tea.KeyMsg {19- return tea.KeyMsg{Type: k}18+ specialKeyMsg := func(k rune) tea.KeyPressMsg {19+ return tea.KeyPressMsg{Code: k}2020 }2121 2222 t.Run("movement within bounds", func(t *testing.T) {
@@ -24,7 +24,7 @@ func TestCursorMove(t *testing.T) {
2424 name string2525 startX int2626 startY int27- msg tea.KeyMsg27+ msg tea.KeyPressMsg2828 maxX int2929 maxY int3030 wantX int
@@ -56,7 +56,7 @@ func TestCursorMove(t *testing.T) {
5656 name string5757 startX int5858 startY int59- msg tea.KeyMsg59+ msg tea.KeyPressMsg6060 maxX int6161 maxY int6262 }{
@@ -81,7 +81,7 @@ func TestCursorMove(t *testing.T) {
8181 })8282 8383 t.Run("1x1 grid no movement", func(t *testing.T) {84- directions := []tea.KeyMsg{84+ directions := []tea.KeyPressMsg{8585 specialKeyMsg(tea.KeyUp),8686 specialKeyMsg(tea.KeyDown),8787 specialKeyMsg(tea.KeyLeft),
@@ -101,7 +101,7 @@ func TestCursorMove(t *testing.T) {
101101 102102 t.Run("arrow keys work", func(t *testing.T) {103103 tests := []struct {104- msg tea.KeyMsg104+ msg tea.KeyPressMsg105105 wantX int106106 wantY int107107 }{
M game/gamer.go +3 -3
M game/keys.go +1 -1
M game/style.go +11 -10
@@ -4,29 +4,30 @@ import (
44 "fmt"55 "strings"66 7- "github.com/charmbracelet/lipgloss"7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"89 )910 1011 // Shared cursor color tokens, used both in style construction and for1112 // composite styling where a cursor color is applied on top of another style.1213 var (13- CursorFG = lipgloss.AdaptiveColor{Light: "255", Dark: "235"}14- CursorBG = lipgloss.AdaptiveColor{Light: "130", Dark: "173"}15- CursorWarmBG = lipgloss.AdaptiveColor{Light: "130", Dark: "214"}16- ConflictFG = lipgloss.AdaptiveColor{Light: "160", Dark: "167"}17- ConflictBG = lipgloss.AdaptiveColor{Light: "224", Dark: "52"}14+ CursorFG = compat.AdaptiveColor{Light: lipgloss.Color("255"), Dark: lipgloss.Color("235")}15+ CursorBG = compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("173")}16+ CursorWarmBG = compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("214")}17+ ConflictFG = compat.AdaptiveColor{Light: lipgloss.Color("160"), Dark: lipgloss.Color("167")}18+ ConflictBG = compat.AdaptiveColor{Light: lipgloss.Color("224"), Dark: lipgloss.Color("52")}1819 )1920 2021 var (2122 titleStyle = lipgloss.NewStyle().2223 Bold(true).23- Foreground(lipgloss.AdaptiveColor{Light: "255", Dark: "255"}).24+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("255"), Dark: lipgloss.Color("255")}).2425 Background(CursorBG).2526 Padding(0, 1)2627 2728 solvedBadgeStyle = lipgloss.NewStyle().2829 Bold(true).29- Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "78"})30+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("28"), Dark: lipgloss.Color("78")})3031 3132 // CursorStyle highlights the cursor position with an accent background.3233 // Used by lightsout, sudoku, wordsearch.
@@ -47,11 +48,11 @@ var (
4748 CursorSolvedStyle = lipgloss.NewStyle().4849 Bold(true).4950 Foreground(CursorFG).50- Background(lipgloss.AdaptiveColor{Light: "28", Dark: "28"})51+ Background(compat.AdaptiveColor{Light: lipgloss.Color("28"), Dark: lipgloss.Color("28")})5152 5253 // StatusBarStyle is the shared style for the status/help bar below each puzzle grid.5354 StatusBarStyle = lipgloss.NewStyle().54- Foreground(lipgloss.AdaptiveColor{Light: "244", Dark: "244"}).55+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("244"), Dark: lipgloss.Color("244")}).5556 MarginTop(1)5657 )5758
M go.mod +18 -14
@@ -3,7 +3,9 @@ module github.com/FelineStateMachine/puzzletea
33 go 1.24.544 55 require (6- github.com/charmbracelet/bubbletea v1.3.66+ charm.land/bubbles/v2 v2.0.0-rc.17+ charm.land/bubbletea/v2 v2.0.0-rc.28+ charm.land/lipgloss/v2 v2.0.0-beta.3.0.20260212100304-e18737634dea79 github.com/spf13/cobra v1.10.2810 modernc.org/sqlite v1.44.3911 )
@@ -12,7 +14,14 @@ require (
1214 github.com/alecthomas/chroma/v2 v2.14.0 // indirect1315 github.com/atotto/clipboard v0.1.4 // indirect1416 github.com/aymerick/douceur v0.2.0 // indirect17+ github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect18+ github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect1519 github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect20+ github.com/charmbracelet/x/termios v0.1.1 // indirect21+ github.com/charmbracelet/x/windows v0.2.2 // indirect22+ github.com/clipperhouse/displaywidth v0.9.0 // indirect23+ github.com/clipperhouse/stringish v0.1.1 // indirect24+ github.com/clipperhouse/uax29/v2 v2.5.0 // indirect1625 github.com/dlclark/regexp2 v1.11.0 // indirect1726 github.com/dustin/go-humanize v1.0.1 // indirect1827 github.com/google/uuid v1.6.0 // indirect
@@ -35,25 +44,20 @@ require (
3544 3645 require (3746 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect38- github.com/charmbracelet/bubbles v0.21.039- github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect47+ github.com/charmbracelet/colorprofile v0.4.2 // indirect4048 github.com/charmbracelet/glamour v0.10.041- github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c66083442- github.com/charmbracelet/x/ansi v0.9.3 // indirect43- github.com/charmbracelet/x/cellbuf v0.0.13 // indirect44- github.com/charmbracelet/x/term v0.2.1 // indirect45- github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect46- github.com/lucasb-eyer/go-colorful v1.2.0 // indirect49+ github.com/charmbracelet/x/ansi v0.11.6 // indirect50+ github.com/charmbracelet/x/cellbuf v0.0.15 // indirect51+ github.com/charmbracelet/x/term v0.2.2 // indirect52+ github.com/lucasb-eyer/go-colorful v1.3.0 // indirect4753 github.com/mattn/go-isatty v0.0.20 // indirect48- github.com/mattn/go-localereader v0.0.1 // indirect49- github.com/mattn/go-runewidth v0.0.16 // indirect50- github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect54+ github.com/mattn/go-runewidth v0.0.19 // indirect5155 github.com/muesli/cancelreader v0.2.2 // indirect5256 github.com/muesli/termenv v0.16.0 // indirect5357 github.com/rivo/uniseg v0.4.7 // indirect5458 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect5559 golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect56- golang.org/x/sync v0.17.0 // indirect57- golang.org/x/sys v0.37.0 // indirect60+ golang.org/x/sync v0.18.0 // indirect61+ golang.org/x/sys v0.41.0 // indirect5862 golang.org/x/text v0.24.0 // indirect5963 )
M go.sum +38 -29
@@ -1,3 +1,9 @@
1+charm.land/bubbles/v2 v2.0.0-rc.1 h1:EiIFVAc3Zi/yY86td+79mPhHR7AqZ1OxF+6ztpOCRaM=2+charm.land/bubbles/v2 v2.0.0-rc.1/go.mod h1:5AbN6cEd/47gkEf8TgiQ2O3RZ5QxMS14l9W+7F9fPC4=3+charm.land/bubbletea/v2 v2.0.0-rc.2 h1:TdTbUOFzbufDJmSz/3gomL6q+fR6HwfY+P13hXQzD7k=4+charm.land/bubbletea/v2 v2.0.0-rc.2/go.mod h1:IXFmnCnMLTWw/KQ9rEatSYqbAPAYi8kA3Yqwa1SFnLk=5+charm.land/lipgloss/v2 v2.0.0-beta.3.0.20260212100304-e18737634dea h1:XBmpGhIKPN8o9VjuXg+X5WXFsEqUs/YtPx0Q0zzmTTA=6+charm.land/lipgloss/v2 v2.0.0-beta.3.0.20260212100304-e18737634dea/go.mod h1:xylWHUuJWcFJqoGrKdZP8Z0y3THC6xqrnfl1IYDviTE=17 github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=28 github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=39 github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
@@ -8,37 +14,45 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
814 github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=915 github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=1016 github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=11-github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=12-github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=17+github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY=18+github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E=1319 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=1420 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=15-github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=16-github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=17-github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU=18-github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc=19-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=20-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=21+github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY=22+github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8=2123 github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY=2224 github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk=2325 github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE=2426 github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA=25-github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0=26-github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=27+github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 h1:OqDqxQZliC7C8adA7KjelW3OjtAxREfeHkNcd66wpeI=28+github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318/go.mod h1:Y6kE2GzHfkyQQVCSL9r2hwokSrIlHGzZG+71+wDYSZI=29+github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=30+github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=2731 github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=2832 github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=29-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=30-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=33+github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=34+github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=35+github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA=36+github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I=3137 github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=3238 github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=33-github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=34-github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=39+github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=40+github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=41+github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY=42+github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo=43+github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM=44+github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k=45+github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=46+github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=47+github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=48+github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=49+github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=50+github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=3551 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=3652 github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=3753 github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=3854 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=3955 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=40-github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=41-github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=4256 github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=4357 github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=4458 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -53,19 +67,15 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
5367 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=5468 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=5569 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=56-github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=57-github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=70+github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=71+github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=5872 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=5973 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=60-github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=61-github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=6274 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=63-github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=64-github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=75+github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=76+github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=6577 github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=6678 github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=67-github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=68-github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=6979 github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=7080 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=7181 github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
@@ -101,12 +111,11 @@ golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
101111 golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=102112 golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=103113 golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=104-golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=105-golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=106-golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=114+golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=115+golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=107116 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=108-golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=109-golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=117+golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=118+golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=110119 golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=111120 golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=112121 golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
M hashiwokakero/Gamemode.go +1 -1
M hashiwokakero/Model.go +3 -3
M hashiwokakero/keys.go +1 -1
M hashiwokakero/style.go +17 -16
@@ -4,29 +4,30 @@ import (
44 "fmt"55 "strings"66 7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"79 "github.com/FelineStateMachine/puzzletea/game"8- "github.com/charmbracelet/lipgloss"910 )1011 1112 const cellWidth = 31213 1314 // Color palette — warm earth-tone theme (ANSI 256, adaptive for light/dark terminals)1415 var (15- colorIslandFg = lipgloss.AdaptiveColor{Dark: "236", Light: "187"}16- colorIslandBg = lipgloss.AdaptiveColor{Dark: "187", Light: "58"}17- colorSatisfiedFg = lipgloss.AdaptiveColor{Dark: "22", Light: "149"}18- colorSatisfiedBg = lipgloss.AdaptiveColor{Dark: "194", Light: "236"}19- colorOverFg = lipgloss.AdaptiveColor{Dark: "160", Light: "167"}20- colorOverBg = lipgloss.AdaptiveColor{Dark: "224", Light: "52"}21- colorSelectedFg = lipgloss.AdaptiveColor{Dark: "255", Light: "235"}22- colorSelectedBg = lipgloss.AdaptiveColor{Dark: "172", Light: "179"}23- colorAdjacentBg = lipgloss.AdaptiveColor{Dark: "223", Light: "58"}24- colorBridge = lipgloss.AdaptiveColor{Dark: "137", Light: "137"}25- colorBridgeSolved = lipgloss.AdaptiveColor{Dark: "22", Light: "149"}26- colorEmptyDot = lipgloss.AdaptiveColor{Dark: "252", Light: "239"}27- colorEmptySolved = lipgloss.AdaptiveColor{Dark: "151", Light: "107"}28- colorInfoSatisfied = lipgloss.AdaptiveColor{Dark: "22", Light: "149"}29- colorInfoText = lipgloss.AdaptiveColor{Dark: "137", Light: "137"}16+ colorIslandFg = compat.AdaptiveColor{Dark: lipgloss.Color("236"), Light: lipgloss.Color("187")}17+ colorIslandBg = compat.AdaptiveColor{Dark: lipgloss.Color("187"), Light: lipgloss.Color("58")}18+ colorSatisfiedFg = compat.AdaptiveColor{Dark: lipgloss.Color("22"), Light: lipgloss.Color("149")}19+ colorSatisfiedBg = compat.AdaptiveColor{Dark: lipgloss.Color("194"), Light: lipgloss.Color("236")}20+ colorOverFg = compat.AdaptiveColor{Dark: lipgloss.Color("160"), Light: lipgloss.Color("167")}21+ colorOverBg = compat.AdaptiveColor{Dark: lipgloss.Color("224"), Light: lipgloss.Color("52")}22+ colorSelectedFg = compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("235")}23+ colorSelectedBg = compat.AdaptiveColor{Dark: lipgloss.Color("172"), Light: lipgloss.Color("179")}24+ colorAdjacentBg = compat.AdaptiveColor{Dark: lipgloss.Color("223"), Light: lipgloss.Color("58")}25+ colorBridge = compat.AdaptiveColor{Dark: lipgloss.Color("137"), Light: lipgloss.Color("137")}26+ colorBridgeSolved = compat.AdaptiveColor{Dark: lipgloss.Color("22"), Light: lipgloss.Color("149")}27+ colorEmptyDot = compat.AdaptiveColor{Dark: lipgloss.Color("252"), Light: lipgloss.Color("239")}28+ colorEmptySolved = compat.AdaptiveColor{Dark: lipgloss.Color("151"), Light: lipgloss.Color("107")}29+ colorInfoSatisfied = compat.AdaptiveColor{Dark: lipgloss.Color("22"), Light: lipgloss.Color("149")}30+ colorInfoText = compat.AdaptiveColor{Dark: lipgloss.Color("137"), Light: lipgloss.Color("137")}3031 )3132 3233 var (
M hitori/Gamemode.go +1 -1
M hitori/Model.go +3 -3
M hitori/keys.go +1 -1
M hitori/style.go +11 -10
@@ -5,31 +5,32 @@ import (
55 66 "github.com/FelineStateMachine/puzzletea/game"77 8- "github.com/charmbracelet/lipgloss"8+ "charm.land/lipgloss/v2"9+ "charm.land/lipgloss/v2/compat"910 )1011 1112 var (1213 baseStyle = lipgloss.NewStyle()13- backgroundColor = lipgloss.AdaptiveColor{Light: "254", Dark: "235"}14+ backgroundColor = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("235")}1415 1516 numberStyle = baseStyle.16- Foreground(lipgloss.AdaptiveColor{Light: "236", Dark: "250"}).17+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("236"), Dark: lipgloss.Color("250")}).1718 Background(backgroundColor)1819 1920 shadedStyle = baseStyle.20- Foreground(lipgloss.AdaptiveColor{Light: "254", Dark: "238"}).21- Background(lipgloss.AdaptiveColor{Light: "240", Dark: "238"})21+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("238")}).22+ Background(compat.AdaptiveColor{Light: lipgloss.Color("240"), Dark: lipgloss.Color("238")})2223 2324 circledStyle = baseStyle.24- Foreground(lipgloss.AdaptiveColor{Light: "25", Dark: "75"}).25+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("25"), Dark: lipgloss.Color("75")}).2526 Background(backgroundColor)2627 2728 cursorSolvedStyle = game.CursorSolvedStyle2829 29- crosshairBG = lipgloss.AdaptiveColor{Light: "254", Dark: "237"}30- solvedBG = lipgloss.AdaptiveColor{Light: "151", Dark: "22"}30+ crosshairBG = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("237")}31+ solvedBG = compat.AdaptiveColor{Light: lipgloss.Color("151"), Dark: lipgloss.Color("22")}3132 32- borderFG = lipgloss.AdaptiveColor{Light: "250", Dark: "240"}33+ borderFG = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}3334 )3435 3536 const cellWidth = 3
@@ -73,7 +74,7 @@ var gridBorderColors = game.GridBorderColors{
7374 BorderFG: borderFG,7475 BackgroundBG: backgroundColor,7576 CrosshairBG: crosshairBG,76- SolvedBorderFG: lipgloss.AdaptiveColor{Light: "22", Dark: "149"},77+ SolvedBorderFG: compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")},7778 SolvedBG: solvedBG,7879 }7980
M keys.go +1 -1
M lightsout/Gamemode.go +1 -1
M lightsout/Model.go +3 -3
M lightsout/keys.go +1 -1
M lightsout/style.go +8 -7
@@ -3,15 +3,16 @@ package lightsout
33 import (44 "strings"55 6+ "charm.land/lipgloss/v2"7+ "charm.land/lipgloss/v2/compat"68 "github.com/FelineStateMachine/puzzletea/game"7- "github.com/charmbracelet/lipgloss"89 )910 1011 var (1112 baseStyle = lipgloss.NewStyle()1213 13- colorOn = lipgloss.AdaptiveColor{Light: "222", Dark: "180"}14- colorOff = lipgloss.AdaptiveColor{Light: "254", Dark: "236"}14+ colorOn = compat.AdaptiveColor{Light: lipgloss.Color("222"), Dark: lipgloss.Color("180")}15+ colorOff = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("236")}1516 1617 styleOn = baseStyle.1718 Background(colorOn)
@@ -23,17 +24,17 @@ var (
2324 cursorSolvedStyle = game.CursorSolvedStyle2425 2526 solvedStyle = baseStyle.26- Background(lipgloss.AdaptiveColor{Light: "151", Dark: "22"})27+ Background(compat.AdaptiveColor{Light: lipgloss.Color("151"), Dark: lipgloss.Color("22")})2728 2829 gridBorderStyle = lipgloss.NewStyle().2930 Border(lipgloss.RoundedBorder()).30- BorderForeground(lipgloss.AdaptiveColor{Light: "250", Dark: "240"}).31+ BorderForeground(compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}).3132 BorderBackground(colorOff)3233 3334 gridBorderSolvedStyle = lipgloss.NewStyle().3435 Border(lipgloss.RoundedBorder()).35- BorderForeground(lipgloss.AdaptiveColor{Light: "22", Dark: "149"}).36- BorderBackground(lipgloss.AdaptiveColor{Light: "151", Dark: "22"})36+ BorderForeground(compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")}).37+ BorderBackground(compat.AdaptiveColor{Light: lipgloss.Color("151"), Dark: lipgloss.Color("22")})3738 )3839 3940 const (
M model.go +6 -6
M nonogram/Gamemode.go +1 -1
M nonogram/Model.go +3 -3
M nonogram/keys.go +1 -1
M nonogram/style.go +16 -15
@@ -4,40 +4,41 @@ import (
44 "fmt"55 "strings"66 7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"79 "github.com/FelineStateMachine/puzzletea/game"8- "github.com/charmbracelet/lipgloss"910 )1011 1112 var (1213 baseStyle = lipgloss.NewStyle()13- backgroundColor = lipgloss.AdaptiveColor{Light: "254", Dark: "235"}14+ backgroundColor = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("235")}1415 1516 filledStyle = baseStyle.16- Foreground(lipgloss.AdaptiveColor{Light: "130", Dark: "222"}).17- Background(lipgloss.AdaptiveColor{Light: "223", Dark: "58"})17+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("222")}).18+ Background(compat.AdaptiveColor{Light: lipgloss.Color("223"), Dark: lipgloss.Color("58")})1819 1920 markedStyle = baseStyle.20- Foreground(lipgloss.AdaptiveColor{Light: "131", Dark: "173"}).21- Background(lipgloss.AdaptiveColor{Light: "224", Dark: "236"})21+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("131"), Dark: lipgloss.Color("173")}).22+ Background(compat.AdaptiveColor{Light: lipgloss.Color("224"), Dark: lipgloss.Color("236")})2223 2324 emptyStyle = baseStyle.24- Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "240"}).25+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}).2526 Background(backgroundColor)2627 2728 cursorStyle = game.CursorWarmStyle2829 cursorSolvedStyle = game.CursorSolvedStyle2930 30- crosshairBG = lipgloss.AdaptiveColor{Light: "254", Dark: "237"}31- crosshairFilledBG = lipgloss.AdaptiveColor{Light: "223", Dark: "100"}32- solvedBG = lipgloss.AdaptiveColor{Light: "151", Dark: "22"}31+ crosshairBG = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("237")}32+ crosshairFilledBG = compat.AdaptiveColor{Light: lipgloss.Color("223"), Dark: lipgloss.Color("100")}33+ solvedBG = compat.AdaptiveColor{Light: lipgloss.Color("151"), Dark: lipgloss.Color("22")}3334 3435 hintStyle = baseStyle.35- Foreground(lipgloss.AdaptiveColor{Light: "137", Dark: "137"})36+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("137"), Dark: lipgloss.Color("137")})3637 3738 hintSatisfiedStyle = baseStyle.38- Foreground(lipgloss.AdaptiveColor{Light: "22", Dark: "149"})39+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")})3940 40- separatorFG = lipgloss.AdaptiveColor{Light: "250", Dark: "240"}41+ separatorFG = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}4142 )4243 4344 const (
@@ -70,7 +71,7 @@ func needsSpacer(i, n int) bool {
7071 // hSeparator builds a horizontal separator row using box-drawing characters.7172 // w is the number of grid columns. cursorX is the cursor column (-1 to disable crosshair).7273 // bg is the default background, crossBG is the crosshair-highlighted background.73-func hSeparator(w, cursorX int, bg, crossBG lipgloss.TerminalColor) string {74+func hSeparator(w, cursorX int, bg, crossBG compat.AdaptiveColor) string {7475 defStyle := baseStyle.Foreground(separatorFG).Background(bg)7576 highStyle := baseStyle.Foreground(separatorFG).Background(crossBG)7677 segment := strings.Repeat("─", cellWidth)
@@ -184,7 +185,7 @@ func gridView(g grid, c game.Cursor, solved bool) string {
184185 sepStyle := baseStyle.Foreground(separatorFG)185186 186187 // Determine background for horizontal separators (matches grid background).187- var gridBG lipgloss.TerminalColor = backgroundColor188+ gridBG := backgroundColor188189 if solved {189190 gridBG = solvedBG190191 }
M resolve/resolve.go +1 -1
M resolve/resolve_test.go +1 -1
M shikaku/Gamemode.go +1 -1
M shikaku/Model.go +3 -3
M shikaku/keys.go +1 -1
M shikaku/style.go +38 -37
@@ -4,53 +4,54 @@ import (
44 "fmt"55 "strings"66 7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"79 "github.com/FelineStateMachine/puzzletea/game"8- "github.com/charmbracelet/lipgloss"910 )1011 1112 const cellWidth = 31213 1314 // 16-color palette for placed rectangles (ANSI 256).14-var rectColors = []lipgloss.AdaptiveColor{15- {Dark: "60", Light: "60"}, // muted purple16- {Dark: "66", Light: "66"}, // teal17- {Dark: "95", Light: "95"}, // mauve18- {Dark: "130", Light: "130"}, // brown/amber19- {Dark: "71", Light: "71"}, // olive green20- {Dark: "132", Light: "132"}, // dusty rose21- {Dark: "37", Light: "37"}, // cyan22- {Dark: "136", Light: "136"}, // dark gold23- {Dark: "97", Light: "97"}, // plum24- {Dark: "29", Light: "29"}, // forest green25- {Dark: "167", Light: "167"}, // salmon26- {Dark: "68", Light: "68"}, // steel blue27- {Dark: "94", Light: "94"}, // rust28- {Dark: "139", Light: "139"}, // lavender29- {Dark: "28", Light: "28"}, // deep green30- {Dark: "133", Light: "133"}, // orchid15+var rectColors = []compat.AdaptiveColor{16+ {Dark: lipgloss.Color("60"), Light: lipgloss.Color("60")}, // muted purple17+ {Dark: lipgloss.Color("66"), Light: lipgloss.Color("66")}, // teal18+ {Dark: lipgloss.Color("95"), Light: lipgloss.Color("95")}, // mauve19+ {Dark: lipgloss.Color("130"), Light: lipgloss.Color("130")}, // brown/amber20+ {Dark: lipgloss.Color("71"), Light: lipgloss.Color("71")}, // olive green21+ {Dark: lipgloss.Color("132"), Light: lipgloss.Color("132")}, // dusty rose22+ {Dark: lipgloss.Color("37"), Light: lipgloss.Color("37")}, // cyan23+ {Dark: lipgloss.Color("136"), Light: lipgloss.Color("136")}, // dark gold24+ {Dark: lipgloss.Color("97"), Light: lipgloss.Color("97")}, // plum25+ {Dark: lipgloss.Color("29"), Light: lipgloss.Color("29")}, // forest green26+ {Dark: lipgloss.Color("167"), Light: lipgloss.Color("167")}, // salmon27+ {Dark: lipgloss.Color("68"), Light: lipgloss.Color("68")}, // steel blue28+ {Dark: lipgloss.Color("94"), Light: lipgloss.Color("94")}, // rust29+ {Dark: lipgloss.Color("139"), Light: lipgloss.Color("139")}, // lavender30+ {Dark: lipgloss.Color("28"), Light: lipgloss.Color("28")}, // deep green31+ {Dark: lipgloss.Color("133"), Light: lipgloss.Color("133")}, // orchid3132 }3233 3334 var (3435 baseStyle = lipgloss.NewStyle()3536 36- emptyDotColor = lipgloss.AdaptiveColor{Dark: "242", Light: "249"}37- clueColor = lipgloss.AdaptiveColor{Dark: "230", Light: "236"}38- clueBgColor = lipgloss.AdaptiveColor{Dark: "238", Light: "254"}37+ emptyDotColor = compat.AdaptiveColor{Dark: lipgloss.Color("242"), Light: lipgloss.Color("249")}38+ clueColor = compat.AdaptiveColor{Dark: lipgloss.Color("230"), Light: lipgloss.Color("236")}39+ clueBgColor = compat.AdaptiveColor{Dark: lipgloss.Color("238"), Light: lipgloss.Color("254")}3940 40- cursorBgColor = lipgloss.AdaptiveColor{Dark: "214", Light: "173"}41- cursorFgColor = lipgloss.AdaptiveColor{Dark: "235", Light: "255"}41+ cursorBgColor = compat.AdaptiveColor{Dark: lipgloss.Color("214"), Light: lipgloss.Color("173")}42+ cursorFgColor = compat.AdaptiveColor{Dark: lipgloss.Color("235"), Light: lipgloss.Color("255")}4243 43- previewGoodBg = lipgloss.AdaptiveColor{Dark: "28", Light: "157"}44- previewBadBg = lipgloss.AdaptiveColor{Dark: "124", Light: "217"}44+ previewGoodBg = compat.AdaptiveColor{Dark: lipgloss.Color("28"), Light: lipgloss.Color("157")}45+ previewBadBg = compat.AdaptiveColor{Dark: lipgloss.Color("124"), Light: lipgloss.Color("217")}4546 46- solvedBg = lipgloss.AdaptiveColor{Dark: "22", Light: "151"}47- solvedBorder = lipgloss.AdaptiveColor{Dark: "149", Light: "22"}48- borderColor = lipgloss.AdaptiveColor{Dark: "240", Light: "250"}47+ solvedBg = compat.AdaptiveColor{Dark: lipgloss.Color("22"), Light: lipgloss.Color("151")}48+ solvedBorder = compat.AdaptiveColor{Dark: lipgloss.Color("149"), Light: lipgloss.Color("22")}49+ borderColor = compat.AdaptiveColor{Dark: lipgloss.Color("240"), Light: lipgloss.Color("250")}4950 50- selectedClueBg = lipgloss.AdaptiveColor{Dark: "172", Light: "179"}51+ selectedClueBg = compat.AdaptiveColor{Dark: lipgloss.Color("172"), Light: lipgloss.Color("179")}5152 52- infoSatisfied = lipgloss.AdaptiveColor{Dark: "22", Light: "149"}53- infoText = lipgloss.AdaptiveColor{Dark: "137", Light: "137"}53+ infoSatisfied = compat.AdaptiveColor{Dark: lipgloss.Color("22"), Light: lipgloss.Color("149")}54+ infoText = compat.AdaptiveColor{Dark: lipgloss.Color("137"), Light: lipgloss.Color("137")}5455 5556 gridBorderStyle = lipgloss.NewStyle().5657 Border(lipgloss.RoundedBorder()).
@@ -113,9 +114,9 @@ func cellView(m Model, x, y int, solved bool, preview *Rectangle, previewClue *C
113114 // Rectangle background color.114115 if owner >= 0 {115116 colorIdx := owner % len(rectColors)116- s = s.Background(rectColors[colorIdx]).Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "255"})117+ s = s.Background(rectColors[colorIdx]).Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("255")})117118 if clue != nil {118- s = s.Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "255"}).Bold(true)119+ s = s.Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("255")}).Bold(true)119120 }120121 }121122
@@ -123,22 +124,22 @@ func cellView(m Model, x, y int, solved bool, preview *Rectangle, previewClue *C
123124 inPreview := preview != nil && preview.Contains(x, y)124125 if inPreview && previewClue != nil {125126 if preview.Area() == previewClue.Value && !m.puzzle.Overlaps(*preview, previewClue.ID) {126- s = s.Background(previewGoodBg).Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "255"})127+ s = s.Background(previewGoodBg).Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("255")})127128 } else {128- s = s.Background(previewBadBg).Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "255"})129+ s = s.Background(previewBadBg).Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("255")})129130 }130131 }131132 132133 // Selected clue highlight.133134 if m.selectedClue != nil && clue != nil && clue.ID == *m.selectedClue && !inPreview {134- s = s.Background(selectedClueBg).Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "235"}).Bold(true)135+ s = s.Background(selectedClueBg).Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("235")}).Bold(true)135136 }136137 137138 // Solved styling.138139 if solved {139140 if owner >= 0 {140141 colorIdx := owner % len(rectColors)141- s = s.Background(rectColors[colorIdx]).Foreground(lipgloss.AdaptiveColor{Dark: "255", Light: "255"})142+ s = s.Background(rectColors[colorIdx]).Foreground(compat.AdaptiveColor{Dark: lipgloss.Color("255"), Light: lipgloss.Color("255")})142143 } else {143144 s = s.Background(solvedBg)144145 }
M spawn.go +1 -1
M sudoku/Gamemode.go +1 -1
M sudoku/Model.go +3 -3
M sudoku/keys.go +1 -1
M sudoku/style.go +13 -12
@@ -4,48 +4,49 @@ import (
44 "fmt"55 "strings"66 7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"79 "github.com/FelineStateMachine/puzzletea/game"8- "github.com/charmbracelet/lipgloss"910 )1011 1112 var (12- backgroundColor = lipgloss.AdaptiveColor{Light: "254", Dark: "235"}13+ backgroundColor = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("235")}1314 1415 emptyCellStyle = lipgloss.NewStyle().15- Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "240"}).16+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}).1617 Background(backgroundColor)1718 1819 providedCellStyle = lipgloss.NewStyle().1920 Bold(true).20- Foreground(lipgloss.AdaptiveColor{Light: "130", Dark: "179"}).21+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("179")}).2122 Background(backgroundColor)2223 2324 userCellStyle = lipgloss.NewStyle().24- Foreground(lipgloss.AdaptiveColor{Light: "236", Dark: "187"}).25+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("236"), Dark: lipgloss.Color("187")}).2526 Background(backgroundColor)2627 2728 cursorCellStyle = game.CursorStyle2829 2930 conflictCellStyle = lipgloss.NewStyle().30- Foreground(lipgloss.AdaptiveColor{Light: "160", Dark: "167"}).31- Background(lipgloss.AdaptiveColor{Light: "224", Dark: "52"})31+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("160"), Dark: lipgloss.Color("167")}).32+ Background(compat.AdaptiveColor{Light: lipgloss.Color("224"), Dark: lipgloss.Color("52")})3233 3334 sameNumberStyle = lipgloss.NewStyle().3435 Bold(true).35- Foreground(lipgloss.AdaptiveColor{Light: "130", Dark: "187"})36+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("187")})3637 37- crosshairBG = lipgloss.AdaptiveColor{Light: "254", Dark: "237"}38+ crosshairBG = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("237")}3839 39- boxBorderFG = lipgloss.AdaptiveColor{Light: "250", Dark: "240"}40+ boxBorderFG = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}4041 4142 gridBorderStyle = lipgloss.NewStyle().4243 Border(lipgloss.RoundedBorder()).43- BorderForeground(lipgloss.AdaptiveColor{Light: "250", Dark: "240"}).44+ BorderForeground(compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}).4445 BorderBackground(backgroundColor)4546 4647 gridBorderSolvedStyle = lipgloss.NewStyle().4748 Border(lipgloss.RoundedBorder()).48- BorderForeground(lipgloss.AdaptiveColor{Light: "22", Dark: "149"}).49+ BorderForeground(compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")}).4950 BorderBackground(backgroundColor)5051 5152 sudokuCellWidth = 2
M takuzu/Gamemode.go +1 -1
M takuzu/Model.go +3 -3
M takuzu/keys.go +1 -1
M takuzu/style.go +10 -9
@@ -1,31 +1,32 @@
11 package takuzu22 33 import (4+ "charm.land/lipgloss/v2"5+ "charm.land/lipgloss/v2/compat"46 "github.com/FelineStateMachine/puzzletea/game"5- "github.com/charmbracelet/lipgloss"67 )78 89 var (910 baseStyle = lipgloss.NewStyle()10- backgroundColor = lipgloss.AdaptiveColor{Light: "254", Dark: "235"}11+ backgroundColor = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("235")}1112 zeroStyle = baseStyle.12- Foreground(lipgloss.AdaptiveColor{Light: "130", Dark: "222"}).13+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("222")}).1314 Background(backgroundColor)1415 1516 oneStyle = baseStyle.16- Foreground(lipgloss.AdaptiveColor{Light: "68", Dark: "111"}).17+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("68"), Dark: lipgloss.Color("111")}).1718 Background(backgroundColor)1819 1920 emptyStyle = baseStyle.20- Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "240"}).21+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}).2122 Background(backgroundColor)2223 2324 cursorSolvedStyle = game.CursorSolvedStyle2425 25- crosshairBG = lipgloss.AdaptiveColor{Light: "254", Dark: "237"}26- solvedBG = lipgloss.AdaptiveColor{Light: "151", Dark: "22"}26+ crosshairBG = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("237")}27+ solvedBG = compat.AdaptiveColor{Light: lipgloss.Color("151"), Dark: lipgloss.Color("22")}2728 28- borderFG = lipgloss.AdaptiveColor{Light: "250", Dark: "240"}29+ borderFG = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}2930 )3031 3132 const cellWidth = 3
@@ -109,7 +110,7 @@ var gridBorderColors = game.GridBorderColors{
109110 BorderFG: borderFG,110111 BackgroundBG: backgroundColor,111112 CrosshairBG: crosshairBG,112- SolvedBorderFG: lipgloss.AdaptiveColor{Light: "22", Dark: "149"},113+ SolvedBorderFG: compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")},113114 SolvedBG: solvedBG,114115 }115116
M ui/list.go +4 -3
M ui/style.go +11 -8
@@ -1,20 +1,23 @@
11 package ui22 3-import "github.com/charmbracelet/lipgloss"3+import (4+ "charm.land/lipgloss/v2"5+ "charm.land/lipgloss/v2/compat"6+)47 58 // Earth-tone palette for menus — ANSI 256 colors with light/dark adaptivity.69 var (7- MenuAccent = lipgloss.AdaptiveColor{Light: "130", Dark: "173"}8- MenuAccentLight = lipgloss.AdaptiveColor{Light: "137", Dark: "180"}9- MenuText = lipgloss.AdaptiveColor{Light: "235", Dark: "252"}10- MenuTextDim = lipgloss.AdaptiveColor{Light: "243", Dark: "243"}11- MenuDim = lipgloss.AdaptiveColor{Light: "250", Dark: "238"}12- MenuTableHeader = lipgloss.AdaptiveColor{Light: "130", Dark: "180"}10+ MenuAccent = compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("173")}11+ MenuAccentLight = compat.AdaptiveColor{Light: lipgloss.Color("137"), Dark: lipgloss.Color("180")}12+ MenuText = compat.AdaptiveColor{Light: lipgloss.Color("235"), Dark: lipgloss.Color("252")}13+ MenuTextDim = compat.AdaptiveColor{Light: lipgloss.Color("243"), Dark: lipgloss.Color("243")}14+ MenuDim = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("238")}15+ MenuTableHeader = compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("180")}1316 1417 RootStyle = lipgloss.NewStyle().Margin(1, 2)1518 DebugStyle = lipgloss.NewStyle().1619 Border(lipgloss.RoundedBorder(), true).17- BorderForeground(lipgloss.AdaptiveColor{Light: "124", Dark: "124"})20+ BorderForeground(compat.AdaptiveColor{Light: lipgloss.Color("124"), Dark: lipgloss.Color("124")})1821 )1922 2023 // RootFrameSize returns the horizontal and vertical frame size of RootStyle.
M ui/table.go +4 -3
M ui/ui_test.go +1 -1
M update.go +6 -6
M view.go +31 -21
@@ -5,20 +5,24 @@ import (
55 66 "github.com/FelineStateMachine/puzzletea/ui"77 8- "github.com/charmbracelet/lipgloss"8+ tea "charm.land/bubbletea/v2"9+ "charm.land/lipgloss/v2"10+ "charm.land/lipgloss/v2/compat"911 )1012 11-func (m model) View() string {13+func (m model) View() tea.View {14+ var content string15+1216 switch m.state {1317 case mainMenuView:14- return ui.CenterView(m.width, m.height, m.mainMenuList.View())18+ content = ui.CenterView(m.width, m.height, m.mainMenuList.View())1519 case gameSelectView:16- return ui.CenterView(m.width, m.height, m.gameSelectList.View())20+ content = ui.CenterView(m.width, m.height, m.gameSelectList.View())1721 case modeSelectView:18- return ui.CenterView(m.width, m.height, m.modeSelectList.View())22+ content = ui.CenterView(m.width, m.height, m.modeSelectList.View())1923 case generatingView:2024 s := m.spinner.View() + " Generating puzzle..."21- return ui.CenterView(m.width, m.height, s)25+ content = ui.CenterView(m.width, m.height, s)2226 case continueView:2327 var s string2428 if len(m.continueGames) == 0 {
@@ -26,28 +30,30 @@ func (m model) View() string {
2630 } else {2731 title := lipgloss.NewStyle().2832 Bold(true).29- Foreground(lipgloss.AdaptiveColor{Light: "255", Dark: "255"}).33+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("255"), Dark: lipgloss.Color("255")}).3034 Background(ui.MenuAccent).3135 Padding(0, 1).3236 Render("Saved Games")3337 s = lipgloss.JoinVertical(lipgloss.Left, title, "", m.continueTable.View())3438 }35- return ui.CenterView(m.width, m.height, s)39+ content = ui.CenterView(m.width, m.height, s)3640 case gameView:3741 if m.game == nil {38- return ""39- }40- var debugInfo string41- if m.debug {42- debugInfo = ui.DebugStyle.Render(m.debuginfo)42+ content = ""43+ } else {44+ var debugInfo string45+ if m.debug {46+ debugInfo = ui.DebugStyle.Render(m.debuginfo)47+ }48+ content = ui.CenterView(m.width, m.height,49+ lipgloss.JoinVertical(lipgloss.Center,50+ m.game.View(),51+ debugInfo,52+ ),53+ )4354 }44- s := lipgloss.JoinVertical(lipgloss.Center,45- m.game.View(),46- debugInfo,47- )48- return ui.CenterView(m.width, m.height, s)4955 case helpSelectView:50- return ui.CenterView(m.width, m.height, m.helpSelectList.View())56+ content = ui.CenterView(m.width, m.height, m.helpSelectList.View())5157 case helpDetailView:5258 footer := lipgloss.NewStyle().5359 Foreground(ui.MenuTextDim).
@@ -56,8 +62,12 @@ func (m model) View() string {
5662 m.helpViewport.View(),5763 footer,5864 )59- return ui.CenterView(m.width, m.height, s)65+ content = ui.CenterView(m.width, m.height, s)6066 default:61- return fmt.Sprintf("unknown state: %d", m.state)67+ content = fmt.Sprintf("unknown state: %d", m.state)6268 }69+70+ v := tea.NewView(content)71+ v.AltScreen = true72+ return v6373 }
M wordsearch/Gamemode.go +1 -1
M wordsearch/Model.go +2 -2
M wordsearch/keys.go +1 -1
M wordsearch/style.go +14 -13
@@ -4,40 +4,41 @@ import (
44 "fmt"55 "strings"66 7+ "charm.land/lipgloss/v2"8+ "charm.land/lipgloss/v2/compat"79 "github.com/FelineStateMachine/puzzletea/game"8- "github.com/charmbracelet/lipgloss"910 )1011 1112 var (1213 normalStyle = lipgloss.NewStyle().13- Foreground(lipgloss.AdaptiveColor{Light: "236", Dark: "252"}).14- Background(lipgloss.AdaptiveColor{Light: "254", Dark: "236"})14+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("236"), Dark: lipgloss.Color("252")}).15+ Background(compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("236")})1516 1617 cursorStyle = game.CursorStyle1718 1819 selectionStyle = lipgloss.NewStyle().19- Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "235"}).20- Background(lipgloss.AdaptiveColor{Light: "172", Dark: "180"})20+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("235"), Dark: lipgloss.Color("235")}).21+ Background(compat.AdaptiveColor{Light: lipgloss.Color("172"), Dark: lipgloss.Color("180")})2122 2223 foundStyle = lipgloss.NewStyle().23- Foreground(lipgloss.AdaptiveColor{Light: "22", Dark: "151"}).24- Background(lipgloss.AdaptiveColor{Light: "194", Dark: "237"})24+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("151")}).25+ Background(compat.AdaptiveColor{Light: lipgloss.Color("194"), Dark: lipgloss.Color("237")})2526 2627 wordListHeaderStyle = lipgloss.NewStyle().27- Foreground(lipgloss.AdaptiveColor{Light: "130", Dark: "173"}).28+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("130"), Dark: lipgloss.Color("173")}).2829 Bold(true).2930 Underline(true)3031 3132 foundWordStyle = lipgloss.NewStyle().32- Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "115"}).33+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("28"), Dark: lipgloss.Color("115")}).3334 Strikethrough(true)3435 3536 unfoundWordStyle = lipgloss.NewStyle().36- Foreground(lipgloss.AdaptiveColor{Light: "137", Dark: "137"})37+ Foreground(compat.AdaptiveColor{Light: lipgloss.Color("137"), Dark: lipgloss.Color("137")})3738 38- borderFG = lipgloss.AdaptiveColor{Light: "250", Dark: "240"}39- gridBG = lipgloss.AdaptiveColor{Light: "254", Dark: "236"}40- solvedBdrFG = lipgloss.AdaptiveColor{Light: "22", Dark: "149"}39+ borderFG = compat.AdaptiveColor{Light: lipgloss.Color("250"), Dark: lipgloss.Color("240")}40+ gridBG = compat.AdaptiveColor{Light: lipgloss.Color("254"), Dark: lipgloss.Color("236")}41+ solvedBdrFG = compat.AdaptiveColor{Light: lipgloss.Color("22"), Dark: lipgloss.Color("149")}4142 4243 gridBorderStyle = lipgloss.NewStyle().4344 Border(lipgloss.RoundedBorder()).