package theme import ( "image/color" "strings" "charm.land/lipgloss/v2" ) // ─── Pastel palette (matching the web app) ─────────────────── var ( Pink = lipgloss.Color("#f472b6") Purple = lipgloss.Color("#a78bfa") Blue = lipgloss.Color("#60a5fa") Mint = lipgloss.Color("#34d399") Orange = lipgloss.Color("#fb923c") Teal = lipgloss.Color("#2dd4bf") Cream = lipgloss.Color("#fdf6ef") Warm = lipgloss.Color("#faf0e6") Peach = lipgloss.Color("#fce8d5") Dark = lipgloss.Color("#2d1f14") Mid = lipgloss.Color("#8b7355") Light = lipgloss.Color("#bfa98a") Red = lipgloss.Color("#f43f5e") DimBg = lipgloss.Color("#f6f6f6") BorderCl = lipgloss.Color("#e8e0d4") // Full-screen background ScreenBg = lipgloss.Color("#fdf6ef") // Cream — matches the web app ) // ─── Category colors ───────────────────────────────────────── func CategoryColor(cat string) color.Color { switch cat { case "image": return Pink case "document": return Blue case "audio": return Purple case "video": return Orange case "data": return Mint case "font": return Teal case "spreadsheet": return Mint default: return Light } } // ─── Reusable styles ───────────────────────────────────────── var ( // Title bar TitleBar = lipgloss.NewStyle(). Bold(true). Foreground(Dark). Background(ScreenBg). Padding(0, 2) // Header / breadcrumb Breadcrumb = lipgloss.NewStyle(). Foreground(Mid). Bold(false) BreadcrumbActive = lipgloss.NewStyle(). Foreground(Dark). Bold(true) // File row FileName = lipgloss.NewStyle(). Foreground(Dark). Bold(true) FileSize = lipgloss.NewStyle(). Foreground(Light) ExtBadge = func(c color.Color) lipgloss.Style { return lipgloss.NewStyle(). Foreground(c). Bold(true) } // Status indicators StatusIdle = lipgloss.NewStyle(). Foreground(Light). Italic(true) StatusConverting = lipgloss.NewStyle(). Foreground(Pink). Bold(true) StatusDone = lipgloss.NewStyle(). Foreground(Mint). Bold(true) StatusError = lipgloss.NewStyle(). Foreground(Red). Bold(true) // Buttons / actions ButtonPrimary = lipgloss.NewStyle(). Foreground(lipgloss.Color("#ffffff")). Background(Pink). Bold(true). Padding(0, 2) ButtonSecondary = lipgloss.NewStyle(). Foreground(lipgloss.Color("#ffffff")). Background(Mint). Bold(true). Padding(0, 2) // Progress bar ProgressFilled = lipgloss.NewStyle(). Foreground(Pink) ProgressEmpty = lipgloss.NewStyle(). Foreground(BorderCl) // Help / footer Help = lipgloss.NewStyle(). Foreground(Light). Italic(true) // Cursor / selection Selected = lipgloss.NewStyle(). Bold(true). Foreground(Pink) Unselected = lipgloss.NewStyle(). Foreground(Dark) // Divider Divider = lipgloss.NewStyle(). Foreground(BorderCl) // Logo / branding Logo = lipgloss.NewStyle(). Foreground(Pink). Bold(true) ) // PadLine pads a single rendered line to the given width with the screen // background color. This ensures every line carries the background color // all the way to the right edge of the terminal. func PadLine(line string, width int) string { w := lipgloss.Width(line) if w >= width { return line } pad := lipgloss.NewStyle(). Background(ScreenBg). Render(strings.Repeat(" ", width-w)) return line + pad } // FillBlankLines returns n blank lines fully painted with the screen // background color at the given width. func FillBlankLines(n, width int) string { if n <= 0 { return "" } blankLine := lipgloss.NewStyle(). Background(ScreenBg). Render(strings.Repeat(" ", width)) lines := make([]string, n) for i := range lines { lines[i] = blankLine } return strings.Join(lines, "\n") }