Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ChromaColors = ChromaPalette{ Keyword: lipgloss.Color("#4FA8A5"), String: lipgloss.Color("#A2AD59"), Comment: lipgloss.Color("#7C8577"), Number: lipgloss.Color("#C4B77A"), Function: lipgloss.Color("#7FC4BE"), }
ChromaColors is the code-fence palette, in the heading ladder's temperature so a fence reads as part of the same document. The values are picked against Theme.Surface (the plate a fence renders on), not against the terminal background — Comment is the quietest of the five and still clears the plate.
Dark backgrounds only. On white, glamour's stock light chroma stays: these are chosen for a dark plate and three of them would be unreadable on paper.
var Default = Theme{ Accent: lipgloss.Color("#DA7756"), Signal: lipgloss.Color("#E5A040"), Ok: lipgloss.Color("#6AAF6A"), Danger: lipgloss.Color("#D06060"), Link: lipgloss.Color("#5F93B8"), Emphasis: lipgloss.Color("#F2F3F5"), Text: lipgloss.Color("#A8ADB8"), Dim: lipgloss.Color("#767C88"), Border: lipgloss.Color("#454B57"), Surface: lipgloss.Color("#343945"), SignalDim: lipgloss.Color("#7A5A1E"), }
Default is keepkit's own theme. A second theme is a second value of this struct — no other file changes.
var HeadingColors = [5]lipgloss.Color{ lipgloss.Color("#a2ad59"), lipgloss.Color("#8e936d"), lipgloss.Color("#598381"), lipgloss.Color("#177e89"), lipgloss.Color("#08605f"), }
HeadingColors is panel [3]'s heading ladder, H1 through H5, index 0 = H1. It exists because the stock config renders H3 through H6 identically, so a README's own structure was invisible below the second level. H6 is not here — it takes the Theme.Dim role, since by the sixth level the honest statement is "this is a heading and it is the quietest one".
THE ORDER IS BRIGHT TO DARK, and that direction is the decision, not the palette. keepkit is a dark-terminal app, and measured against a typical dark background these five run 7.2 : 5.4 : 4.1 : 3.6 : 2.4 in contrast — so the dark-to-bright reading puts the LEAST contrast on H1, below the 3:1 floor for bold text and below the Dim role a caption uses. A document's top heading being the hardest line on the page to read is not a ladder, it is an inverted one. Loud at the top, quiet at the bottom.
Accepted consequences of choosing for the dark terminal: on white the ends swap, so H1 measures ~2.4 there and the lowest steps read best — and on dark, H5 (2.4) sits below H6's Dim (4.2), which makes the ladder's last two steps read as one. Both are the price of the ordering, and both were weighed against a top-level heading nobody can find.
Both background variants share the ladder: it is content typography, not a tint, and the light variant of keepkitStyle takes these colors while keeping glamour's stock light palette for everything else.
Functions ¶
func LanguageColor ¶ added in v0.2.0
LanguageColor returns the color GitHub paints a language with, and whether it knows the language at all. An unknown language gets no color from here — the caller falls back to a theme role, so a language linguist has since added reads as "unrecognized" rather than as the wrong one.
func PlaceOverlay ¶
PlaceOverlay renders fg centered over bg, replacing the background cells it covers so the modal reads as floating on top. The visible background is dimmed: original styling is stripped and repainted with dim (the caller's Styles.OverlayDim — passed in rather than read from a package var, so the compositor follows a theme switch like everything else). fg is passed through untouched.
func StripANSI ¶
StripANSI removes ANSI escape sequences from s. It is the single ANSI-strip helper shared across packages (the model layer delegates to it). It must cover the full escape grammar, not just SGR: captured tool output can carry private-mode CSI (ESC[?1049l — leave alternate screen), OSC, DCS, … which a simple [0-9;]* regex misses; anything left unstripped is re-emitted by the renderer and flips the real terminal's state mid-frame.
Types ¶
type ChromaPalette ¶ added in v0.4.0
type ChromaPalette struct {
// Keyword is `func`, `if`, `export` — the structure of the sample.
Keyword lipgloss.Color
// String is a quoted literal, the loudest thing in a shell fence.
String lipgloss.Color
// Comment sits below body brightness on purpose: it is the one part of a
// sample the reader may skip.
Comment lipgloss.Color
// Number is a literal count or version.
Number lipgloss.Color
// Function is a called or declared name.
Function lipgloss.Color
}
ChromaPalette names the code-fence syntax accents keepkit owns. Every other chroma token stays whatever the standard config chose — this is a bounded repaint, not a full syntax theme (see keepkitStyle's comment for what the boundary is and why).
The five are the tokens a README's fences actually spend: a shell block is mostly Keyword/LiteralString, a Go block adds NameFunction and Comment.
type Styles ¶ added in v0.2.0
type Styles struct {
// Theme is the palette these styles were built from. Renderers that need a
// raw color rather than a style — a border repaint, glamour's StyleConfig,
// a background derived per segment — read it from here, so they still go
// through the theme instead of reaching for a package-level color.
Theme Theme
// Accent: focus and interaction. AccentBold additionally marks the one
// element that *has* focus — the selected tool's name, a search hit.
Accent lipgloss.Style
AccentBold lipgloss.Style
// Signal: requires action. Bold is the card's headline version, plain the
// repeated markers in the list.
Signal lipgloss.Style
SignalBold lipgloss.Style
// Ok: healthy state. Danger: broken or exhausted — always bold, it is an
// alarm and there is never more than one on screen.
Ok lipgloss.Style
Danger lipgloss.Style
// Link: URLs only.
Link lipgloss.Style
// Emphasis: the brightest text. EmphasisBold heads a section or names the
// selected tool in the card — the screen's few typographic peaks.
Emphasis lipgloss.Style
EmphasisBold lipgloss.Style
// Text: ordinary reading text. Dim: labels, counters, SHAs, secondary
// hints. Note: the same step down, italic — placeholders and prose that is
// not the app's own voice ("no tools tracked", a repo's tagline).
Text lipgloss.Style
Dim lipgloss.Style
Note lipgloss.Style
// Rule draws dividers, group headers and the vertical lines between metric
// columns. Surface is a background *only* — a call site pairs it with a
// foreground style rather than using it alone, because a lipgloss style
// applied around already-styled text cannot repaint the segments inside it.
Rule lipgloss.Style
Surface lipgloss.Style
// Panel frames and the status bar. The focused panel differs by color and
// by the ▸ its title carries — two signals, so focus survives a colorless
// terminal.
PanelBorder lipgloss.Style
PanelBorderFocused lipgloss.Style
StatusBar lipgloss.Style
// Overlays: the modal frame, and the repaint applied to everything behind
// it so the modal is the only full-color element on screen.
OverlayBorder lipgloss.Style
OverlayDim lipgloss.Style
// The API-usage gauge. GaugeTrack is Theme.SignalDim's only consumer: fill
// and track have to read as one bar, which no other pair of roles can do.
GaugeFill lipgloss.Style
GaugeTrack lipgloss.Style
}
Styles is every lipgloss.Style keepkit renders with, built from one Theme. It is a value, not a package of vars: the model holds one (see model.New), so re-theming the whole app is handing the model a different Styles rather than mutating globals under a running render.
The set is deliberately small and named after Theme's roles rather than after the widgets that use it. A per-widget name (the old TagHeaderStyle, HelpSectionStyle, SectionLabelStyle, …) reads well exactly once — at the call site it was invented for — and then quietly multiplies into a palette of near-duplicates that a theme has to keep consistent by hand. Emphasis steps that used to justify a new color are covered here by weight (Bold), italics and the Surface background, so what a call site picks is a *meaning*, and the comment above it says which.
func DefaultStyles ¶ added in v0.2.0
func DefaultStyles() *Styles
func NewStyles ¶ added in v0.2.0
NewStyles builds the style set for a theme. It is the only function in the codebase allowed to turn a color into a style — every field below is derived from t, never from a literal.
It returns a pointer: Styles is ~20 lipgloss.Style values (a few kilobytes), the renderers are value receivers, and a frame reads it dozens of times.
type Theme ¶ added in v0.2.0
type Theme struct {
// Accent marks *focus and interaction*: the active panel's border and
// title, the ⏺ cursor, the selected tool's name, and every key hint in the
// app. If it is accented, pressing something is involved.
Accent lipgloss.Color
// Signal means "requires action" and nothing else: the ↑ on an outdated
// tool, the latest version when an update exists, the updates counter,
// status trying. Deliberately scarce — it is the color the eye should find
// first on a screen full of tools.
Signal lipgloss.Color
// Ok is a healthy resting state: ● active maintenance, a version-less but
// working install, keepkit's own up-to-date version.
Ok lipgloss.Color
// Danger is broken or exhausted: a failed detection, a spent rate limit.
Danger lipgloss.Color
// Link is URLs, and only URLs.
Link lipgloss.Color
// Emphasis is the brightest text on screen: the card's tool name, metric
// values, section headings, the bold lead of a readme feature line. There
// are meant to be very few of them per frame.
Emphasis lipgloss.Color
// Text is ordinary reading text — the default for anything with no reason
// to stand out or step back.
Text lipgloss.Color
// Dim is labels, counters, SHAs, secondary hints: present, readable,
// never competing.
Dim lipgloss.Color
// Border draws panel frames, dividers and the vertical rules between metric
// columns — structure the eye should follow without reading.
Border lipgloss.Color
// Surface is the only background role: the card's metrics strip, the code
// lines in its changelog, readme code plates. It must sit close enough to
// the terminal background that a filled block reads as raised rather than
// as a painted bar.
Surface lipgloss.Color
// SignalDim is the API gauge's empty track — the one place a *shade* of a
// role is unavoidable, since fill and track must read as one bar. It is not
// a semantic role and nothing else may use it.
SignalDim lipgloss.Color
}
Theme is the app's entire color vocabulary — ten semantic roles and nothing else. Styles are built from these roles only (NewStyles is the single consumer), so no file below internal/ui carries a hex literal and switching every color keepkit paints as a *meaning* is switching one Theme value.
Two palettes in this package stand outside that vocabulary, and a theme switch repaints neither. languageColors (lang.go) are linguist's brand marks — somebody else's colors, not keepkit's to restyle. HeadingColors/ChromaColors (readme_palette.go) are keepkit-invented shades for panel [3]'s heading ladder and code-fence accents, taken because a heading *level* is not a meaning this vocabulary has a word for and six levels cannot be six roles. Each file carries its own argument; both are exceptions to the two rules below rather than applications of them.
The roles are named for what a color *means*, not for what it looks like: a theme that paints "signal" green would still be internally consistent, while a role named "orange" would be a lie the moment it changed. Two rules keep the vocabulary from growing back into a palette:
- a new role must name a distinct *meaning*, not a shade — weight (Bold), italics and the Surface background cover emphasis steps for free. This is what retired the old ColorCategory/ColorKey (headers and search hits) and ColorMuted (a second, indistinguishable text gray);
- Link is for URLs only. Everything that used to be "meta blue" — help placeholders, hints, tag suffixes — is Dim, so a blue run of text in the UI always means "this is an address".