Style Overview
ftui-style is the shared vocabulary for color and visual attributes
across the entire FrankenTUI stack. Widgets compose styles with a CSS-
like cascade; color profiles downgrade 24-bit RGB gracefully on older
terminals; named styles live in a StyleSheet registry; Theme wires
adaptive light/dark variants.
Nothing in this crate renders. It defines the types the render layer reads.
The four pieces
Style builder: bold, italic, underline, dim, reversed,
strikethrough, hidden, plus fg / bg / underline-color.
Color, ColorProfile (TrueColor / Ansi256 / Ansi16 / Mono), and
automatic downgrade.
WCAG 2.1 contrast ratios, relative luminance, AA / AAA checks.
WCAG contrastNamed-style registry with optional default semantic styles.
StyleSheetThe 3.5K-line theming engine for tabular data.
Table themeMulti-stop color interpolation.
GradientsThe cascade
Styles combine in CSS-like fashion: a child style inherits the parent’s
values where the child hasn’t set its own. Attribute flags (bold,
italic, etc.) OR together — both parent and child contribute. Colors
are “most-specific wins”: a child’s fg overrides the parent’s.
parent: bold, fg: white
child: fg: red
combined: bold, fg: redThis is the Style::merge(parent) / Style::combine(other) contract.
Details in the Style API page.
Color profiles
Terminals vary in color fidelity. ftui-style represents this
explicitly and downgrades automatically:
TrueColor (24-bit) COLORTERM=truecolor
│
▼ if unavailable
Ansi256 (8-bit) TERM contains "256"
│
▼ if unavailable
Ansi16 (basic ANSI) default
│
▼ if NO_COLOR set
Mono (black/white)ColorProfile::detect() picks the right level from environment
variables; Color::downgrade(profile) produces the best
approximation via Euclidean distance in RGB space.
Named styles — the StyleSheet
Rather than hardcoding colors across widgets, register styles once and refer to them by name:
let sheet = StyleSheet::with_defaults();
let style = sheet.get("error").unwrap();with_defaults populates the common semantic styles (error,
warning, info, success, muted, highlight, link). See
stylesheet.
Adaptive color and themes
pub enum AdaptiveColor {
Fixed(Color),
Adaptive { light: Color, dark: Color },
}Theme composes a whole UI palette: primary, secondary, background,
text, success, warning, error — with each color as an AdaptiveColor.
The runtime decides light-vs-dark once (from terminal background or an
explicit user choice) and resolves the theme for that choice.
Principles you can rely on
- Cheap to copy.
StyleisCopy(28 bytes on x86_64). Passing it by value is idiomatic. - Hashable.
StylederivesHash/Eq, so you can key a cache on styled content. - No hidden I/O. No
println!, no file reads. Purely functional. - Forward-compatible. Extension fields live in the
StyleSheetmap andTableTheme’s spec layer, not in flags-by-bit.