package tui import ( "os" "github.com/charmbracelet/lipgloss" ) // styles holds the few rendered styles the control center uses. They are // intentionally minimal and neutral (Constraint 4: precise, no emoji, no // first person). When colour is disabled the styles degrade to plain // text rather than changing layout. type styles struct { brand lipgloss.Style // logo accent (matches the "eco" half of the README mark) logoMuted lipgloss.Style // logo accent for the leading "e"; adapts to terminal background (near-black on light, near-white on dark) to mirror the two PNG mark variants prompt lipgloss.Style // » input prompt dim lipgloss.Style // hint line, secondary text dimmer lipgloss.Style // status footer — sits below placeholder weight key lipgloss.Style // command names, key labels value lipgloss.Style // primary readable body text — table values, free-text body tableHeader lipgloss.Style // column header cells in a section table warn lipgloss.Style // cautionary inline notes ok lipgloss.Style // success inline notes } // colorEnabled reports whether coloured output is wanted. The NO_COLOR // convention (any non-empty value disables colour) is honoured; a value // the user cannot override (a non-terminal sink) is handled separately // by the non-interactive path. func colorEnabled() bool { return os.Getenv("NO_COLOR") == "" } // newStyles builds the style set. With colour off every style is the // identity style, so the same View code path renders readable plain // text under NO_COLOR or a dumb terminal. func newStyles(color bool) styles { if !color { plain := lipgloss.NewStyle() return styles{ brand: plain, logoMuted: plain, prompt: plain, dim: plain, dimmer: plain, key: plain, value: plain, tableHeader: plain, warn: plain, ok: plain, } } // Atom One Dark palette. Blue (#61afef, the palette's blue slot) is // the eeco brand accent — logo "eco", prompt, command names, primary // affordances. Green stays a semantic success signal only (never an // accent). Greys form a three-step hierarchy: body > hint > footer. const ( blue = "#61afef" // brand accent — logo "eco", prompt, command names cyan = "#66b2ff" // table headers yellow = "#e5c07b" // cautions green = "#98c379" // success only fgWhite = "#ffffff" // primary body text fgGrey = "#abb2bf" // hints, secondary text fgFooter = "#5c6370" // status footer, faintest nearDark = "#282c34" // light-background foreground ) return styles{ brand: lipgloss.NewStyle().Foreground(lipgloss.Color(blue)).Bold(true), logoMuted: lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: nearDark, Dark: fgGrey}).Bold(true), prompt: lipgloss.NewStyle().Foreground(lipgloss.Color(blue)).Bold(true), dim: lipgloss.NewStyle().Foreground(lipgloss.Color(fgGrey)), dimmer: lipgloss.NewStyle().Foreground(lipgloss.Color(fgFooter)), key: lipgloss.NewStyle().Foreground(lipgloss.Color(blue)).Bold(true), value: lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: nearDark, Dark: fgWhite}), tableHeader: lipgloss.NewStyle().Foreground(lipgloss.Color(cyan)).Bold(true), warn: lipgloss.NewStyle().Foreground(lipgloss.Color(yellow)).Bold(true), ok: lipgloss.NewStyle().Foreground(lipgloss.Color(green)).Bold(true), } }