internal/tui/theme/palette.go

// Package theme holds the colour palette and the shared lipgloss styles.
// The palette is resolvable against both 256-colour and TrueColor
// terminals because bubbletea autodetects and downsamples.
//
// mercemay.top/src/httptap/
package theme

import "github.com/charmbracelet/lipgloss"

// Palette is a complete set of colours used by the TUI.
type Palette struct {
	Background    lipgloss.Color
	Foreground    lipgloss.Color
	Dim           lipgloss.Color
	Accent        lipgloss.Color
	Warning       lipgloss.Color
	Error         lipgloss.Color
	Success       lipgloss.Color
	HighlightBG   lipgloss.Color
	HighlightFG   lipgloss.Color
	StatusBarBG   lipgloss.Color
	StatusBarFG   lipgloss.Color

	Screen        lipgloss.Style
	List          lipgloss.Style
	ListSelected  lipgloss.Style
	Detail        lipgloss.Style
	StatusBar     lipgloss.Style
	FilterBar     lipgloss.Style
	Focused       lipgloss.Style
}

// Default returns the palette used when no profile is loaded.
func Default() Palette {
	p := Palette{
		Background:  "#1a1a1a",
		Foreground:  "#eaeaea",
		Dim:         "#888888",
		Accent:      "#6bb0ff",
		Warning:     "#f5c542",
		Error:       "#ff5a5a",
		Success:     "#6bd68c",
		HighlightBG: "#2f3a4a",
		HighlightFG: "#ffffff",
		StatusBarBG: "#2b2b2b",
		StatusBarFG: "#dadada",
	}
	p.Screen = lipgloss.NewStyle().
		Foreground(p.Foreground).
		Background(p.Background)
	p.List = lipgloss.NewStyle().
		Border(lipgloss.NormalBorder()).
		BorderForeground(p.Dim)
	p.ListSelected = lipgloss.NewStyle().
		Background(p.HighlightBG).
		Foreground(p.HighlightFG).
		Bold(true)
	p.Detail = lipgloss.NewStyle().
		Border(lipgloss.NormalBorder()).
		BorderForeground(p.Dim).
		Padding(0, 1)
	p.StatusBar = lipgloss.NewStyle().
		Foreground(p.StatusBarFG).
		Background(p.StatusBarBG).
		Padding(0, 1)
	p.FilterBar = lipgloss.NewStyle().
		Foreground(p.Foreground).
		Background(p.Background).
		Padding(0, 1)
	p.Focused = lipgloss.NewStyle().
		Border(lipgloss.ThickBorder()).
		BorderForeground(p.Accent)
	return p
}

// Light returns a high-contrast palette for solarized-style light themes.
func Light() Palette {
	p := Default()
	p.Background = "#fdfdfd"
	p.Foreground = "#222222"
	p.Dim = "#666666"
	p.HighlightBG = "#e6f0fa"
	p.HighlightFG = "#0f3a66"
	p.StatusBarBG = "#eeeeee"
	p.StatusBarFG = "#333333"
	p.Screen = lipgloss.NewStyle().Foreground(p.Foreground).Background(p.Background)
	return p
}