diff --git a/frontend/public/logos/QUELLE.md b/frontend/public/logos/QUELLE.md
new file mode 100644
index 0000000..bc8bd10
--- /dev/null
+++ b/frontend/public/logos/QUELLE.md
@@ -0,0 +1,9 @@
+# Logos
+
+Die Logos in diesem Ordner stammen aus **selfh.st/icons** (https://selfh.st/icons, Quelle
+https://github.com/selfhst/icons), Lizenz **Creative Commons Attribution 4.0 International (CC BY 4.0)**. Die Marken
+gehören ihren jeweiligen Inhabern; sie dienen hier nur dazu, die eigenen Dienste im Homelab wiederzuerkennen.
+
+Geladen am 25.09.2026 mit `frontend/scripts/logos_laden.py` (User-Ja): 181 gängige Homelab-Dienste als SVG. Wo das
+Standard-Logo auf dunklem Grund verschwände, steht die helle Variante der Sammlung (Liste HELL im Skript). Die Liste der vorhandenen Namen steht in
+`frontend/src/lib/logos-liste.ts`; ein Dienst ohne Logo bekommt ein gezeichnetes Symbol.
diff --git a/frontend/public/logos/actual-budget.svg b/frontend/public/logos/actual-budget.svg
new file mode 100644
index 0000000..f367fad
--- /dev/null
+++ b/frontend/public/logos/actual-budget.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/adguard-home.svg b/frontend/public/logos/adguard-home.svg
new file mode 100644
index 0000000..e3e837d
--- /dev/null
+++ b/frontend/public/logos/adguard-home.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/affine.svg b/frontend/public/logos/affine.svg
new file mode 100644
index 0000000..7292691
--- /dev/null
+++ b/frontend/public/logos/affine.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/alpine-linux.svg b/frontend/public/logos/alpine-linux.svg
new file mode 100644
index 0000000..e44da77
--- /dev/null
+++ b/frontend/public/logos/alpine-linux.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/ansible.svg b/frontend/public/logos/ansible.svg
new file mode 100644
index 0000000..06e1473
--- /dev/null
+++ b/frontend/public/logos/ansible.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/appflowy.svg b/frontend/public/logos/appflowy.svg
new file mode 100644
index 0000000..26c3504
--- /dev/null
+++ b/frontend/public/logos/appflowy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/apprise.svg b/frontend/public/logos/apprise.svg
new file mode 100644
index 0000000..1fb0dbf
--- /dev/null
+++ b/frontend/public/logos/apprise.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/arcane.svg b/frontend/public/logos/arcane.svg
new file mode 100644
index 0000000..efbcef8
--- /dev/null
+++ b/frontend/public/logos/arcane.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/audiobookshelf.svg b/frontend/public/logos/audiobookshelf.svg
new file mode 100644
index 0000000..634b853
--- /dev/null
+++ b/frontend/public/logos/audiobookshelf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/authelia.svg b/frontend/public/logos/authelia.svg
new file mode 100644
index 0000000..d53db9c
--- /dev/null
+++ b/frontend/public/logos/authelia.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/authentik.svg b/frontend/public/logos/authentik.svg
new file mode 100644
index 0000000..7cbe6ea
--- /dev/null
+++ b/frontend/public/logos/authentik.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/baserow.svg b/frontend/public/logos/baserow.svg
new file mode 100644
index 0000000..3037406
--- /dev/null
+++ b/frontend/public/logos/baserow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/bazarr.svg b/frontend/public/logos/bazarr.svg
new file mode 100644
index 0000000..3cc113e
--- /dev/null
+++ b/frontend/public/logos/bazarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/beszel.svg b/frontend/public/logos/beszel.svg
new file mode 100644
index 0000000..dcd4454
--- /dev/null
+++ b/frontend/public/logos/beszel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/bitwarden.svg b/frontend/public/logos/bitwarden.svg
new file mode 100644
index 0000000..4c59526
--- /dev/null
+++ b/frontend/public/logos/bitwarden.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/bookstack.svg b/frontend/public/logos/bookstack.svg
new file mode 100644
index 0000000..8f8fd9e
--- /dev/null
+++ b/frontend/public/logos/bookstack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/borgmatic.svg b/frontend/public/logos/borgmatic.svg
new file mode 100644
index 0000000..20cd3c9
--- /dev/null
+++ b/frontend/public/logos/borgmatic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/caddy.svg b/frontend/public/logos/caddy.svg
new file mode 100644
index 0000000..6dcb186
--- /dev/null
+++ b/frontend/public/logos/caddy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/calibre-web.svg b/frontend/public/logos/calibre-web.svg
new file mode 100644
index 0000000..3255b8d
--- /dev/null
+++ b/frontend/public/logos/calibre-web.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/changedetection.svg b/frontend/public/logos/changedetection.svg
new file mode 100644
index 0000000..13f42f0
--- /dev/null
+++ b/frontend/public/logos/changedetection.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/checkmk.svg b/frontend/public/logos/checkmk.svg
new file mode 100644
index 0000000..6997f2c
--- /dev/null
+++ b/frontend/public/logos/checkmk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/claude.svg b/frontend/public/logos/claude.svg
new file mode 100644
index 0000000..45d60bc
--- /dev/null
+++ b/frontend/public/logos/claude.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/cloudflare.svg b/frontend/public/logos/cloudflare.svg
new file mode 100644
index 0000000..6245d81
--- /dev/null
+++ b/frontend/public/logos/cloudflare.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/cockpit.svg b/frontend/public/logos/cockpit.svg
new file mode 100644
index 0000000..10d4c50
--- /dev/null
+++ b/frontend/public/logos/cockpit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/comfyui.svg b/frontend/public/logos/comfyui.svg
new file mode 100644
index 0000000..68e4554
--- /dev/null
+++ b/frontend/public/logos/comfyui.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/crafty-controller.svg b/frontend/public/logos/crafty-controller.svg
new file mode 100644
index 0000000..a18faec
--- /dev/null
+++ b/frontend/public/logos/crafty-controller.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/crowdsec.svg b/frontend/public/logos/crowdsec.svg
new file mode 100644
index 0000000..d0c9288
--- /dev/null
+++ b/frontend/public/logos/crowdsec.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/debian.svg b/frontend/public/logos/debian.svg
new file mode 100644
index 0000000..2f0ebce
--- /dev/null
+++ b/frontend/public/logos/debian.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/deluge.svg b/frontend/public/logos/deluge.svg
new file mode 100644
index 0000000..48b984b
--- /dev/null
+++ b/frontend/public/logos/deluge.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/docker.svg b/frontend/public/logos/docker.svg
new file mode 100644
index 0000000..3a5eba7
--- /dev/null
+++ b/frontend/public/logos/docker.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/dockge.svg b/frontend/public/logos/dockge.svg
new file mode 100644
index 0000000..fdf8a3b
--- /dev/null
+++ b/frontend/public/logos/dockge.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/docmost.svg b/frontend/public/logos/docmost.svg
new file mode 100644
index 0000000..cb579fb
--- /dev/null
+++ b/frontend/public/logos/docmost.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/dozzle.svg b/frontend/public/logos/dozzle.svg
new file mode 100644
index 0000000..8fe9150
--- /dev/null
+++ b/frontend/public/logos/dozzle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/draw-io.svg b/frontend/public/logos/draw-io.svg
new file mode 100644
index 0000000..216bc41
--- /dev/null
+++ b/frontend/public/logos/draw-io.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/duplicati.svg b/frontend/public/logos/duplicati.svg
new file mode 100644
index 0000000..31d4673
--- /dev/null
+++ b/frontend/public/logos/duplicati.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/elasticsearch.svg b/frontend/public/logos/elasticsearch.svg
new file mode 100644
index 0000000..fc10e2a
--- /dev/null
+++ b/frontend/public/logos/elasticsearch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/element.svg b/frontend/public/logos/element.svg
new file mode 100644
index 0000000..51db6de
--- /dev/null
+++ b/frontend/public/logos/element.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/emby.svg b/frontend/public/logos/emby.svg
new file mode 100644
index 0000000..63a0594
--- /dev/null
+++ b/frontend/public/logos/emby.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/esphome.svg b/frontend/public/logos/esphome.svg
new file mode 100644
index 0000000..5388901
--- /dev/null
+++ b/frontend/public/logos/esphome.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/excalidraw.svg b/frontend/public/logos/excalidraw.svg
new file mode 100644
index 0000000..31b89f9
--- /dev/null
+++ b/frontend/public/logos/excalidraw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/firefly-iii.svg b/frontend/public/logos/firefly-iii.svg
new file mode 100644
index 0000000..c8b0d2f
--- /dev/null
+++ b/frontend/public/logos/firefly-iii.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/flatnotes.svg b/frontend/public/logos/flatnotes.svg
new file mode 100644
index 0000000..029cad9
--- /dev/null
+++ b/frontend/public/logos/flatnotes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/forgejo.svg b/frontend/public/logos/forgejo.svg
new file mode 100644
index 0000000..8d09b27
--- /dev/null
+++ b/frontend/public/logos/forgejo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/freshrss.svg b/frontend/public/logos/freshrss.svg
new file mode 100644
index 0000000..d09a443
--- /dev/null
+++ b/frontend/public/logos/freshrss.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/frigate.svg b/frontend/public/logos/frigate.svg
new file mode 100644
index 0000000..9ba5338
--- /dev/null
+++ b/frontend/public/logos/frigate.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/gatus.svg b/frontend/public/logos/gatus.svg
new file mode 100644
index 0000000..25c990a
--- /dev/null
+++ b/frontend/public/logos/gatus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/gitea.svg b/frontend/public/logos/gitea.svg
new file mode 100644
index 0000000..d9eb11a
--- /dev/null
+++ b/frontend/public/logos/gitea.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/github.svg b/frontend/public/logos/github.svg
new file mode 100644
index 0000000..7914685
--- /dev/null
+++ b/frontend/public/logos/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/gitlab.svg b/frontend/public/logos/gitlab.svg
new file mode 100644
index 0000000..2c7f5a8
--- /dev/null
+++ b/frontend/public/logos/gitlab.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/glance.svg b/frontend/public/logos/glance.svg
new file mode 100644
index 0000000..0902467
--- /dev/null
+++ b/frontend/public/logos/glance.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/glances.svg b/frontend/public/logos/glances.svg
new file mode 100644
index 0000000..aa72ebb
--- /dev/null
+++ b/frontend/public/logos/glances.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/go2rtc.svg b/frontend/public/logos/go2rtc.svg
new file mode 100644
index 0000000..2b71175
--- /dev/null
+++ b/frontend/public/logos/go2rtc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/gotify.svg b/frontend/public/logos/gotify.svg
new file mode 100644
index 0000000..90ee29e
--- /dev/null
+++ b/frontend/public/logos/gotify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/grafana.svg b/frontend/public/logos/grafana.svg
new file mode 100644
index 0000000..c482be9
--- /dev/null
+++ b/frontend/public/logos/grafana.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/grocy.svg b/frontend/public/logos/grocy.svg
new file mode 100644
index 0000000..588e8db
--- /dev/null
+++ b/frontend/public/logos/grocy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/harbor.svg b/frontend/public/logos/harbor.svg
new file mode 100644
index 0000000..c96d4f6
--- /dev/null
+++ b/frontend/public/logos/harbor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/headscale.svg b/frontend/public/logos/headscale.svg
new file mode 100644
index 0000000..316fc34
--- /dev/null
+++ b/frontend/public/logos/headscale.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/healthchecks.svg b/frontend/public/logos/healthchecks.svg
new file mode 100644
index 0000000..8e32461
--- /dev/null
+++ b/frontend/public/logos/healthchecks.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/hedgedoc.svg b/frontend/public/logos/hedgedoc.svg
new file mode 100644
index 0000000..5f412e6
--- /dev/null
+++ b/frontend/public/logos/hedgedoc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/heimdall.svg b/frontend/public/logos/heimdall.svg
new file mode 100644
index 0000000..45ad88e
--- /dev/null
+++ b/frontend/public/logos/heimdall.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/hermes-agent.svg b/frontend/public/logos/hermes-agent.svg
new file mode 100644
index 0000000..51860b2
--- /dev/null
+++ b/frontend/public/logos/hermes-agent.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/homarr.svg b/frontend/public/logos/homarr.svg
new file mode 100644
index 0000000..af80b23
--- /dev/null
+++ b/frontend/public/logos/homarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/home-assistant.svg b/frontend/public/logos/home-assistant.svg
new file mode 100644
index 0000000..f6d0660
--- /dev/null
+++ b/frontend/public/logos/home-assistant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/homebridge.svg b/frontend/public/logos/homebridge.svg
new file mode 100644
index 0000000..e92de90
--- /dev/null
+++ b/frontend/public/logos/homebridge.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/homepage.svg b/frontend/public/logos/homepage.svg
new file mode 100644
index 0000000..f260828
--- /dev/null
+++ b/frontend/public/logos/homepage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/immich-kiosk.svg b/frontend/public/logos/immich-kiosk.svg
new file mode 100644
index 0000000..132e7d3
--- /dev/null
+++ b/frontend/public/logos/immich-kiosk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/immich.svg b/frontend/public/logos/immich.svg
new file mode 100644
index 0000000..5c758ff
--- /dev/null
+++ b/frontend/public/logos/immich.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/influxdb.svg b/frontend/public/logos/influxdb.svg
new file mode 100644
index 0000000..098f537
--- /dev/null
+++ b/frontend/public/logos/influxdb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/it-tools.svg b/frontend/public/logos/it-tools.svg
new file mode 100644
index 0000000..8395b08
--- /dev/null
+++ b/frontend/public/logos/it-tools.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/jellyfin.svg b/frontend/public/logos/jellyfin.svg
new file mode 100644
index 0000000..f1703bb
--- /dev/null
+++ b/frontend/public/logos/jellyfin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/jellyseerr.svg b/frontend/public/logos/jellyseerr.svg
new file mode 100644
index 0000000..e5474e0
--- /dev/null
+++ b/frontend/public/logos/jellyseerr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/jenkins.svg b/frontend/public/logos/jenkins.svg
new file mode 100644
index 0000000..be579f0
--- /dev/null
+++ b/frontend/public/logos/jenkins.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/jitsi-meet.svg b/frontend/public/logos/jitsi-meet.svg
new file mode 100644
index 0000000..656e04d
--- /dev/null
+++ b/frontend/public/logos/jitsi-meet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/joplin.svg b/frontend/public/logos/joplin.svg
new file mode 100644
index 0000000..4719a44
--- /dev/null
+++ b/frontend/public/logos/joplin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/kavita.svg b/frontend/public/logos/kavita.svg
new file mode 100644
index 0000000..60815de
--- /dev/null
+++ b/frontend/public/logos/kavita.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/keycloak.svg b/frontend/public/logos/keycloak.svg
new file mode 100644
index 0000000..d8f1342
--- /dev/null
+++ b/frontend/public/logos/keycloak.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/komga.svg b/frontend/public/logos/komga.svg
new file mode 100644
index 0000000..4498aa6
--- /dev/null
+++ b/frontend/public/logos/komga.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/komodo.svg b/frontend/public/logos/komodo.svg
new file mode 100644
index 0000000..6521d64
--- /dev/null
+++ b/frontend/public/logos/komodo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/kopia.svg b/frontend/public/logos/kopia.svg
new file mode 100644
index 0000000..7edb033
--- /dev/null
+++ b/frontend/public/logos/kopia.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/kubernetes.svg b/frontend/public/logos/kubernetes.svg
new file mode 100644
index 0000000..55807cb
--- /dev/null
+++ b/frontend/public/logos/kubernetes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/librenms.svg b/frontend/public/logos/librenms.svg
new file mode 100644
index 0000000..2b80638
--- /dev/null
+++ b/frontend/public/logos/librenms.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/librespeed.svg b/frontend/public/logos/librespeed.svg
new file mode 100644
index 0000000..c76c99e
--- /dev/null
+++ b/frontend/public/logos/librespeed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/lidarr.svg b/frontend/public/logos/lidarr.svg
new file mode 100644
index 0000000..f25f408
--- /dev/null
+++ b/frontend/public/logos/lidarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/linkding.svg b/frontend/public/logos/linkding.svg
new file mode 100644
index 0000000..076381f
--- /dev/null
+++ b/frontend/public/logos/linkding.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/linux-containers-lxc.svg b/frontend/public/logos/linux-containers-lxc.svg
new file mode 100644
index 0000000..7a0940d
--- /dev/null
+++ b/frontend/public/logos/linux-containers-lxc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/linux.svg b/frontend/public/logos/linux.svg
new file mode 100644
index 0000000..2fed596
--- /dev/null
+++ b/frontend/public/logos/linux.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/linuxserver-io.svg b/frontend/public/logos/linuxserver-io.svg
new file mode 100644
index 0000000..59a2229
--- /dev/null
+++ b/frontend/public/logos/linuxserver-io.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/llama-cpp.svg b/frontend/public/logos/llama-cpp.svg
new file mode 100644
index 0000000..019ea69
--- /dev/null
+++ b/frontend/public/logos/llama-cpp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/logseq.svg b/frontend/public/logos/logseq.svg
new file mode 100644
index 0000000..e8a04ea
--- /dev/null
+++ b/frontend/public/logos/logseq.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/loki.svg b/frontend/public/logos/loki.svg
new file mode 100644
index 0000000..a99d8b7
--- /dev/null
+++ b/frontend/public/logos/loki.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/mariadb.svg b/frontend/public/logos/mariadb.svg
new file mode 100644
index 0000000..1ca8f33
--- /dev/null
+++ b/frontend/public/logos/mariadb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/matomo.svg b/frontend/public/logos/matomo.svg
new file mode 100644
index 0000000..5ea621a
--- /dev/null
+++ b/frontend/public/logos/matomo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/matrix.svg b/frontend/public/logos/matrix.svg
new file mode 100644
index 0000000..ad7bc80
--- /dev/null
+++ b/frontend/public/logos/matrix.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/mattermost.svg b/frontend/public/logos/mattermost.svg
new file mode 100644
index 0000000..ac97647
--- /dev/null
+++ b/frontend/public/logos/mattermost.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/mealie.svg b/frontend/public/logos/mealie.svg
new file mode 100644
index 0000000..f24e466
--- /dev/null
+++ b/frontend/public/logos/mealie.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/minecraft.svg b/frontend/public/logos/minecraft.svg
new file mode 100644
index 0000000..74200a8
--- /dev/null
+++ b/frontend/public/logos/minecraft.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/miniflux.svg b/frontend/public/logos/miniflux.svg
new file mode 100644
index 0000000..0b2968b
--- /dev/null
+++ b/frontend/public/logos/miniflux.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/minio.svg b/frontend/public/logos/minio.svg
new file mode 100644
index 0000000..d4f4b05
--- /dev/null
+++ b/frontend/public/logos/minio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/mongodb.svg b/frontend/public/logos/mongodb.svg
new file mode 100644
index 0000000..ca5c8c8
--- /dev/null
+++ b/frontend/public/logos/mongodb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/mosquitto.svg b/frontend/public/logos/mosquitto.svg
new file mode 100644
index 0000000..69cb6be
--- /dev/null
+++ b/frontend/public/logos/mosquitto.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/n8n.svg b/frontend/public/logos/n8n.svg
new file mode 100644
index 0000000..8236d9e
--- /dev/null
+++ b/frontend/public/logos/n8n.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/navidrome.svg b/frontend/public/logos/navidrome.svg
new file mode 100644
index 0000000..5d567f7
--- /dev/null
+++ b/frontend/public/logos/navidrome.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/netbird.svg b/frontend/public/logos/netbird.svg
new file mode 100644
index 0000000..27c13a8
--- /dev/null
+++ b/frontend/public/logos/netbird.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/netdata.svg b/frontend/public/logos/netdata.svg
new file mode 100644
index 0000000..5f00d6a
--- /dev/null
+++ b/frontend/public/logos/netdata.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/nextcloud.svg b/frontend/public/logos/nextcloud.svg
new file mode 100644
index 0000000..336aff5
--- /dev/null
+++ b/frontend/public/logos/nextcloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/nginx-proxy-manager.svg b/frontend/public/logos/nginx-proxy-manager.svg
new file mode 100644
index 0000000..14de3d3
--- /dev/null
+++ b/frontend/public/logos/nginx-proxy-manager.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/nginx.svg b/frontend/public/logos/nginx.svg
new file mode 100644
index 0000000..844bd13
--- /dev/null
+++ b/frontend/public/logos/nginx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/nocodb.svg b/frontend/public/logos/nocodb.svg
new file mode 100644
index 0000000..9a07e4b
--- /dev/null
+++ b/frontend/public/logos/nocodb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/node-red.svg b/frontend/public/logos/node-red.svg
new file mode 100644
index 0000000..108b312
--- /dev/null
+++ b/frontend/public/logos/node-red.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/ntfy.svg b/frontend/public/logos/ntfy.svg
new file mode 100644
index 0000000..aa3c2e9
--- /dev/null
+++ b/frontend/public/logos/ntfy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/nzbget.svg b/frontend/public/logos/nzbget.svg
new file mode 100644
index 0000000..0421875
--- /dev/null
+++ b/frontend/public/logos/nzbget.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/obsidian.svg b/frontend/public/logos/obsidian.svg
new file mode 100644
index 0000000..6b75120
--- /dev/null
+++ b/frontend/public/logos/obsidian.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/ollama.svg b/frontend/public/logos/ollama.svg
new file mode 100644
index 0000000..4f534cf
--- /dev/null
+++ b/frontend/public/logos/ollama.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/onlyoffice.svg b/frontend/public/logos/onlyoffice.svg
new file mode 100644
index 0000000..87209b5
--- /dev/null
+++ b/frontend/public/logos/onlyoffice.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/open-webui.svg b/frontend/public/logos/open-webui.svg
new file mode 100644
index 0000000..8f5380b
--- /dev/null
+++ b/frontend/public/logos/open-webui.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/openai.svg b/frontend/public/logos/openai.svg
new file mode 100644
index 0000000..4be2414
--- /dev/null
+++ b/frontend/public/logos/openai.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/openmediavault.svg b/frontend/public/logos/openmediavault.svg
new file mode 100644
index 0000000..8f4cf3f
--- /dev/null
+++ b/frontend/public/logos/openmediavault.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/openwrt.svg b/frontend/public/logos/openwrt.svg
new file mode 100644
index 0000000..021ac94
--- /dev/null
+++ b/frontend/public/logos/openwrt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/opnsense.svg b/frontend/public/logos/opnsense.svg
new file mode 100644
index 0000000..aeedf2a
--- /dev/null
+++ b/frontend/public/logos/opnsense.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/outline.svg b/frontend/public/logos/outline.svg
new file mode 100644
index 0000000..b1a7bbe
--- /dev/null
+++ b/frontend/public/logos/outline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/overseerr.svg b/frontend/public/logos/overseerr.svg
new file mode 100644
index 0000000..d586c23
--- /dev/null
+++ b/frontend/public/logos/overseerr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/paperless-ngx.svg b/frontend/public/logos/paperless-ngx.svg
new file mode 100644
index 0000000..c0b7489
--- /dev/null
+++ b/frontend/public/logos/paperless-ngx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/penpot.svg b/frontend/public/logos/penpot.svg
new file mode 100644
index 0000000..37e1b94
--- /dev/null
+++ b/frontend/public/logos/penpot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/pfsense.svg b/frontend/public/logos/pfsense.svg
new file mode 100644
index 0000000..1b9e6c5
--- /dev/null
+++ b/frontend/public/logos/pfsense.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/photoprism.svg b/frontend/public/logos/photoprism.svg
new file mode 100644
index 0000000..b7fb84d
--- /dev/null
+++ b/frontend/public/logos/photoprism.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/pi-hole.svg b/frontend/public/logos/pi-hole.svg
new file mode 100644
index 0000000..d096cd9
--- /dev/null
+++ b/frontend/public/logos/pi-hole.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/pingvin-share.svg b/frontend/public/logos/pingvin-share.svg
new file mode 100644
index 0000000..894677e
--- /dev/null
+++ b/frontend/public/logos/pingvin-share.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/piwigo.svg b/frontend/public/logos/piwigo.svg
new file mode 100644
index 0000000..888194e
--- /dev/null
+++ b/frontend/public/logos/piwigo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/planka.svg b/frontend/public/logos/planka.svg
new file mode 100644
index 0000000..9686cda
--- /dev/null
+++ b/frontend/public/logos/planka.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/plausible.svg b/frontend/public/logos/plausible.svg
new file mode 100644
index 0000000..6e960e4
--- /dev/null
+++ b/frontend/public/logos/plausible.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/plex.svg b/frontend/public/logos/plex.svg
new file mode 100644
index 0000000..ae62ba7
--- /dev/null
+++ b/frontend/public/logos/plex.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/portainer.svg b/frontend/public/logos/portainer.svg
new file mode 100644
index 0000000..30ea408
--- /dev/null
+++ b/frontend/public/logos/portainer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/postgresql.svg b/frontend/public/logos/postgresql.svg
new file mode 100644
index 0000000..03078fb
--- /dev/null
+++ b/frontend/public/logos/postgresql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/privatebin.svg b/frontend/public/logos/privatebin.svg
new file mode 100644
index 0000000..c57aedb
--- /dev/null
+++ b/frontend/public/logos/privatebin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/prometheus.svg b/frontend/public/logos/prometheus.svg
new file mode 100644
index 0000000..da19fd6
--- /dev/null
+++ b/frontend/public/logos/prometheus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/prowlarr.svg b/frontend/public/logos/prowlarr.svg
new file mode 100644
index 0000000..b0adcbc
--- /dev/null
+++ b/frontend/public/logos/prowlarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/proxmox-helper-scripts.svg b/frontend/public/logos/proxmox-helper-scripts.svg
new file mode 100644
index 0000000..3f45249
--- /dev/null
+++ b/frontend/public/logos/proxmox-helper-scripts.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/proxmox.svg b/frontend/public/logos/proxmox.svg
new file mode 100644
index 0000000..b5fd75f
--- /dev/null
+++ b/frontend/public/logos/proxmox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/pterodactyl.svg b/frontend/public/logos/pterodactyl.svg
new file mode 100644
index 0000000..171809c
--- /dev/null
+++ b/frontend/public/logos/pterodactyl.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/qbittorrent.svg b/frontend/public/logos/qbittorrent.svg
new file mode 100644
index 0000000..9a8dd44
--- /dev/null
+++ b/frontend/public/logos/qbittorrent.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/qnap.svg b/frontend/public/logos/qnap.svg
new file mode 100644
index 0000000..0a22afd
--- /dev/null
+++ b/frontend/public/logos/qnap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/rabbitmq.svg b/frontend/public/logos/rabbitmq.svg
new file mode 100644
index 0000000..4983ad5
--- /dev/null
+++ b/frontend/public/logos/rabbitmq.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/radarr.svg b/frontend/public/logos/radarr.svg
new file mode 100644
index 0000000..44af49b
--- /dev/null
+++ b/frontend/public/logos/radarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/rancher.svg b/frontend/public/logos/rancher.svg
new file mode 100644
index 0000000..b422383
--- /dev/null
+++ b/frontend/public/logos/rancher.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/rclone.svg b/frontend/public/logos/rclone.svg
new file mode 100644
index 0000000..acac61a
--- /dev/null
+++ b/frontend/public/logos/rclone.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/readarr.svg b/frontend/public/logos/readarr.svg
new file mode 100644
index 0000000..958ef16
--- /dev/null
+++ b/frontend/public/logos/readarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/redis.svg b/frontend/public/logos/redis.svg
new file mode 100644
index 0000000..f06a275
--- /dev/null
+++ b/frontend/public/logos/redis.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/rocket-chat.svg b/frontend/public/logos/rocket-chat.svg
new file mode 100644
index 0000000..f6dcce4
--- /dev/null
+++ b/frontend/public/logos/rocket-chat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/rustdesk.svg b/frontend/public/logos/rustdesk.svg
new file mode 100644
index 0000000..981feb8
--- /dev/null
+++ b/frontend/public/logos/rustdesk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/sabnzbd.svg b/frontend/public/logos/sabnzbd.svg
new file mode 100644
index 0000000..a2a0c61
--- /dev/null
+++ b/frontend/public/logos/sabnzbd.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/scrutiny.svg b/frontend/public/logos/scrutiny.svg
new file mode 100644
index 0000000..ca5bf80
--- /dev/null
+++ b/frontend/public/logos/scrutiny.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/scrypted.svg b/frontend/public/logos/scrypted.svg
new file mode 100644
index 0000000..793a448
--- /dev/null
+++ b/frontend/public/logos/scrypted.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/seafile.svg b/frontend/public/logos/seafile.svg
new file mode 100644
index 0000000..845ebc0
--- /dev/null
+++ b/frontend/public/logos/seafile.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/searxng.svg b/frontend/public/logos/searxng.svg
new file mode 100644
index 0000000..26290eb
--- /dev/null
+++ b/frontend/public/logos/searxng.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/semaphore.svg b/frontend/public/logos/semaphore.svg
new file mode 100644
index 0000000..f0b7ec6
--- /dev/null
+++ b/frontend/public/logos/semaphore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/sonarr.svg b/frontend/public/logos/sonarr.svg
new file mode 100644
index 0000000..54108f4
--- /dev/null
+++ b/frontend/public/logos/sonarr.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/speedtest-tracker.svg b/frontend/public/logos/speedtest-tracker.svg
new file mode 100644
index 0000000..2318712
--- /dev/null
+++ b/frontend/public/logos/speedtest-tracker.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/stirling-pdf.svg b/frontend/public/logos/stirling-pdf.svg
new file mode 100644
index 0000000..f322d83
--- /dev/null
+++ b/frontend/public/logos/stirling-pdf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/syncthing.svg b/frontend/public/logos/syncthing.svg
new file mode 100644
index 0000000..fa5320f
--- /dev/null
+++ b/frontend/public/logos/syncthing.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/synology.svg b/frontend/public/logos/synology.svg
new file mode 100644
index 0000000..67b1445
--- /dev/null
+++ b/frontend/public/logos/synology.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/tailscale.svg b/frontend/public/logos/tailscale.svg
new file mode 100644
index 0000000..64dd14c
--- /dev/null
+++ b/frontend/public/logos/tailscale.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/tautulli.svg b/frontend/public/logos/tautulli.svg
new file mode 100644
index 0000000..917a2a9
--- /dev/null
+++ b/frontend/public/logos/tautulli.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/telegram.svg b/frontend/public/logos/telegram.svg
new file mode 100644
index 0000000..5b360f5
--- /dev/null
+++ b/frontend/public/logos/telegram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/traefik.svg b/frontend/public/logos/traefik.svg
new file mode 100644
index 0000000..319e1d2
--- /dev/null
+++ b/frontend/public/logos/traefik.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/transmission.svg b/frontend/public/logos/transmission.svg
new file mode 100644
index 0000000..382d7e4
--- /dev/null
+++ b/frontend/public/logos/transmission.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/ubuntu.svg b/frontend/public/logos/ubuntu.svg
new file mode 100644
index 0000000..f9c0942
--- /dev/null
+++ b/frontend/public/logos/ubuntu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/umami.svg b/frontend/public/logos/umami.svg
new file mode 100644
index 0000000..3124397
--- /dev/null
+++ b/frontend/public/logos/umami.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/unraid.svg b/frontend/public/logos/unraid.svg
new file mode 100644
index 0000000..6287894
--- /dev/null
+++ b/frontend/public/logos/unraid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/uptime-kuma.svg b/frontend/public/logos/uptime-kuma.svg
new file mode 100644
index 0000000..5f8909b
--- /dev/null
+++ b/frontend/public/logos/uptime-kuma.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/vaultwarden.svg b/frontend/public/logos/vaultwarden.svg
new file mode 100644
index 0000000..6a88fba
--- /dev/null
+++ b/frontend/public/logos/vaultwarden.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/vikunja.svg b/frontend/public/logos/vikunja.svg
new file mode 100644
index 0000000..2b713af
--- /dev/null
+++ b/frontend/public/logos/vikunja.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/wallabag.svg b/frontend/public/logos/wallabag.svg
new file mode 100644
index 0000000..f997455
--- /dev/null
+++ b/frontend/public/logos/wallabag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/watchtower.svg b/frontend/public/logos/watchtower.svg
new file mode 100644
index 0000000..1474afa
--- /dev/null
+++ b/frontend/public/logos/watchtower.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/webmin.svg b/frontend/public/logos/webmin.svg
new file mode 100644
index 0000000..e9c97ef
--- /dev/null
+++ b/frontend/public/logos/webmin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/wekan.svg b/frontend/public/logos/wekan.svg
new file mode 100644
index 0000000..de5d24c
--- /dev/null
+++ b/frontend/public/logos/wekan.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/wiki-js.svg b/frontend/public/logos/wiki-js.svg
new file mode 100644
index 0000000..c87927e
--- /dev/null
+++ b/frontend/public/logos/wiki-js.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/wireguard.svg b/frontend/public/logos/wireguard.svg
new file mode 100644
index 0000000..c571f03
--- /dev/null
+++ b/frontend/public/logos/wireguard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/woodpecker-ci.svg b/frontend/public/logos/woodpecker-ci.svg
new file mode 100644
index 0000000..6a816f4
--- /dev/null
+++ b/frontend/public/logos/woodpecker-ci.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/wordpress.svg b/frontend/public/logos/wordpress.svg
new file mode 100644
index 0000000..ec09c05
--- /dev/null
+++ b/frontend/public/logos/wordpress.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/zabbix.svg b/frontend/public/logos/zabbix.svg
new file mode 100644
index 0000000..2997d11
--- /dev/null
+++ b/frontend/public/logos/zabbix.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/logos/zigbee2mqtt.svg b/frontend/public/logos/zigbee2mqtt.svg
new file mode 100644
index 0000000..08eca76
--- /dev/null
+++ b/frontend/public/logos/zigbee2mqtt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/scripts/logos_laden.py b/frontend/scripts/logos_laden.py
new file mode 100644
index 0000000..efe7995
--- /dev/null
+++ b/frontend/scripts/logos_laden.py
@@ -0,0 +1,73 @@
+"""Logos der Homelab-Dienste von selfh.st/icons laden (CC BY 4.0) — seit 25.09.2026.
+
+Holt für jede Referenz in WUNSCH das SVG nach frontend/public/logos/.svg und schreibt die Liste der
+vorhandenen Namen nach frontend/src/lib/logos-liste.ts (die Oberfläche fragt dort nach, ob es ein Logo gibt). Wo das
+Standard-Logo auf dem dunklen Grund verschwände, steht es in HELL: dann kommt die helle Variante der Sammlung. Die
+Liste HELL ist am 25.09.2026 gemessen worden (jedes Logo auf den Kachelgrund gezeichnet, Anteil sichtbarer Pixel).
+
+Neue Dienste: Referenz aus https://selfh.st/icons in WUNSCH eintragen (ggf. auch in HELL) und laufen lassen:
+ python frontend/scripts/logos_laden.py
+Ohne Netz nach cdn.jsdelivr.net geht es nicht; die Oberfläche lädt Logos nie aus dem Netz, nur aus diesem Ordner.
+"""
+import sys
+import urllib.request
+from pathlib import Path
+
+REPO = Path(__file__).resolve().parents[2]
+ZIEL = REPO / "frontend" / "public" / "logos"
+LISTE = REPO / "frontend" / "src" / "lib" / "logos-liste.ts"
+BASIS = "https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/"
+
+WUNSCH = """
+actual-budget adguard-home affine alpine-linux ansible appflowy apprise arcane audiobookshelf authelia authentik baserow
+bazarr beszel bitwarden bookstack borgmatic caddy calibre-web changedetection checkmk claude cloudflare cockpit comfyui
+crafty-controller crowdsec debian deluge docker dockge docmost dozzle draw-io duplicati elasticsearch element emby
+esphome excalidraw firefly-iii flatnotes forgejo freshrss frigate gatus gitea github gitlab glance glances go2rtc
+gotify grafana grocy harbor headscale healthchecks hedgedoc heimdall hermes-agent homarr home-assistant homebridge
+homepage immich immich-kiosk influxdb it-tools jellyfin jellyseerr jenkins jitsi-meet joplin kavita keycloak kopia
+komga komodo kubernetes librenms librespeed lidarr linkding linux linux-containers-lxc linuxserver-io llama-cpp loki
+logseq mariadb matomo matrix mattermost mealie minecraft miniflux minio mongodb mosquitto n8n navidrome netbird
+netdata nextcloud nginx nginx-proxy-manager nocodb node-red ntfy nzbget obsidian ollama onlyoffice open-webui openai
+openmediavault openwrt opnsense outline overseerr paperless-ngx penpot pfsense photoprism pi-hole pingvin-share piwigo
+planka plausible plex portainer postgresql privatebin prometheus prowlarr proxmox proxmox-helper-scripts pterodactyl
+qbittorrent qnap rabbitmq radarr rancher rclone readarr redis rocket-chat rustdesk sabnzbd scrutiny scrypted seafile
+searxng semaphore sonarr speedtest-tracker stirling-pdf syncthing synology tailscale tautulli telegram traefik
+transmission ubuntu umami unraid uptime-kuma vaultwarden vikunja wallabag watchtower webmin wekan wiki-js wireguard
+woodpecker-ci wordpress zabbix zigbee2mqtt
+""".split()
+
+# Auf dunklem Grund zu dunkel → helle Variante der Sammlung.
+HELL = set("""
+affine borgmatic cockpit crafty-controller debian docmost frigate github go2rtc healthchecks heimdall hermes-agent
+homebridge influxdb logseq matrix mattermost miniflux minio node-red openai outline penpot pfsense portainer radarr scrutiny semaphore tailscale umami vaultwarden wallabag wireguard
+""".split())
+
+
+def laden(ref: str) -> bytes:
+ name = f"{ref}-light.svg" if ref in HELL else f"{ref}.svg"
+ with urllib.request.urlopen(BASIS + name, timeout=30) as antwort:
+ return antwort.read()
+
+
+def main() -> int:
+ ZIEL.mkdir(parents=True, exist_ok=True)
+ fehlt = []
+ for ref in dict.fromkeys(WUNSCH):
+ try:
+ (ZIEL / f"{ref}.svg").write_bytes(laden(ref))
+ except Exception as exc: # ein fehlendes Logo ist kein Beinbruch: dann bleibt das Symbol
+ fehlt.append(f"{ref} ({exc})")
+ vorhanden = sorted(p.stem for p in ZIEL.glob("*.svg"))
+ zeilen = "\n".join(f' "{r}",' for r in vorhanden)
+ LISTE.write_bytes((
+ "// Erzeugt von frontend/scripts/logos_laden.py: die Logos unter /logos/.svg (selfh.st/icons, CC BY 4.0).\n"
+ "// Nicht von Hand pflegen — neue Logos mit demselben Skript holen.\n"
+ f"export const LOGOS: ReadonlySet = new Set([\n{zeilen}\n])\n").encode("utf-8"))
+ print(f"{len(vorhanden)} Logos in {ZIEL}")
+ if fehlt:
+ print("nicht geladen:", ", ".join(fehlt))
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/frontend/src/components/cockpit/Geraetesymbol.tsx b/frontend/src/components/cockpit/Geraetesymbol.tsx
index 0cdde6a..dec2cc7 100644
--- a/frontend/src/components/cockpit/Geraetesymbol.tsx
+++ b/frontend/src/components/cockpit/Geraetesymbol.tsx
@@ -1,26 +1,32 @@
import { cn } from "cn"
import { type Geraetebild, PUNKT, type Punktzustand } from "@/lib/geraetebild"
-// Kachel in der Farbe des Bereichs; Zustände trägt nur der Punkt (grün/bernstein/rot/cyan) — nie das Symbol.
+// Kachel in der Farbe des Bereichs; Zustände trägt nur der Punkt (grün/bernstein/rot/cyan) — nie das Bild.
+// Mit echtem Logo wird die Kachel neutral (sonst färbte das Violett die Markenfarben), nur der Rand behält den Bereich.
const BEREICH = {
box: "from-box/30 to-box/[0.05] ring-box/35 text-box-text",
homelab: "from-lab/30 to-lab/[0.05] ring-lab/35 text-lab-text",
} as const
+const LOGO_KACHEL = {
+ box: "from-white/[0.1] to-white/[0.03] ring-box/30",
+ homelab: "from-white/[0.1] to-white/[0.03] ring-lab/30",
+} as const
+
const LEUCHTEN = {
box: "shadow-[0_0_28px_-6px_var(--box)]",
homelab: "shadow-[0_0_28px_-6px_var(--lab)]",
} as const
const GROESSE = {
- sm: { kachel: "size-8 rounded-[10px]", icon: "size-4", punkt: "size-2.5" },
- md: { kachel: "size-10 rounded-xl", icon: "size-5", punkt: "size-2.5" },
- lg: { kachel: "size-12 rounded-2xl", icon: "size-6", punkt: "size-3" },
+ sm: { kachel: "size-8 rounded-[10px]", icon: "size-4", logo: "size-5", punkt: "size-2.5" },
+ md: { kachel: "size-10 rounded-xl", icon: "size-5", logo: "size-6", punkt: "size-2.5" },
+ lg: { kachel: "size-12 rounded-2xl", icon: "size-6", logo: "size-7", punkt: "size-3" },
} as const
/**
- * Das Symbol eines Geräts oder Dienstes als kleine Kachel, optional mit Zustandspunkt unten rechts. Rein
- * schmückend (aria-hidden) — Name und Zustand stehen daneben als Text.
+ * Das Bild eines Geräts oder Dienstes als kleine Kachel — das echte Logo, wo es eines gibt, sonst ein Symbol —,
+ * optional mit Zustandspunkt unten rechts. Rein schmückend (aria-hidden): Name und Zustand stehen daneben als Text.
*/
export function Geraetesymbol({ bild, groesse = "md", punkt, leuchtet = false, className }: {
bild: Geraetebild
@@ -36,10 +42,13 @@ export function Geraetesymbol({ bild, groesse = "md", punkt, leuchtet = false, c
aria-hidden
className={cn(
"relative inline-flex shrink-0 items-center justify-center bg-gradient-to-br ring-1 ring-inset",
- BEREICH[bild.bereich], g.kachel, leuchtet && LEUCHTEN[bild.bereich], className,
+ bild.logo ? LOGO_KACHEL[bild.bereich] : BEREICH[bild.bereich], g.kachel, leuchtet && LEUCHTEN[bild.bereich],
+ className,
)}
>
-
+ {bild.logo
+ ?
+ : }
{punkt && (
)}
diff --git a/frontend/src/lib/geraetebild.ts b/frontend/src/lib/geraetebild.ts
index 39ba329..0951f23 100644
--- a/frontend/src/lib/geraetebild.ts
+++ b/frontend/src/lib/geraetebild.ts
@@ -2,15 +2,19 @@ import {
Bird, Bot, Box, BrainCircuit, Clapperboard, Code, Container, DatabaseBackup, FileCode2, GitBranch, HardDrive, House,
Layers, type LucideIcon, Monitor, Route, Server, ShieldCheck, Shuffle, Workflow, Zap,
} from "lucide-react"
+import { LOGOS } from "@/lib/logos-liste"
import type { Bereich } from "@/lib/navigation"
-// Jedes Gerät bekommt ein eigenes Symbol (Design v5, 25.09.2026) — wie bei Heimdall, Dashy oder Homepage erkennt
-// man es so auf einen Blick. Die Farbe bleibt die des Bereichs (Indigo KI-Box, Violett Homelab): Farben für
-// Zustände (grün, bernstein, rot, cyan) tragen nur Punkte und Schildchen, nie das Symbol.
+// Jedes Gerät bekommt ein eigenes Bild (Design v5, 25.09.2026) — wie bei Heimdall, Dashy oder Homepage erkennt man
+// es so auf einen Blick: das echte Logo (selfh.st/icons, CC BY 4.0, mitgeliefert unter /logos), sonst ein
+// gezeichnetes Symbol in der Farbe des Bereichs. Farben für Zustände (grün, bernstein, rot, cyan) tragen nur Punkte
+// und Schildchen, nie das Bild.
export interface Geraetebild {
Icon: LucideIcon
bereich: Bereich
+ /** Name eines mitgelieferten Logos (/logos/.svg), wo es eines gibt. */
+ logo?: string
}
export type Punktzustand = "ok" | "warn" | "rot" | "info" | "aus"
@@ -24,44 +28,63 @@ export const PUNKT: Record = {
aus: "bg-text-3",
}
-// Nach dem Namen, weil die ID nur die Nummer kennt. Reihenfolge zählt: Spezielles vor Allgemeinem.
-const NACH_NAME: [RegExp, LucideIcon][] = [
+// Nach dem Namen, weil die ID nur die Nummer kennt. Reihenfolge zählt: Spezielles vor Allgemeinem. Der dritte Wert
+// nennt das Logo, wo der Name allein nicht darauf führt.
+const NACH_NAME: [RegExp, LucideIcon, string?][] = [
[/adguard|pi-?hole/i, ShieldCheck],
- [/npm|nginx proxy|traefik|caddy/i, Route],
+ [/npm|nginx proxy/i, Route, "nginx-proxy-manager"],
+ [/traefik|caddy/i, Route],
[/netbird|wireguard|tailscale/i, Bird],
[/gitea|forgejo|gitlab/i, GitBranch],
- [/backup server|\bpbs\b/i, DatabaseBackup],
+ // Proxmox Backup Server trägt das Proxmox-Zeichen.
+ [/backup server|\bpbs\b/i, DatabaseBackup, "proxmox"],
[/arcane|docker|portainer|dockge|komodo/i, Container],
+ [/pve scripts|helper.?scripts|community.?scripts/i, FileCode2, "proxmox-helper-scripts"],
[/scripts/i, FileCode2],
[/home ?assistant/i, House],
[/jellyfin|plex|emby/i, Clapperboard],
[/\bnas\b|qnap|truenas|synology/i, HardDrive],
]
-/** Das Symbol eines Geräts im Ziel-Modell (KI-Box, Proxmox-Host, Container, VM). */
+/** „Arcane (Docker)“ → „arcane“, „AdGuard Home“ → „adguard-home“. */
+export function logoName(name: string): string {
+ return name.toLowerCase().replace(/\(.*?\)/g, "").trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")
+}
+
+/** Das Logo zu einem Namen, wo es eines gibt: fester Eintrag der Liste oben, sonst der Name selbst. */
+function logoFuer(name: string, fest?: string): string | undefined {
+ if (fest && LOGOS.has(fest)) return fest
+ const kandidat = logoName(name)
+ if (LOGOS.has(kandidat)) return kandidat
+ const erstesWort = kandidat.split("-")[0]
+ return erstesWort.length > 2 && LOGOS.has(erstesWort) ? erstesWort : undefined
+}
+
+/** Das Bild eines Geräts im Ziel-Modell (KI-Box, Proxmox-Host, Container, VM). */
export function geraetebild(ziel: { art: string; name: string }): Geraetebild {
if (ziel.art === "ki-box") return { Icon: BrainCircuit, bereich: "box" }
- if (ziel.art === "proxmox-host") return { Icon: Server, bereich: "homelab" }
+ if (ziel.art === "proxmox-host") return { Icon: Server, bereich: "homelab", logo: logoFuer("proxmox") }
const treffer = NACH_NAME.find(([muster]) => muster.test(ziel.name))
- if (treffer) return { Icon: treffer[1], bereich: "homelab" }
- return { Icon: ziel.art === "vm" ? Monitor : Box, bereich: "homelab" }
+ const Icon = treffer?.[1] ?? (ziel.art === "vm" ? Monitor : Box)
+ return { Icon, bereich: "homelab", logo: logoFuer(ziel.name, treffer?.[2]) }
}
// Die Bausteine der KI-Box (GET /api/ziele) und die Lampen der Startdaten (GET /api/start).
-const KI_BOX: Record = {
- os: Layers,
- engine: Zap,
- motor: Zap,
- swap: Shuffle,
- hermes: Bot,
- hirn: BrainCircuit,
- coder: Code,
- jobs: Workflow,
- sicherung: DatabaseBackup,
- platte: HardDrive,
+const KI_BOX: Record = {
+ os: [Layers, "ubuntu"],
+ engine: [Zap, "llama-cpp"],
+ motor: [Zap, "llama-cpp"],
+ swap: [Shuffle],
+ hermes: [Bot, "hermes-agent"],
+ hirn: [BrainCircuit],
+ coder: [Code],
+ jobs: [Workflow],
+ sicherung: [DatabaseBackup],
+ platte: [HardDrive],
}
-/** Das Symbol eines Bausteins oder einer Lampe der KI-Box. */
+/** Das Bild eines Bausteins oder einer Lampe der KI-Box. */
export function boxbild(id: string): Geraetebild {
- return { Icon: KI_BOX[id] ?? Box, bereich: "box" }
+ const [Icon, logo] = KI_BOX[id] ?? [Box]
+ return { Icon, bereich: "box", logo: logo && LOGOS.has(logo) ? logo : undefined }
}
diff --git a/frontend/src/lib/logos-liste.ts b/frontend/src/lib/logos-liste.ts
new file mode 100644
index 0000000..a89fac0
--- /dev/null
+++ b/frontend/src/lib/logos-liste.ts
@@ -0,0 +1,185 @@
+// Erzeugt von frontend/scripts/logos_laden.py: die Logos unter /logos/.svg (selfh.st/icons, CC BY 4.0).
+// Nicht von Hand pflegen — neue Logos mit demselben Skript holen.
+export const LOGOS: ReadonlySet = new Set([
+ "actual-budget",
+ "adguard-home",
+ "affine",
+ "alpine-linux",
+ "ansible",
+ "appflowy",
+ "apprise",
+ "arcane",
+ "audiobookshelf",
+ "authelia",
+ "authentik",
+ "baserow",
+ "bazarr",
+ "beszel",
+ "bitwarden",
+ "bookstack",
+ "borgmatic",
+ "caddy",
+ "calibre-web",
+ "changedetection",
+ "checkmk",
+ "claude",
+ "cloudflare",
+ "cockpit",
+ "comfyui",
+ "crafty-controller",
+ "crowdsec",
+ "debian",
+ "deluge",
+ "docker",
+ "dockge",
+ "docmost",
+ "dozzle",
+ "draw-io",
+ "duplicati",
+ "elasticsearch",
+ "element",
+ "emby",
+ "esphome",
+ "excalidraw",
+ "firefly-iii",
+ "flatnotes",
+ "forgejo",
+ "freshrss",
+ "frigate",
+ "gatus",
+ "gitea",
+ "github",
+ "gitlab",
+ "glance",
+ "glances",
+ "go2rtc",
+ "gotify",
+ "grafana",
+ "grocy",
+ "harbor",
+ "headscale",
+ "healthchecks",
+ "hedgedoc",
+ "heimdall",
+ "hermes-agent",
+ "homarr",
+ "home-assistant",
+ "homebridge",
+ "homepage",
+ "immich",
+ "immich-kiosk",
+ "influxdb",
+ "it-tools",
+ "jellyfin",
+ "jellyseerr",
+ "jenkins",
+ "jitsi-meet",
+ "joplin",
+ "kavita",
+ "keycloak",
+ "komga",
+ "komodo",
+ "kopia",
+ "kubernetes",
+ "librenms",
+ "librespeed",
+ "lidarr",
+ "linkding",
+ "linux",
+ "linux-containers-lxc",
+ "linuxserver-io",
+ "llama-cpp",
+ "logseq",
+ "loki",
+ "mariadb",
+ "matomo",
+ "matrix",
+ "mattermost",
+ "mealie",
+ "minecraft",
+ "miniflux",
+ "minio",
+ "mongodb",
+ "mosquitto",
+ "n8n",
+ "navidrome",
+ "netbird",
+ "netdata",
+ "nextcloud",
+ "nginx",
+ "nginx-proxy-manager",
+ "nocodb",
+ "node-red",
+ "ntfy",
+ "nzbget",
+ "obsidian",
+ "ollama",
+ "onlyoffice",
+ "open-webui",
+ "openai",
+ "openmediavault",
+ "openwrt",
+ "opnsense",
+ "outline",
+ "overseerr",
+ "paperless-ngx",
+ "penpot",
+ "pfsense",
+ "photoprism",
+ "pi-hole",
+ "pingvin-share",
+ "piwigo",
+ "planka",
+ "plausible",
+ "plex",
+ "portainer",
+ "postgresql",
+ "privatebin",
+ "prometheus",
+ "prowlarr",
+ "proxmox",
+ "proxmox-helper-scripts",
+ "pterodactyl",
+ "qbittorrent",
+ "qnap",
+ "rabbitmq",
+ "radarr",
+ "rancher",
+ "rclone",
+ "readarr",
+ "redis",
+ "rocket-chat",
+ "rustdesk",
+ "sabnzbd",
+ "scrutiny",
+ "scrypted",
+ "seafile",
+ "searxng",
+ "semaphore",
+ "sonarr",
+ "speedtest-tracker",
+ "stirling-pdf",
+ "syncthing",
+ "synology",
+ "tailscale",
+ "tautulli",
+ "telegram",
+ "traefik",
+ "transmission",
+ "ubuntu",
+ "umami",
+ "unraid",
+ "uptime-kuma",
+ "vaultwarden",
+ "vikunja",
+ "wallabag",
+ "watchtower",
+ "webmin",
+ "wekan",
+ "wiki-js",
+ "wireguard",
+ "woodpecker-ci",
+ "wordpress",
+ "zabbix",
+ "zigbee2mqtt",
+])
diff --git a/frontend/src/views/Uebersicht.tsx b/frontend/src/views/Uebersicht.tsx
index bdaad29..c8041c0 100644
--- a/frontend/src/views/Uebersicht.tsx
+++ b/frontend/src/views/Uebersicht.tsx
@@ -198,7 +198,8 @@ function Bereichskarte({ bereich, verbindung, unterzeile, i, children }: {
}) {
const b = BEREICH[bereich]
const v = VERBINDUNG[verbindung]
- const bild = geraetebild({ art: bereich === "box" ? "ki-box" : "proxmox-host", name: b.name })
+ // Der Kopf trägt das Zeichen des Bereichs (wie die Seitenleiste), nicht das Proxmox-Logo.
+ const bild = { ...geraetebild({ art: bereich === "box" ? "ki-box" : "proxmox-host", name: b.name }), logo: undefined }
return (