theme

package
v0.11.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package theme centralizes the miren CLI's color palette and adapts it to the terminal it's running in.

Historically colors were hard-coded as bright 256-color ANSI indices tuned for dark terminals, which washed out (or dropped below readable contrast) on light backgrounds. This package instead exposes a small set of semantic roles (Header, Success, Warning, ...) as lipgloss.AdaptiveColor values whose light and dark variants are hand-tuned for contrast on their respective backgrounds.

Init decides, once per process, which variant to use. It honors the de-facto terminal color conventions (NO_COLOR, FORCE_COLOR/CLICOLOR) and a manual override (MIREN_THEME env var or the `theme` client-config field), falling back to background auto-detection (COLORFGBG hint, then an OSC 11 query) and finally to dark, the safe historical default.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Header styles section headings and table column headers (was bright "220").
	// On light backgrounds gold reads muddy, so headers borrow the Info blue there
	// (bold + underline still distinguish them from plain Info text); dark keeps
	// the gold.
	Header = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#FFD75F", ANSI256: "221", ANSI: "11"},
		Light: lipgloss.CompleteColor{TrueColor: "#2563EB", ANSI256: "26", ANSI: "4"},
	}
	// Success marks healthy/OK/added state (was bright green "10"/"2").
	Success = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#4EC94E", ANSI256: "77", ANSI: "10"},
		Light: lipgloss.CompleteColor{TrueColor: "#15803D", ANSI256: "28", ANSI: "2"},
	}
	// Warning marks degraded/pending/attention state (was yellow "11"/"3"/"208").
	Warning = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#E0B000", ANSI256: "178", ANSI: "11"},
		Light: lipgloss.CompleteColor{TrueColor: "#C2410C", ANSI256: "166", ANSI: "3"},
	}
	// Error marks failed/error state (was red "9"/"196").
	Error = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#FF6B6B", ANSI256: "203", ANSI: "9"},
		Light: lipgloss.CompleteColor{TrueColor: "#DC2626", ANSI256: "160", ANSI: "1"},
	}
	// Info marks informational accents and links (was blue "12"/"62").
	Info = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#5FAFFF", ANSI256: "75", ANSI: "12"},
		Light: lipgloss.CompleteColor{TrueColor: "#2563EB", ANSI256: "26", ANSI: "4"},
	}
	// Muted is low-emphasis secondary text. It replaces the pervasive Faint(true)
	// usage, which relied on the terminal's dim attribute and vanished on light
	// backgrounds (was gray "8"/"240"/"244"/"245").
	Muted = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#9A9A9A", ANSI256: "246", ANSI: "8"},
		Light: lipgloss.CompleteColor{TrueColor: "#6B7280", ANSI256: "243", ANSI: "8"},
	}
	// Highlight marks the selected/active item in interactive pickers.
	Highlight = lipgloss.CompleteAdaptiveColor{
		Dark:  lipgloss.CompleteColor{TrueColor: "#D7AFFF", ANSI256: "183", ANSI: "13"},
		Light: lipgloss.CompleteColor{TrueColor: "#7C3AED", ANSI256: "91", ANSI: "5"},
	}
)

Semantic color roles. Each is a lipgloss.CompleteAdaptiveColor, which carries exact values for the truecolor, ANSI256, and ANSI profiles, split by light and dark background. lipgloss selects the Light/Dark side from the background darkness we set via SetHasDarkBackground in Init, then reads the field matching the terminal's color profile with NO automatic degradation. This lets us serve designed jewel tones on truecolor terminals while pinning 256-color terminals to xterm anchor indices (so distinct roles never quantize into the same muddy bucket) and still degrade sanely to the basic 16 colors.

Dark values stay close to the previous bright palette. Light values are darker, saturated tones tuned for contrast on white; the warm hues (gold/orange) run a little lower on contrast but are used bold or as status glyphs where that reads fine.

Functions

func DetectedBackground

func DetectedBackground() string

DetectedBackground returns the terminal background hex observed during detection, or "" if detection didn't run (override set, not a TTY, or the terminal didn't answer). Used by the `miren colors` debug command.

func Init

func Init(configured string)

Init resolves the palette variant once per process and applies it to lipgloss's default renderer. configured is the `theme` value from client config (may be empty). It is safe to call multiple times; only the first call takes effect.

Types

type Role

type Role struct {
	Name  string
	Color lipgloss.CompleteAdaptiveColor
}

Role pairs a human name with its color, for the `miren colors` debug command.

func Roles

func Roles() []Role

Roles returns the semantic roles in display order.

type Variant

type Variant int

Variant is the resolved palette variant.

const (
	// VariantDark is the palette for dark-background terminals (the default).
	VariantDark Variant = iota
	// VariantLight is the palette for light-background terminals.
	VariantLight
	// VariantNoColor disables color entirely (NO_COLOR / `theme: no`).
	VariantNoColor
)

func Current

func Current() Variant

Current returns the resolved palette variant. It is only meaningful after Init.

func (Variant) String

func (v Variant) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL