feat(ui): Hintergrundgrafiken fuer Leiste und Seitenleiste je Theme

Pixel Art, Outdoor und Cyberpunk legen jetzt eine Grafik hinter die obere
Leiste und die Seitenleiste: 8-bit-Himmel mit Wolken und Huegelkante
sowie eine Steinmauer, blauer Himmel mit Schleierwolken sowie eine Wiese,
Neonroehren im Regen sowie eine regnerische Gasse. perinco bleibt
einfarbig.

Sechs SVG in public/themes/, von Hand gezeichnet - stilisierte Grafik
statt Foto, damit sie in jeder Aufloesung scharf bleibt; zusammen 36 kB.
Die Pixel-Grafiken haben einen absichtlich winzigen viewBox (eine Einheit
= ein Bildpunkt) und shape-rendering="crispEdges", damit die Kanten beim
Hochskalieren hart bleiben; die Mauer blendet nach oben stufenweise aus
und nicht mit einem Verlauf - Pixelgrafik kennt keine Zwischentoene.

Im Markup nur zwei Anker: app-header und app-sidebar. Den Rest machen
zwei Variablen mit Rueckfall auf none, weshalb perinco unberuehrt bleibt.

Die Variable enthaelt zwei Ebenen: einen Schleier aus der Flaechenfarbe
des Themes und darunter die Grafik. Das erledigt zwei Dinge zugleich -
derselbe blaue Himmel wird im Dunkelmodus zur Nacht (keine zweite Datei
noetig), und die Schrift bleibt lesbar, weil der Schleier in der Leiste an
den Raendern dicht liegt und in der Seitenleiste oben ueber den
Menuepunkten.

