mit Versionsstempel. */ public static function script(string $path, string $base = '', bool $defer = false): string { return ''; } /** * Theme-Bootstrap: gespeicherte Auswahl, sonst Systemeinstellung. * Muss im
stehen, damit nichts hell aufblitzt. */ public static function themeScript(): string { return ''; } /** Gueltige Hex-Farbe oder Fallback. */ private static function color(?string $value, string $fallback): string { $value = trim((string)$value); return preg_match('/^#[0-9a-fA-F]{6}$/', $value) ? strtolower($value) : $fallback; } /** * CSS-Overrides fuer die Markenfarben. Gibt einen leeren String zurueck, * wenn nichts vom Standard abweicht. */ public static function brandingStyle($db = null): string { if (!$db) { return ''; } $accent = self::color($db->getSetting('brand_accent', ''), self::DEFAULT_ACCENT); $accentDark = self::color($db->getSetting('brand_accent_dark', ''), self::DEFAULT_ACCENT_DARK); $from = self::color($db->getSetting('brand_gradient_from', ''), self::DEFAULT_GRADIENT_FROM); $to = self::color($db->getSetting('brand_gradient_to', ''), self::DEFAULT_GRADIENT_TO); $radius = (int)$db->getSetting('brand_radius', (string)self::DEFAULT_RADIUS); $radius = max(0, min(28, $radius)); $isDefault = $accent === self::DEFAULT_ACCENT && $accentDark === self::DEFAULT_ACCENT_DARK && $from === self::DEFAULT_GRADIENT_FROM && $to === self::DEFAULT_GRADIENT_TO && $radius === self::DEFAULT_RADIUS; if ($isDefault) { return ''; } // Abgeleitete Töne über color-mix – so genügt eine einzige Grundfarbe. return ''; } /** * URL eines Bildes aus den Einstellungen. * Hochgeladene Dateien liegen relativ zur Projektwurzel (uploads/…), * externe Adressen bleiben unveraendert. */ public static function mediaUrl(string $value, string $base = ''): string { $value = trim($value); if ($value === '') { return ''; } if (preg_match('#^(https?:)?//#i', $value) || strncmp($value, 'data:', 5) === 0 || $value[0] === '/') { return $value; } return $base . $value; } /** * Kompletter Standard-Kopf: Favicon, Schrift, Icons, Design-System, * Theme-Bootstrap und Branding. */ public static function head($db = null, string $base = ''): string { $out = []; $favicon = $db ? self::mediaUrl((string)$db->getSetting('favicon_url', ''), $base) : ''; if ($favicon !== '') { $out[] = ''; } $out[] = ''; $out[] = ''; $out[] = ''; $out[] = ''; $out[] = self::themeScript(); $branding = self::brandingStyle($db); if ($branding !== '') { $out[] = $branding; } return implode("\n ", $out); } }