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;
}
}