using System.Windows.Media; namespace ytLive.Services.Compositor; /// The colours and typefaces the ON-STREAM graphics paint with. /// /// Why this exists rather than reading Themes/Tokens.xaml: the renderers run on the /// frame-pump thread and must never touch application resources or a dispatcher. They need frozen /// values they can read from any thread. /// /// Two groups live here, deliberately separated: /// /// Brand tokens — a mirror of DESIGN.md. OutputPaletteTests parses the design /// document and fails if any of these drifts from the theme, so the duplication cannot rot. /// Event accents — the alert box's own six-event colour language (gold for Super /// Chats, violet for members, …). These are content, not chrome: the design standard has no /// purple and should not grow one, but they still belong in ONE place instead of 57 scattered /// literals. /// public static class OutputPalette { // ─── Brand tokens (must equal Themes/Tokens.xaml; guarded) ──────────────── public static readonly Color Live = Color.FromRgb(0xff, 0x54, 0x51); // primary public static readonly Color LiveDark = Color.FromRgb(0xb9, 0x1a, 0x24); // primary-container public static readonly Color Amber = Color.FromRgb(0xff, 0xb9, 0x5f); // secondary public static readonly Color Attention = Color.FromRgb(0xff, 0x8c, 0x3a); public static readonly Color Positive = Color.FromRgb(0x22, 0xc5, 0x5e); public static readonly Color Error = Color.FromRgb(0xef, 0x44, 0x44); public static readonly Color ErrorSurface = Color.FromRgb(0x93, 0x00, 0x0a); public static readonly Color Tertiary = Color.FromRgb(0x38, 0xbd, 0xf8); public static readonly Color TextPrimary = Color.FromRgb(0xda, 0xe2, 0xfd); public static readonly Color TextMuted = Color.FromRgb(0x94, 0xa3, 0xb8); public static readonly Color Background = Color.FromRgb(0x0b, 0x13, 0x26); public static readonly Color Surface = Color.FromRgb(0x17, 0x1f, 0x33); public static readonly Color SurfaceHigh = Color.FromRgb(0x22, 0x2a, 0x3d); public static readonly Color Outline = Color.FromRgb(0x33, 0x41, 0x55); // ─── Alert event accents (content language, not chrome) ─────────────────── public static readonly Color Gold = Color.FromRgb(0xff, 0xd1, 0x66); public static readonly Color GoldBright = Color.FromRgb(0xff, 0xdd, 0x66); public static readonly Color GoldPale = Color.FromRgb(0xff, 0xf3, 0xc4); public static readonly Color WarmCream = Color.FromRgb(0xff, 0xe8, 0xd0); public static readonly Color Pink = Color.FromRgb(0xff, 0xb3, 0xd9); public static readonly Color Lilac = Color.FromRgb(0xf5, 0xd0, 0xfe); public static readonly Color Crimson = Color.FromRgb(0xf4, 0x2f, 0x5f); public static readonly Color MintText = Color.FromRgb(0xdb, 0xff, 0xf0); public static readonly Color Violet = Color.FromRgb(0xa7, 0x8b, 0xfa); /// The branding flash's halo channels. Red is the standard live red — one red in the /// product, including the credit — and the blue is lifted for luminance against a video feed. public static readonly Color NeonRed = Live; public static readonly Color NeonBlue = Color.FromRgb(0x4d, 0x8b, 0xff); // ─── Typefaces ─────────────────────────────────────────────────────────── /// Bundled families (OFL). Resolved from the pack folder so on-stream graphics wear /// the same faces as the UI; a failure falls back to the system face rather than throwing /// inside a render tick. private static readonly System.Lazy SansFamily = new(() => Family("Inter")); private static readonly System.Lazy MonoFamily = new(() => Family("JetBrains Mono")); public static FontFamily Sans => SansFamily.Value; public static FontFamily Mono => MonoFamily.Value; /// The pack scheme only exists once WPF has registered it, so a static initializer /// must not build a pack URI: it throws a TypeInitializationException in any host without an /// Application (exactly what the first version did in the test process). Fall back to the /// family name, which resolves from the bundled resource or the system face. private static FontFamily Family(string name) { try { return new FontFamily(new System.Uri("pack://application:,,,/"), "/Assets/Fonts/#" + name); } catch (System.Exception) { return new FontFamily(name); } } public static SolidColorBrush Brush(Color colour) { var brush = new SolidColorBrush(colour); brush.Freeze(); return brush; } }