// pyramid_theme.dart // Pyramid · Design Tokens für Flutter // // Zentrale Farb-, Typo- und Radius-Konstanten. Alle Player ziehen sich hier raus. // Dark-first; Light-Modus umschaltbar via PyramidTheme.dark = false. import 'package:flutter/material.dart'; class PyramidTheme { PyramidTheme._(); /// Dark mode toggle. Beim Umschalten alle Player rebuilden. static bool dark = true; // ─── Accent (HSL → Color) ───────────────────────────────────────────── // Default: Amber. Per setAccent(h,s,l) änderbar. static double accentH = 42; static double accentS = 95; static double accentL = 58; static Color get accent => HSLColor.fromAHSL(1, accentH, accentS / 100, accentL / 100).toColor(); static Color get accentSoft => HSLColor.fromAHSL(0.14, accentH, accentS / 100, accentL / 100).toColor(); static Color get accentGlow => HSLColor.fromAHSL(0.35, accentH, accentS / 100, accentL / 100).toColor(); static const Color accentFg = Color(0xFF0B0B0D); static void setAccent(double h, double s, double l) { accentH = h; accentS = s; accentL = l; } // ─── Backgrounds & Foregrounds ──────────────────────────────────────── static Color get bg0 => dark ? const Color(0xFF0A0A0C) : const Color(0xFFF5F4F0); static Color get bg1 => dark ? const Color(0xFF111114) : const Color(0xFFFFFFFF); static Color get bg2 => dark ? const Color(0xFF17171C) : const Color(0xFFFAF9F5); static Color get bg3 => dark ? const Color(0xFF1E1E25) : const Color(0xFFF0EEEA); static Color get bgHover => dark ? const Color(0xFF232330) : const Color(0xFFE9E7E1); static Color get bgActive => dark ? const Color(0xFF2A2A38) : const Color(0xFFDFDCD3); static Color get border => dark ? const Color(0xFF25252E) : const Color(0xFFE5E2DC); static Color get borderStrong => dark ? const Color(0xFF32323D) : const Color(0xFFD3CFC6); static Color get fg => dark ? const Color(0xFFECECF0) : const Color(0xFF1A1A1F); static Color get fgMuted => dark ? const Color(0xFFA4A4B0) : const Color(0xFF54545E); static Color get fgDim => dark ? const Color(0xFF6F6F7D) : const Color(0xFF8A8A92); // ─── Radii ──────────────────────────────────────────────────────────── static const double rBase = 12; static const double rSm = 7.2; // base * 0.6 static const double rLg = 18; // base * 1.5 static const double rXl = 24; // base * 2 static const double rPill = 999; // ─── Typography ─────────────────────────────────────────────────────── // Erfordert: Geist + Geist Mono in pubspec.yaml als fonts. // (Alternativ: durch ein anderes Sans/Mono-Paar ersetzen.) static const String fontSans = 'Geist'; static const String fontMono = 'GeistMono'; static TextStyle get title => TextStyle( fontFamily: fontSans, fontSize: 14, fontWeight: FontWeight.w500, color: fg, letterSpacing: -0.1, ); static TextStyle get subtitle => TextStyle( fontFamily: fontSans, fontSize: 12, color: fgMuted, ); static TextStyle get mono => TextStyle( fontFamily: fontMono, fontSize: 11, color: fgDim, letterSpacing: 0.4, ); static TextStyle get monoStrong => TextStyle( fontFamily: fontMono, fontSize: 11, color: fg, fontWeight: FontWeight.w500, letterSpacing: 0.4, ); // ─── Shadows ────────────────────────────────────────────────────────── static List get shadowLg => [ BoxShadow(color: Colors.black.withOpacity(dark ? 0.6 : 0.12), blurRadius: 40, offset: const Offset(0, 12)), BoxShadow(color: Colors.black.withOpacity(dark ? 0.4 : 0.06), blurRadius: 8, offset: const Offset(0, 2)), ]; }