Aus dem ersten Versuch gelernt: die Cyberpunk-Grafik hatte eine deckende
Nachtflaeche. Im hellen Modus wurde daraus unter dem weissen Schleier ein
grauer Schmutzstreifen. Sie ist jetzt durchsichtig und zeigt nur Licht -
ueber Dunkel leuchtet das Neon, ueber Weiss bleiben blasse farbige
Linien. Ebenso zurueckgenommen wurde der Schleier ueber der Steinmauer:
"Einstellungen" und der Benutzername stehen darauf.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-09 15:08:17 +02:00
co-authored by Claude Opus 5
parent 93fe8cfd73
commit dc701f8522
12 changed files with 662 additions and 3 deletions
+144
View File
@@ -160,6 +160,24 @@
* kaputt - genau das ist der Grund fuer die Schreibweise in allen Themes.
* =========================================================================== */
html.theme-outdoor:not(.dark) {
/* Blauer Himmel oben, Wiese links. Heller Schleier aus der Flaechenfarbe. */
--theme-header-image: linear-gradient(
90deg,
rgb(253 251 246 / 0.94) 0%,
rgb(253 251 246 / 0.38) 30%,
rgb(253 251 246 / 0.3) 55%,
rgb(253 251 246 / 0.94) 100%
),
url('/themes/outdoor-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(253 251 246 / 0.97) 0%,
rgb(253 251 246 / 0.88) 45%,
rgb(253 251 246 / 0.44) 78%,
rgb(253 251 246 / 0.58) 100%
),
url('/themes/outdoor-sidebar.svg');
--color-canvas: #f2eee3;
--color-surface: #fdfbf6;
@@ -210,6 +228,25 @@ html.theme-outdoor:not(.dark) {
* nach kaltem Terminal aussieht.
*/
html.theme-outdoor.dark {
/* Dieselben Grafiken, dunkler Schleier: aus dem Himmel wird Nacht, aus der
Wiese eine Silhouette. */
--theme-header-image: linear-gradient(
90deg,
rgb(26 32 22 / 0.95) 0%,
rgb(26 32 22 / 0.68) 30%,
rgb(26 32 22 / 0.6) 55%,
rgb(26 32 22 / 0.95) 100%
),
url('/themes/outdoor-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(26 32 22 / 0.97) 0%,
rgb(26 32 22 / 0.9) 45%,
rgb(26 32 22 / 0.62) 78%,
rgb(26 32 22 / 0.72) 100%
),
url('/themes/outdoor-sidebar.svg');
--color-canvas: #12170f;
--color-surface: #1a2016;
@@ -268,6 +305,24 @@ html.theme-outdoor.dark {
* schlechtes Design.
* =========================================================================== */
html.theme-pixel:not(.dark) {
/* 8-bit-Himmel oben, Steinmauer links. */
--theme-header-image: linear-gradient(
90deg,
rgb(246 248 241 / 0.95) 0%,
rgb(246 248 241 / 0.45) 30%,
rgb(246 248 241 / 0.38) 55%,
rgb(246 248 241 / 0.95) 100%
),
url('/themes/pixel-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(246 248 241 / 0.97) 0%,
rgb(246 248 241 / 0.92) 48%,
rgb(246 248 241 / 0.72) 80%,
rgb(246 248 241 / 0.84) 100%
),
url('/themes/pixel-sidebar.svg');
/* Deutlich dunkler als die Karten: Pixelgrafik lebt von harten Kanten, und
bei zu aehnlichen Toenen verschwimmen Karte und Grund. */
--color-canvas: #cdd8c2;
@@ -319,6 +374,24 @@ html.theme-pixel:not(.dark) {
* schwarzem Grund unsichtbar), das Gruen der Knoepfe leuchtet kraeftiger.
*/
html.theme-pixel.dark {
/* Nachtvariante: derselbe Himmel unter dunklem Schleier. */
--theme-header-image: linear-gradient(
90deg,
rgb(21 26 34 / 0.96) 0%,
rgb(21 26 34 / 0.7) 30%,
rgb(21 26 34 / 0.62) 55%,
rgb(21 26 34 / 0.96) 100%
),
url('/themes/pixel-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(21 26 34 / 0.97) 0%,
rgb(21 26 34 / 0.92) 48%,
rgb(21 26 34 / 0.78) 80%,
rgb(21 26 34 / 0.88) 100%
),
url('/themes/pixel-sidebar.svg');
--color-canvas: #0d0f14;
--color-surface: #151a22;
@@ -374,6 +447,25 @@ html.theme-pixel.dark {
* plus weicher Halo in der Markenfarbe.
* =========================================================================== */
html.theme-cyberpunk.dark {
/* Neonroehren oben, regnerische Gasse links - hier ist die Grafik zu Hause,
der Schleier darf duenner sein. */
--theme-header-image: linear-gradient(
90deg,
rgb(15 17 32 / 0.94) 0%,
rgb(15 17 32 / 0.5) 28%,
rgb(15 17 32 / 0.42) 55%,
rgb(15 17 32 / 0.94) 100%
),
url('/themes/cyberpunk-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(15 17 32 / 0.96) 0%,
rgb(15 17 32 / 0.86) 45%,
rgb(15 17 32 / 0.45) 78%,
rgb(15 17 32 / 0.6) 100%
),
url('/themes/cyberpunk-sidebar.svg');
--color-canvas: #07080f;
--color-surface: #0f1120;
@@ -439,6 +531,25 @@ html.theme-cyberpunk.dark {
* Schatten: ein Halo auf hellem Grund sieht nach Fehler aus, nicht nach Neon.
*/
html.theme-cyberpunk:not(.dark) {
/* Am Tag bleibt vom Neon nur ein Nachklang: heller Schleier, dicht genug,
dass aus den Roehren blasse Linien werden statt dunkler Flecken. */
--theme-header-image: linear-gradient(
90deg,
rgb(255 255 255 / 0.96) 0%,
rgb(255 255 255 / 0.62) 30%,
rgb(255 255 255 / 0.55) 55%,
rgb(255 255 255 / 0.96) 100%
),
url('/themes/cyberpunk-header.svg');
--theme-sidebar-image: linear-gradient(
180deg,
rgb(255 255 255 / 0.98) 0%,
rgb(255 255 255 / 0.9) 45%,
rgb(255 255 255 / 0.68) 78%,
rgb(255 255 255 / 0.78) 100%
),
url('/themes/cyberpunk-sidebar.svg');
--color-canvas: #eceff7;
--color-surface: #ffffff;
@@ -518,6 +629,39 @@ html.theme-cyberpunk:not(.dark) {
font-family: var(--font-display);
}
/*
* Hintergrundbilder der oberen Leiste und der Seitenleiste.
*
* Ohne Theme steht in den Variablen nichts, dann greift der Rueckfall `none`
* und beide Flaechen bleiben einfarbig - perinco sieht also aus wie immer.
*
* Die Variable enthaelt **zwei** Ebenen: einen Schleier aus der Flaechenfarbe
* des Themes und darunter die Grafik. Das ist kein Umweg, sondern der Grund,
* dass eine Grafik in beiden Modi funktioniert - der Schleier des
* Dunkelmodus toent den blauen Himmel zur Nacht ab. Er ist ausserdem die
* Bedingung dafuer, dass die Schrift lesbar bleibt: in der oberen Leiste
* steht er an den Raendern dicht (Titel links, Knoepfe rechts) und laesst die
* Grafik nur in der leeren Mitte durch, in der Seitenleiste liegt er oben
* ueber den Menuepunkten und gibt nach unten frei.
*
* `bg-surface` an den Elementen bleibt: die Farbe liegt unter dem Bild und
* traegt, solange die Grafik laedt oder fehlt.
*/
.app-header {
background-image: var(--theme-header-image, none);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.app-sidebar {
background-image: var(--theme-sidebar-image, none);
background-repeat: no-repeat;
/* Unten verankert: dort sitzt in allen drei Grafiken das Motiv. */
background-position: bottom center;
background-size: cover;
}
/*
* Pixelschrift hat eine feste Zeichenbreite und traegt ihre Sperrung selbst;
* die negative Laufweite der Ueberschriften wuerde die Buchstaben ineinander