Files
RedBear-OS/local/recipes/tui/redbear-tui-theme/source

Red Bear OS — Default TUI Skin Palette

redbear-tui-theme is the single source of truth for the Red Bear brand colours used by every TUI application on Red Bear OS:

  • tlc (file manager)
  • cub (package manager)
  • redbear-info (system dashboard)
  • redbear-netctl-console (network control)
  • redbear-wifictl, redbear-btctl (device control)
  • redbear-mtr, redbear-traceroute, redbear-nmap, redbear-hwutils (diagnostics)
  • any future TUI app

The palette is pure-Rust (no ratatui dep at the core), builds offline, and ships with both dark and light presets.

Quick start

# Cargo.toml
[dependencies]
redbear-tui-theme = { path = "../../../tui/redbear-tui-theme/source" }
use redbear_tui_theme::{REDBEAR_DARK, Theme};

// Render a selection row.
let bg = REDBEAR_DARK.selection_bg;  // #3652A0
let fg = REDBEAR_DARK.selection_fg;  // #F4F4F4

// Or pick a theme from the environment (REDBEAR_TUI_THEME or COLORFGBG).
let theme = Theme::from_env();

What's in the palette

The Theme struct has 33 slots organized into six families:

Family Slots Purpose
Surface background, surface, overlay_bg, title_bg, status_bg, gauge_bg 6 slots; 3-tier raised surface; chrome bars
Text text, muted, dim, border 4 slots; body text + de-emphasis
Accent accent, accent_soft, title_accent, pink 4 slots; brand red + secondary accents
Semantic success, warning, error, info 4 slots; status colours (must pair with glyphs)
File types directory, executable, symlink, device, device_warn, hidden 6 slots; tlc file-type colours
Selection selection_{bg,fg}, cursor_{bg,fg}, marked_{bg,fg}, buttonbar_{bg,fg} 8 slots; tlc selection/cursor/marked/buttonbar

All 33 slots are sourced from the shared Theme — no consumer hard-codes brand hex values.

Brand red

#B52430 is the Red Bear OS brand red. It is identical in both dark and light themes. This matches the convention of macOS, KDE, GNOME, and Windows: the brand stays constant; only the background flips.

WCAG 2.1 AA contrast (verified)

Pair Dark ratio Light ratio Pass
text on background 17.51 15.86 AA-body ✓
text on accent 5.86 6.44 AA-body ✓
muted on background 8.33 5.82 AA-body ✓
border on background 4.53 2.27 AA-body (dark) / AA-large (light)
dim on background 2.91 3.81 Intentionally below AA-body (de-emphasis)

The only intentional AA-body failure is dim/hidden. By design: de-emphasis is the function. Apps must not use dim for body text.

Color-blindness

  • success vs error: distinguishable for all three common deficiencies.
  • warning vs error: confusable for protanopia and deuteranopia. Mitigation: every warning must be accompanied by a glyph prefix, every error by .
  • info vs success: confusable for tritanopia. Mitigation: keep info and success on separate lines in status bars.
  • pink is for highlights (favorites, active link). Mitigation: when used, also prepend (U+2605).

Apps render these as styles with Modifier::BOLD on the semantic colours; the styles module (planned v0.2) will provide ready-made success_style(), warning_style(), etc. as one-liners.

256-color + 16-color fallback

For terminals that don't support truecolor, the fallback module provides:

  • fallback_256(rgb: Rgb) -> u8 — closest XTerm-256 index (0..=255)
  • fallback_16_name(rgb: Rgb) -> &'static str — closest ANSI-16 name

fallback_256 uses a weighted Euclidean distance in sRGB space (small luminance penalty to keep the returned colour visually close). Verified mappings:

Slot Truecolor 256-idx 16-name
background #0E0E12 233 Black
text #F4F4F4 255 Bright White
accent #B52430 125 or 9 Bright Red
success #74C793 114 Bright Black
warning #FFBF57 215 Bright Yellow

Migrating an existing TUI app

  1. Add the dep to Cargo.toml:
    redbear-tui-theme = { path = "../../../tui/redbear-tui-theme/source" }
    
  2. Replace local Color::Rgb(r, g, b) constants with REDBEAR_DARK.<slot> (or Rgb(r,g,b) if you need a custom value).
  3. Convert to your TUI lib's colour type: ratatui::style::Color::Rgb(t.bg.0, t.bg.1, t.bg.2).
  4. Replace any local Theme struct with pub use redbear_tui_theme::Theme;.
  5. Add redbear-tui-theme to the cookbook's cascade list in local/scripts/rebuild-cascade.sh.

Build

The crate has zero required dependencies. It builds offline:

cd local/recipes/tui/redbear-tui-theme/source
cargo build --release
cargo test              # 11 unit tests (palette + fallback) + 1 doc test

The recipe lives at local/recipes/tui/redbear-tui-theme/recipe.toml and stages the resulting libredbear_tui_theme.rlib into ${COOKBOOK_STAGE}/usr/lib/ so the cookbook's repo artifact check passes. The recipe is symlinked into the cookbook search path at recipes/tui/redbear-tui-theme (per local/AGENTS.md "Local recipe priority vs upstream WIP"). Downstream TUI apps depend on the crate via a Cargo path dependency — they do not install it as a binary.

Downstream consumers (as of 2026-06-13)

App Status Notes
tlc wired tlc/source/Cargo.toml adds redbear-tui-theme = { path = "../../../tui/redbear-tui-theme/source" }. The 22-field Theme struct in src/terminal/color.rs is preserved (TOML skin deserializer still works); DEFAULT_THEME and LIGHT_THEME are now built from the shared REDBEAR_DARK/REDBEAR_LIGHT via a const as_color(rgb) adapter.
cub wired local/recipes/system/cub/source/cub/src/tui/theme.rs is now a 33-field RedBearTheme newtype constructed from redbear_tui_theme::REDBEAR_DARK via a const as_color(rgb) adapter. The 19 *_style() methods are preserved as inherent methods; all 33 slots are sourced from the shared palette. 2 new tests verify byte-identical brand red and 19 non-empty styles.
redbear-info 🚧 TODO local/recipes/system/redbear-info/source/src/tui.rs uses the legacy ANSI-16 palette (Color::Red, Color::DarkGray, etc.). Migration is non-trivial because the file uses semantic colors only, not slot names.
redbear-netctl-console 🚧 TODO local/recipes/system/redbear-netctl-console/source/src/ui.rs uses the legacy ANSI-16 palette. Same migration story as redbear-info.

License

MIT — same as Red Bear OS.