Branding: Farben systemweit einstellbar + Bild-Upload statt nur URLs

Design-Tab (Administration → Einstellungen → Design):
- Akzentfarbe für Hell- und Dark-Mode, Markenverlauf und Eckenradius
- abgeleitete Töne (Hover, weiche Flächen, Fokusring) werden per
  color-mix aus der Grundfarbe berechnet – eine Farbe genügt
- Live-Vorschau mit Button, Badge, Chip, Logo-Kachel und Link
- Ausgabe als schlanker :root-Override über Ui::brandingStyle(), greift
  auf allen Seiten inklusive Login und Installer

Uploads (includes/Upload.php):
- Logo, Favicon, Login-Logo und Login-Hintergrund lassen sich jetzt
  hochladen; das URL-Feld bleibt als Alternative bestehen
- Whitelist nach Endung, 3-MB-Grenze, getimagesize-Prüfung für Raster,
  SVGs werden von Skripten, Event-Handlern und externen Verweisen befreit
- Zufällige Dateinamen in uploads/, dort sperrt eine .htaccess die
  Ausführung von PHP; beim Ersetzen wird die alte Datei gelöscht

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-23 06:27:30 +00:00
parent 6da46f040a
commit 30d0ce3a23
13 changed files with 437 additions and 32 deletions

View file

@ -220,6 +220,28 @@ return [
// Settings
'settings_title' => 'Settings',
'settings_subtitle' => 'System configuration and customization',
'settings_tab_branding' => 'Design',
'settings_branding_intro' => 'Colours and shapes for the whole interface front end and administration.',
'settings_brand_accent' => 'Accent colour (light)',
'settings_brand_accent_hint' => 'Buttons, active navigation, links. Derived shades are calculated automatically.',
'settings_brand_accent_dark' => 'Accent colour (dark mode)',
'settings_brand_accent_dark_hint' => 'Usually a lighter variant of the base colour for dark mode.',
'settings_brand_gradient_from'=> 'Brand gradient: start',
'settings_brand_gradient_to' => 'Brand gradient: end',
'settings_brand_gradient_hint'=> 'Used for the logo tile, avatars and the voucher card.',
'settings_brand_radius' => 'Corner radius',
'settings_brand_radius_sharp' => 'Sharp',
'settings_brand_radius_default'=> 'Default',
'settings_brand_radius_round' => 'Round',
'settings_brand_preview' => 'Preview',
'settings_brand_link' => 'Example link',
'settings_image_url_placeholder' => 'https://… or upload a file',
'settings_image_remove' => 'Remove image',
'settings_upload_hint' => 'PNG, JPG, WEBP, GIF or SVG 3 MB maximum.',
'upload_error_generic' => 'The file could not be uploaded.',
'upload_error_size' => 'The file is too large (3 MB maximum).',
'upload_error_type' => 'This file type is not supported.',
'upload_error_dir' => 'The uploads/ directory is not writable.',
'settings_tab_login' => 'Login page',
'settings_login_intro' => 'Appearance and wording of the sign-in page. Empty fields fall back to the defaults.',
'settings_login_panel' => 'Show left image column (split screen)',
@ -249,8 +271,8 @@ return [
'settings_tab_password' => 'Password',
'settings_saved' => 'Settings saved successfully!',
'settings_app_title' => 'Application Title *',
'settings_logo_url' => 'Logo URL',
'settings_favicon_url' => 'Favicon URL',
'settings_logo_url' => 'Logo',
'settings_favicon_url' => 'Favicon',
'settings_favicon_hint' => 'Browser tab icon (.ico, .png, .svg)',
'settings_instr_header' => 'Instructions - Headline',
'settings_instr_text' => 'Instructions - Text',