Die festen Huegel weichen drei Wellenkacheln (aura-wave-back/mid/front). Jede ist genau eine Sinusperiode breit, wiederholt sich waagerecht und wandert in 40 s um ihre eigene Kachelbreite - nahtlos und in beiden Modi. Unterschiedliche Kachelbreiten ergeben unterschiedliche Geschwindigkeiten. Loest aura-hills ab; bei prefers-reduced-motion stehen die Wellen still. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1314 lines
41 KiB
CSS
1314 lines
41 KiB
CSS
@import 'tailwindcss';
|
|
|
|
/*
|
|
* perinco CRM - Corporate Identity
|
|
* Farben direkt aus dem perinco Logo gesampelt:
|
|
* Gruen #6BA04A (Akzent #68A33F)
|
|
* Grau #6E6E6E
|
|
* Schrift: perinco.de nutzt Avenir LT (Light 35 / Heavy 85). Ist Avenir lokal
|
|
* installiert, wird es verwendet, sonst Nunito Sans als freies Aequivalent.
|
|
*/
|
|
|
|
/*
|
|
* Sieben Farbwelten, jede in hell und dunkel. Sie haengen an einer Klasse am
|
|
* <html> (theme-pixel, theme-outdoor, theme-cyberpunk, theme-rainy, theme-snow, theme-aura); ohne Klasse gilt
|
|
* perinco. Der Modus bleibt die vorhandene Klasse "dark".
|
|
*
|
|
* Warum das ohne Aenderung an den Komponenten geht: im Markup steht nirgends
|
|
* eine feste Farbe, sondern durchgaengig ink-*, brand-*, canvas und surface -
|
|
* und Tailwind v4 loest auch Eckenradien (--radius-*), Schatten und Schriften
|
|
* ueber Variablen auf. Ein Theme tauscht also nur Werte.
|
|
*
|
|
* Die Rollen der Skalen sind ueber die ganze App gleich (nachgezaehlt, damit
|
|
* ein Theme nichts unlesbar macht):
|
|
* ink-50/100 Flaechen und Hover
|
|
* ink-200 Rahmen (224 von 225 Verwendungen)
|
|
* ink-300-900 Text, 400 traegt die Hinweistexte
|
|
* ink-950 liegt nur unter Dialog-Overlays, bleibt immer dunkel
|
|
* brand-50/100 getoente Flaechen
|
|
* brand-200-400 Rahmen
|
|
* brand-500/600 gefuellte Knoepfe - hier steht WEISSE Schrift drauf, jedes
|
|
* Theme braucht dort also einen ausreichend dunklen Ton
|
|
* brand-600-800 Text auf getoenten Flaechen
|
|
*/
|
|
|
|
@theme {
|
|
--font-sans: 'Avenir Next', 'Avenir', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
|
|
/*
|
|
* Zweite Schrift fuer Ueberschriften und Feldbeschriftungen. Meist ist sie mit
|
|
* der Grundschrift identisch; nur "Pixel Art" setzt hier eine andere ein - die
|
|
* Pixelschrift bleibt damit aus dem Fliesstext heraus, ohne dass es dafuer
|
|
* eigene Selektoren braucht.
|
|
*/
|
|
--font-display: 'Avenir Next', 'Avenir', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
|
|
/*
|
|
* Flaechen sind bewusst semantisch benannt statt "weiss": im Dark Mode werden
|
|
* unten nur diese Variablen umgesetzt, die Utility-Klassen in den Komponenten
|
|
* bleiben unveraendert.
|
|
* canvas = Seitenhintergrund
|
|
* surface = Karten, Leisten, Dialoge
|
|
*/
|
|
--color-canvas: #f7f7f7;
|
|
--color-surface: #ffffff;
|
|
|
|
--color-brand-50: #f2f8ee;
|
|
--color-brand-100: #e2efd9;
|
|
--color-brand-200: #c6e0b6;
|
|
--color-brand-300: #a3cd8a;
|
|
--color-brand-400: #85ba66;
|
|
--color-brand-500: #6ba04a;
|
|
--color-brand-600: #58873b;
|
|
--color-brand-700: #456a2f;
|
|
--color-brand-800: #375427;
|
|
--color-brand-900: #2d4421;
|
|
--color-brand-accent: #68a33f;
|
|
|
|
--color-ink-50: #f7f7f7;
|
|
--color-ink-100: #ededed;
|
|
--color-ink-200: #dcdcdc;
|
|
--color-ink-300: #c2c2c2;
|
|
--color-ink-400: #9a9a9a;
|
|
--color-ink-500: #6e6e6e;
|
|
--color-ink-600: #5a5a5a;
|
|
--color-ink-700: #464646;
|
|
--color-ink-800: #333333;
|
|
--color-ink-900: #1f1f1f;
|
|
--color-ink-950: #141414;
|
|
|
|
--shadow-card: 0 1px 2px rgb(31 31 31 / 0.04), 0 4px 16px rgb(31 31 31 / 0.06);
|
|
--shadow-lift: 0 8px 28px rgb(31 31 31 / 0.1);
|
|
}
|
|
|
|
/*
|
|
* Dark Mode. Die Komponenten benutzen durchgaengig die Skalen ink-* und brand-*
|
|
* sowie canvas/surface - hier werden nur deren Werte getauscht, deshalb braucht
|
|
* es keine dark:-Varianten im Markup.
|
|
*
|
|
* Zwei Ausnahmen bleiben absichtlich in beiden Modi gleich:
|
|
* ink-950 - liegt nur unter Dialog-Overlays, muss also dunkel bleiben
|
|
* text-white - steht immer auf farbigen Flaechen (Buttons, Termin-Chips)
|
|
*/
|
|
.dark {
|
|
--color-canvas: #141414;
|
|
--color-surface: #1c1c1c;
|
|
|
|
/* Neutrale Skala gedreht: 50 = dunkelste Flaeche, 900 = hellster Text */
|
|
--color-ink-50: #1f1f1f;
|
|
--color-ink-100: #292929;
|
|
--color-ink-200: #383838;
|
|
/* Nicht die exakte Umkehrung von #c2c2c2: dunkler waeren Hinweistexte
|
|
(text-ink-300) auf der Flaeche kaum noch zu lesen. */
|
|
--color-ink-300: #6e6e6e;
|
|
--color-ink-400: #909090;
|
|
--color-ink-500: #a8a8a8;
|
|
--color-ink-600: #bdbdbd;
|
|
--color-ink-700: #d2d2d2;
|
|
--color-ink-800: #e6e6e6;
|
|
--color-ink-900: #f5f5f5;
|
|
--color-ink-950: #000000;
|
|
|
|
/*
|
|
* brand-500 bleibt das CI-Gruen (Buttons). Die hellen Stufen werden zu
|
|
* dunklen Tints (Hintergruende), die dunklen zu hellen Toenen (Text) - 600
|
|
* dient beidem: als hellerer Button-Hover und als lesbare Textfarbe.
|
|
*/
|
|
--color-brand-50: #1d2b15;
|
|
--color-brand-100: #26381c;
|
|
--color-brand-200: #3a5a29;
|
|
--color-brand-300: #4e7739;
|
|
--color-brand-400: #6b9f4f;
|
|
--color-brand-600: #7fb75c;
|
|
--color-brand-700: #a3cd8a;
|
|
--color-brand-800: #c6e0b6;
|
|
--color-brand-900: #e2efd9;
|
|
|
|
/*
|
|
* Statusfarben der Kontakte und Toasts sind getoente Pillen: helle Flaeche mit
|
|
* dunklem Text. Im Dark Mode wird das gedreht. Die Stufen 500/600 bleiben
|
|
* unberuehrt - dort steht weisse Schrift drauf (Loeschen-Button).
|
|
*/
|
|
--color-sky-50: #0d2537;
|
|
--color-sky-200: #1d4a6b;
|
|
--color-sky-700: #7cc4ef;
|
|
|
|
--color-amber-50: #2e2008;
|
|
--color-amber-200: #5c4210;
|
|
--color-amber-700: #f0b356;
|
|
|
|
--color-violet-50: #241a3d;
|
|
--color-violet-200: #3f2f66;
|
|
--color-violet-700: #b49bf2;
|
|
|
|
--color-red-50: #2e1414;
|
|
--color-red-200: #5e2626;
|
|
--color-red-700: #f28b8b;
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Outdoor
|
|
*
|
|
* Wanderkarte und Bergsee: Sandpapier als Flaeche, Seeblau-Gruen als Akzent,
|
|
* warme Lehmgrautoene fuer Text. Bewusst kein zweites Blattgruen - das haette
|
|
* neben perinco wie ein Versehen gewirkt. Der Unterschied faellt an drei
|
|
* Stellen auf: die Flaeche ist warm statt neutral, die Ecken sind runder und
|
|
* die Schatten weicher.
|
|
*
|
|
* Der helle Block ist mit :not(.dark) abgegrenzt. Ohne das gewinnt er gegen
|
|
* .dark (eine Klasse mehr in der Spezifitaet) und der Dunkelmodus waere
|
|
* 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;
|
|
|
|
--color-brand-50: #e8f2f1;
|
|
--color-brand-100: #d2e6e3;
|
|
--color-brand-200: #a8cfca;
|
|
--color-brand-300: #74b3ac;
|
|
--color-brand-400: #3f938b;
|
|
--color-brand-500: #12736c;
|
|
--color-brand-600: #0d5d57;
|
|
--color-brand-700: #0a4a45;
|
|
--color-brand-800: #073833;
|
|
--color-brand-900: #052b27;
|
|
--color-brand-accent: #12736c;
|
|
|
|
/* Lehmgrau: dieselbe Helligkeitstreppe wie perinco, nur mit warmem Stich. */
|
|
--color-ink-50: #f4f0e6;
|
|
--color-ink-100: #e9e3d4;
|
|
--color-ink-200: #d6cdb8;
|
|
--color-ink-300: #a1977f;
|
|
/* Hinweistexte (text-ink-400, 241 Stellen) muessen auf dem Sand lesbar
|
|
bleiben - deshalb dunkler als die reine Umkehrung. */
|
|
--color-ink-400: #6f6650;
|
|
--color-ink-500: #5c5344;
|
|
--color-ink-600: #4b4436;
|
|
--color-ink-700: #3b352a;
|
|
--color-ink-800: #2b271e;
|
|
--color-ink-900: #1d1a14;
|
|
--color-ink-950: #100e0a;
|
|
|
|
/* Runder und weicher als perinco - der zweite Wiedererkennungswert. */
|
|
--radius-sm: 0.3rem;
|
|
--radius-md: 0.45rem;
|
|
--radius-lg: 0.65rem;
|
|
--radius-xl: 0.9rem;
|
|
--radius-2xl: 1.25rem;
|
|
|
|
--shadow-card: 0 2px 4px rgb(61 53 42 / 0.06), 0 8px 24px rgb(61 53 42 / 0.1);
|
|
--shadow-lift: 0 12px 32px rgb(61 53 42 / 0.16);
|
|
|
|
--font-sans: 'Cabin', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: 'Cabin', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
}
|
|
|
|
/*
|
|
* Outdoor, dunkel: Waldnacht. Die Flaechen sind nicht neutral schwarz, sondern
|
|
* ins Tannengruen gezogen; der Text bekommt einen warmen Stich, damit es nicht
|
|
* 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;
|
|
|
|
--color-brand-50: #0c2b28;
|
|
--color-brand-100: #103833;
|
|
--color-brand-200: #17544d;
|
|
--color-brand-300: #1d6d65;
|
|
--color-brand-400: #2f9187;
|
|
--color-brand-500: #14837a;
|
|
--color-brand-600: #1f9c91;
|
|
--color-brand-700: #74b3ac;
|
|
--color-brand-800: #a8cfca;
|
|
--color-brand-900: #d2e6e3;
|
|
--color-brand-accent: #1f9c91;
|
|
|
|
--color-ink-50: #1d2419;
|
|
--color-ink-100: #26301f;
|
|
--color-ink-200: #35412c;
|
|
--color-ink-300: #6f7a63;
|
|
--color-ink-400: #8e9a81;
|
|
--color-ink-500: #a7b39a;
|
|
--color-ink-600: #bdc7b2;
|
|
--color-ink-700: #d3dbca;
|
|
--color-ink-800: #e6ebe0;
|
|
--color-ink-900: #f4f7f0;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0.3rem;
|
|
--radius-md: 0.45rem;
|
|
--radius-lg: 0.65rem;
|
|
--radius-xl: 0.9rem;
|
|
--radius-2xl: 1.25rem;
|
|
|
|
--shadow-card: 0 2px 4px rgb(0 0 0 / 0.4), 0 8px 24px rgb(0 0 0 / 0.45);
|
|
--shadow-lift: 0 12px 32px rgb(0 0 0 / 0.6);
|
|
|
|
--font-sans: 'Cabin', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: 'Cabin', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
|
|
/* Die Statusfarben kommen aus .dark und passen dort schon - hier nur die
|
|
Pillen leicht ins Warme gezogen, damit sie nicht herausfallen. */
|
|
--color-amber-50: #2c2109;
|
|
--color-amber-200: #574112;
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Pixel Art
|
|
*
|
|
* 8-bit: keine runden Ecken, harte Schatten ohne Weichzeichnung, Rahmen als
|
|
* schwarze Outlines, gesaettigtes Arcade-Gruen.
|
|
*
|
|
* Die Pixelschrift steckt nur in --font-display (Ueberschriften und
|
|
* Feldbeschriftungen). Der Fliesstext bleibt bewusst Nunito Sans: die
|
|
* Akquise-Tabelle hat acht Spalten bei 11-13 px, und eine Pixelschrift waere
|
|
* darin nicht mehr zu lesen - ein Design, das die Arbeit behindert, waere ein
|
|
* 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;
|
|
--color-surface: #f6f8f1;
|
|
|
|
--color-brand-50: #e0f2d4;
|
|
--color-brand-100: #c8e8b4;
|
|
/* Rahmen sind hier keine Andeutung, sondern Kontur - deshalb dunkel. */
|
|
--color-brand-200: #2b7a1c;
|
|
--color-brand-300: #256b18;
|
|
--color-brand-400: #35931f;
|
|
--color-brand-500: #2e8b22;
|
|
--color-brand-600: #24701a;
|
|
--color-brand-700: #1b5613;
|
|
--color-brand-800: #143f0e;
|
|
--color-brand-900: #0e2f0a;
|
|
--color-brand-accent: #2e8b22;
|
|
|
|
--color-ink-50: #eef2e8;
|
|
--color-ink-100: #dde4d4;
|
|
/* Der Kniff des Themes: ink-200 ist fast ausschliesslich Rahmen, wird hier
|
|
also zur schwarzen Outline - 224 Stellen ohne eine Zeile im Markup. */
|
|
--color-ink-200: #1f2a1a;
|
|
--color-ink-300: #5a6653;
|
|
--color-ink-400: #47523f;
|
|
--color-ink-500: #38412f;
|
|
--color-ink-600: #2c3425;
|
|
--color-ink-700: #22291c;
|
|
--color-ink-800: #182015;
|
|
--color-ink-900: #0e140c;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0;
|
|
--radius-md: 0;
|
|
--radius-lg: 0;
|
|
--radius-xl: 0;
|
|
--radius-2xl: 0;
|
|
|
|
/* Versetzt statt weichgezeichnet - so sehen Schatten in Pixelgrafik aus. */
|
|
--shadow-card: 4px 4px 0 0 #1f2a1a;
|
|
--shadow-lift: 6px 6px 0 0 #1f2a1a;
|
|
|
|
--font-display: 'Silkscreen', 'Courier New', ui-monospace, monospace;
|
|
}
|
|
|
|
/*
|
|
* Pixel Art, dunkel: Arcade-Automat im dunklen Raum. Flaechen fast schwarz mit
|
|
* blauem Stich, Konturen in gedecktem Gruen (schwarze Outlines waeren auf
|
|
* 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;
|
|
|
|
--color-brand-50: #0f2a0c;
|
|
--color-brand-100: #163c11;
|
|
--color-brand-200: #2c7a1f;
|
|
--color-brand-300: #35931f;
|
|
--color-brand-400: #3aa524;
|
|
--color-brand-500: #3aa524;
|
|
--color-brand-600: #49bf30;
|
|
--color-brand-700: #7fdc63;
|
|
--color-brand-800: #b0ec9c;
|
|
--color-brand-900: #d8f7cd;
|
|
--color-brand-accent: #49bf30;
|
|
|
|
--color-ink-50: #1a2029;
|
|
--color-ink-100: #232b36;
|
|
--color-ink-200: #33734a;
|
|
--color-ink-300: #6f7f92;
|
|
--color-ink-400: #93a3b5;
|
|
--color-ink-500: #adbccb;
|
|
--color-ink-600: #c2cfdb;
|
|
--color-ink-700: #d6e0ea;
|
|
--color-ink-800: #e9eff5;
|
|
--color-ink-900: #f6f9fc;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0;
|
|
--radius-md: 0;
|
|
--radius-lg: 0;
|
|
--radius-xl: 0;
|
|
--radius-2xl: 0;
|
|
|
|
--shadow-card: 4px 4px 0 0 #000000;
|
|
--shadow-lift: 6px 6px 0 0 #000000;
|
|
|
|
--font-display: 'Silkscreen', 'Courier New', ui-monospace, monospace;
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Cyberpunk
|
|
*
|
|
* Neon in der Nacht: fast schwarze Flaechen mit blauem Stich, violettes
|
|
* Leuchten, Kanten so scharf, dass die Karten wie HUD-Elemente wirken (2 px
|
|
* statt 12 px Radius - nicht ganz eckig, das ist schon Pixel Art).
|
|
*
|
|
* Der Akzent ist bewusst Violett und nicht Neon-Cyan: auf brand-500 und
|
|
* brand-600 steht 69 Mal weisse Schrift, und auf Cyan waere die nicht zu lesen.
|
|
* Cyan sitzt deshalb nur in --color-brand-accent und in den Statusfarben, wo
|
|
* dunkler Text drauf steht.
|
|
*
|
|
* Schatten sind hier kein Schatten, sondern ein Schein: eine farbige Kontur
|
|
* 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;
|
|
|
|
--color-brand-50: #1a0e2e;
|
|
--color-brand-100: #24123f;
|
|
--color-brand-200: #4a1f7a;
|
|
--color-brand-300: #5f27a0;
|
|
--color-brand-400: #7a30cc;
|
|
--color-brand-500: #8b31f0;
|
|
--color-brand-600: #a24cff;
|
|
--color-brand-700: #c79bff;
|
|
--color-brand-800: #ddc4ff;
|
|
--color-brand-900: #efe3ff;
|
|
--color-brand-accent: #00e5ff;
|
|
|
|
/* Blaustahl statt Neutralgrau - Grau waere hier zu brav. */
|
|
--color-ink-50: #141728;
|
|
--color-ink-100: #1c2135;
|
|
--color-ink-200: #2b4560;
|
|
--color-ink-300: #6b7899;
|
|
--color-ink-400: #8e9bbd;
|
|
--color-ink-500: #a9b5d4;
|
|
--color-ink-600: #c1cbe4;
|
|
--color-ink-700: #d6ddf0;
|
|
--color-ink-800: #e9eefa;
|
|
--color-ink-900: #f7f9ff;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0.125rem;
|
|
--radius-md: 0.125rem;
|
|
--radius-lg: 0.1875rem;
|
|
--radius-xl: 0.25rem;
|
|
--radius-2xl: 0.375rem;
|
|
|
|
--shadow-card: 0 0 0 1px rgb(139 49 240 / 0.16), 0 0 22px rgb(139 49 240 / 0.2);
|
|
--shadow-lift: 0 0 0 1px rgb(139 49 240 / 0.3), 0 0 40px rgb(139 49 240 / 0.35);
|
|
|
|
--font-sans: 'Chakra Petch', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: 'Chakra Petch', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
|
|
/* Die getoenten Pillen aus .dark ins Neon gezogen. */
|
|
--color-sky-50: #04202e;
|
|
--color-sky-200: #0b4a63;
|
|
--color-sky-700: #22d3ee;
|
|
|
|
--color-amber-50: #2b1f04;
|
|
--color-amber-200: #57400a;
|
|
--color-amber-700: #ffcc4d;
|
|
|
|
--color-violet-50: #1d1140;
|
|
--color-violet-200: #382068;
|
|
--color-violet-700: #d0a2ff;
|
|
|
|
--color-red-50: #2c0e1c;
|
|
--color-red-200: #5c1c34;
|
|
--color-red-700: #ff6b8a;
|
|
}
|
|
|
|
/*
|
|
* Cyberpunk, hell: Konzern bei Tageslicht. Kuehles Blaugrau statt warmem
|
|
* Weiss, dasselbe Violett - nur dunkler, damit weisse Schrift darauf haelt.
|
|
* Die scharfen Kanten bleiben, das Leuchten wird zu einem knappen kalten
|
|
* 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;
|
|
|
|
--color-brand-50: #f3ecff;
|
|
--color-brand-100: #e6d9ff;
|
|
--color-brand-200: #c9adff;
|
|
--color-brand-300: #a97bff;
|
|
--color-brand-400: #8d4df0;
|
|
--color-brand-500: #7326d6;
|
|
--color-brand-600: #5d1cb0;
|
|
--color-brand-700: #4a1590;
|
|
--color-brand-800: #380f6e;
|
|
--color-brand-900: #290a52;
|
|
--color-brand-accent: #7326d6;
|
|
|
|
--color-ink-50: #f2f4fb;
|
|
--color-ink-100: #e4e8f4;
|
|
--color-ink-200: #c3cbe0;
|
|
--color-ink-300: #98a2bd;
|
|
--color-ink-400: #5d6786;
|
|
--color-ink-500: #4a5473;
|
|
--color-ink-600: #3a4260;
|
|
--color-ink-700: #2c334d;
|
|
--color-ink-800: #1e2438;
|
|
--color-ink-900: #121728;
|
|
--color-ink-950: #0a0d18;
|
|
|
|
--radius-sm: 0.125rem;
|
|
--radius-md: 0.125rem;
|
|
--radius-lg: 0.1875rem;
|
|
--radius-xl: 0.25rem;
|
|
--radius-2xl: 0.375rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(18 23 40 / 0.06), 0 6px 18px rgb(115 38 214 / 0.1);
|
|
--shadow-lift: 0 12px 30px rgb(115 38 214 / 0.18);
|
|
|
|
--font-sans: 'Chakra Petch', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: 'Chakra Petch', 'Avenir Next', 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Rainy - Regenwetter.
|
|
*
|
|
* Das einzige Theme mit Bewegung: Nieselregen faellt ueber den Bildschirm und
|
|
* die Wolken in der oberen Leiste leuchten ab und zu auf. Das macht nicht CSS,
|
|
* sondern components/RainyWeather.tsx; hier stehen nur die Farben, darunter
|
|
* --rain-color fuer die Tropfen.
|
|
*
|
|
* Die Farbwelt ist Schieferblau auf kuehlem Grau - nass, aber nicht trist.
|
|
* Schrift bleibt Nunito Sans: das Wetter ist Auffaelligkeit genug.
|
|
* =========================================================================== */
|
|
html.theme-rainy:not(.dark) {
|
|
/* Tagsueber bedeckt: der Schleier ist in der Mitte duenn genug, dass die
|
|
grauen Wolken tragen und ein Blitz darauf sichtbar wird. */
|
|
--theme-header-image: linear-gradient(
|
|
90deg,
|
|
rgb(248 250 252 / 0.96) 0%,
|
|
rgb(248 250 252 / 0.35) 30%,
|
|
rgb(248 250 252 / 0.3) 60%,
|
|
rgb(248 250 252 / 0.96) 100%
|
|
),
|
|
url('/themes/rainy-header.svg');
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(248 250 252 / 0.97) 0%,
|
|
rgb(248 250 252 / 0.88) 45%,
|
|
rgb(248 250 252 / 0.4) 78%,
|
|
rgb(248 250 252 / 0.55) 100%
|
|
),
|
|
url('/themes/rainy-sidebar.svg');
|
|
|
|
--rain-color: rgb(62 90 128 / 0.5);
|
|
/* Auf hellem Grund macht "screen" aus Grau nur etwas helleres Grau - der
|
|
Blitz waere kaum zu sehen. Tagsueber deckt er deshalb normal und bekommt
|
|
einen warmen Stich, damit die Wolke sichtbar aufgluehen kann. */
|
|
--flash-color: rgb(255 244 196);
|
|
--flash-blend: normal;
|
|
|
|
--color-canvas: #e8ecf1;
|
|
--color-surface: #f8fafc;
|
|
|
|
--color-brand-50: #eaf1f7;
|
|
--color-brand-100: #d3e2ee;
|
|
--color-brand-200: #a9c5dc;
|
|
--color-brand-300: #7ba5c6;
|
|
--color-brand-400: #4f84ad;
|
|
--color-brand-500: #2f6690;
|
|
--color-brand-600: #255477;
|
|
--color-brand-700: #1e4461;
|
|
--color-brand-800: #17354c;
|
|
--color-brand-900: #112839;
|
|
--color-brand-accent: #2f6690;
|
|
|
|
--color-ink-50: #f1f4f7;
|
|
--color-ink-100: #e3e8ee;
|
|
--color-ink-200: #cdd5de;
|
|
--color-ink-300: #9aa6b4;
|
|
--color-ink-400: #5f6b7a;
|
|
--color-ink-500: #4d5866;
|
|
--color-ink-600: #3d4753;
|
|
--color-ink-700: #2f3741;
|
|
--color-ink-800: #222931;
|
|
--color-ink-900: #161b21;
|
|
--color-ink-950: #0c0f13;
|
|
|
|
--radius-sm: 0.25rem;
|
|
--radius-md: 0.4rem;
|
|
--radius-lg: 0.55rem;
|
|
--radius-xl: 0.75rem;
|
|
--radius-2xl: 1rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(22 27 33 / 0.05), 0 6px 20px rgb(47 102 144 / 0.08);
|
|
--shadow-lift: 0 12px 30px rgb(47 102 144 / 0.16);
|
|
}
|
|
|
|
/*
|
|
* Rainy, dunkel: Gewitternacht. Tintenblaue Flaechen, die Wolken treten erst
|
|
* beim Blitz richtig hervor.
|
|
*/
|
|
html.theme-rainy.dark {
|
|
--theme-header-image: linear-gradient(
|
|
90deg,
|
|
rgb(21 27 36 / 0.95) 0%,
|
|
rgb(21 27 36 / 0.45) 30%,
|
|
rgb(21 27 36 / 0.4) 60%,
|
|
rgb(21 27 36 / 0.95) 100%
|
|
),
|
|
url('/themes/rainy-header.svg');
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(21 27 36 / 0.97) 0%,
|
|
rgb(21 27 36 / 0.88) 45%,
|
|
rgb(21 27 36 / 0.5) 78%,
|
|
rgb(21 27 36 / 0.62) 100%
|
|
),
|
|
url('/themes/rainy-sidebar.svg');
|
|
|
|
--rain-color: rgb(170 195 225 / 0.45);
|
|
--flash-color: rgb(225 236 255);
|
|
--flash-blend: screen;
|
|
|
|
--color-canvas: #0d1117;
|
|
--color-surface: #151b24;
|
|
|
|
--color-brand-50: #10202e;
|
|
--color-brand-100: #15293b;
|
|
--color-brand-200: #1f3d57;
|
|
--color-brand-300: #2b5577;
|
|
--color-brand-400: #3b6f99;
|
|
--color-brand-500: #3a72a0;
|
|
--color-brand-600: #447fae;
|
|
--color-brand-700: #8fb8da;
|
|
--color-brand-800: #bcd5ea;
|
|
--color-brand-900: #e1edf7;
|
|
--color-brand-accent: #7fb2dc;
|
|
|
|
--color-ink-50: #1a212b;
|
|
--color-ink-100: #222b37;
|
|
--color-ink-200: #313c4a;
|
|
--color-ink-300: #5d6a7b;
|
|
--color-ink-400: #8593a4;
|
|
--color-ink-500: #a0adbc;
|
|
--color-ink-600: #b9c4d0;
|
|
--color-ink-700: #d0d8e1;
|
|
--color-ink-800: #e4e9ef;
|
|
--color-ink-900: #f4f7fa;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0.25rem;
|
|
--radius-md: 0.4rem;
|
|
--radius-lg: 0.55rem;
|
|
--radius-xl: 0.75rem;
|
|
--radius-2xl: 1rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.3), 0 6px 20px rgb(0 0 0 / 0.25);
|
|
--shadow-lift: 0 12px 32px rgb(0 0 0 / 0.4);
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Snow - Winter.
|
|
*
|
|
* Zweites Theme mit Bewegung: Schnee faellt und sammelt sich am unteren
|
|
* Fensterrand (components/SnowWeather.tsx). Hier stehen die Farben, dazu die
|
|
* --snow-* Variablen fuer Flocken und Schneedecke.
|
|
*
|
|
* Eisblau auf fast weissem Grund. Weisse Flocken waeren darauf unsichtbar,
|
|
* deshalb bekommen sie im hellen Modus eine zarte blaugraue Kontur, und die
|
|
* Schneedecke eine Schattierung nach unten.
|
|
* =========================================================================== */
|
|
html.theme-snow:not(.dark) {
|
|
--theme-header-image: linear-gradient(
|
|
90deg,
|
|
rgb(250 252 255 / 0.96) 0%,
|
|
rgb(250 252 255 / 0.35) 30%,
|
|
rgb(250 252 255 / 0.3) 60%,
|
|
rgb(250 252 255 / 0.96) 100%
|
|
),
|
|
url('/themes/snow-header.svg');
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(250 252 255 / 0.97) 0%,
|
|
rgb(250 252 255 / 0.88) 45%,
|
|
rgb(250 252 255 / 0.4) 78%,
|
|
rgb(250 252 255 / 0.55) 100%
|
|
),
|
|
url('/themes/snow-sidebar.svg');
|
|
|
|
--snow-flake: #f4f9ff;
|
|
--snow-flake-edge: rgb(90 125 160 / 0.7);
|
|
--snow-pile: #ffffff;
|
|
--snow-pile-shade: #c2d3e4;
|
|
--snow-pile-edge: rgb(80 115 150 / 0.75);
|
|
|
|
--color-canvas: #edf2f7;
|
|
--color-surface: #fafcff;
|
|
|
|
--color-brand-50: #e9f3fa;
|
|
--color-brand-100: #d0e5f3;
|
|
--color-brand-200: #a3cbe6;
|
|
--color-brand-300: #6eaad4;
|
|
--color-brand-400: #3f89bd;
|
|
--color-brand-500: #1f6a9e;
|
|
--color-brand-600: #185681;
|
|
--color-brand-700: #144566;
|
|
--color-brand-800: #10354f;
|
|
--color-brand-900: #0b273b;
|
|
--color-brand-accent: #1f6a9e;
|
|
|
|
--color-ink-50: #f1f5f9;
|
|
--color-ink-100: #e2e9f0;
|
|
--color-ink-200: #cbd6e1;
|
|
--color-ink-300: #97a6b6;
|
|
--color-ink-400: #5c6b7c;
|
|
--color-ink-500: #4a5868;
|
|
--color-ink-600: #3a4655;
|
|
--color-ink-700: #2c3643;
|
|
--color-ink-800: #1f2731;
|
|
--color-ink-900: #141a21;
|
|
--color-ink-950: #0a0e13;
|
|
|
|
--radius-sm: 0.3rem;
|
|
--radius-md: 0.45rem;
|
|
--radius-lg: 0.65rem;
|
|
--radius-xl: 0.85rem;
|
|
--radius-2xl: 1.15rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(20 26 33 / 0.05), 0 6px 20px rgb(31 106 158 / 0.08);
|
|
--shadow-lift: 0 12px 30px rgb(31 106 158 / 0.16);
|
|
}
|
|
|
|
/*
|
|
* Snow, dunkel: Winternacht. Tiefes Nachtblau, der Schnee leuchtet darauf von
|
|
* selbst und braucht keine Kontur.
|
|
*/
|
|
html.theme-snow.dark {
|
|
--theme-header-image: linear-gradient(
|
|
90deg,
|
|
rgb(18 26 38 / 0.95) 0%,
|
|
rgb(18 26 38 / 0.55) 30%,
|
|
rgb(18 26 38 / 0.5) 60%,
|
|
rgb(18 26 38 / 0.95) 100%
|
|
),
|
|
url('/themes/snow-header.svg');
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(18 26 38 / 0.97) 0%,
|
|
rgb(18 26 38 / 0.88) 45%,
|
|
rgb(18 26 38 / 0.55) 78%,
|
|
rgb(18 26 38 / 0.65) 100%
|
|
),
|
|
url('/themes/snow-sidebar.svg');
|
|
|
|
--snow-flake: rgb(240 246 252 / 0.9);
|
|
--snow-flake-edge: transparent;
|
|
--snow-pile: #e9f1f9;
|
|
--snow-pile-shade: #a9bdd1;
|
|
--snow-pile-edge: rgb(255 255 255 / 0.6);
|
|
|
|
--color-canvas: #0b1119;
|
|
--color-surface: #121a26;
|
|
|
|
--color-brand-50: #0e1f2e;
|
|
--color-brand-100: #13283c;
|
|
--color-brand-200: #1c3d59;
|
|
--color-brand-300: #27567c;
|
|
--color-brand-400: #3571a0;
|
|
--color-brand-500: #2f73a8;
|
|
--color-brand-600: #3b80b5;
|
|
--color-brand-700: #92c2e6;
|
|
--color-brand-800: #c0dcf1;
|
|
--color-brand-900: #e3f0fa;
|
|
--color-brand-accent: #8cc6ef;
|
|
|
|
--color-ink-50: #172131;
|
|
--color-ink-100: #1f2a3b;
|
|
--color-ink-200: #2e3b4e;
|
|
--color-ink-300: #5b6a7e;
|
|
--color-ink-400: #8493a7;
|
|
--color-ink-500: #9fadbf;
|
|
--color-ink-600: #b9c5d3;
|
|
--color-ink-700: #d0d9e4;
|
|
--color-ink-800: #e4eaf1;
|
|
--color-ink-900: #f5f8fb;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0.3rem;
|
|
--radius-md: 0.45rem;
|
|
--radius-lg: 0.65rem;
|
|
--radius-xl: 0.85rem;
|
|
--radius-2xl: 1.15rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.3), 0 6px 20px rgb(0 0 0 / 0.25);
|
|
--shadow-lift: 0 12px 32px rgb(0 0 0 / 0.4);
|
|
}
|
|
|
|
/* ===========================================================================
|
|
* Aura - hell "Sunshine", dunkel "Mond".
|
|
*
|
|
* Ein Theme mit zwei Gesichtern: bei Tag Sonne in der Ecke oben rechts,
|
|
* Himmelblau in der Leiste und warmes Bernstein als Akzent; bei Nacht der
|
|
* Mond an derselben Stelle, Sterne und Lavendel. In beiden ziehen Wolken
|
|
* langsam von links nach rechts durch die Leiste (reines CSS, siehe
|
|
* .app-header::before weiter unten), bei Tag fallen dazu ab und zu
|
|
* Sonnenstrahlen quer ueber den Bildschirm (components/AuraWeather.tsx).
|
|
*
|
|
* Die Leiste hat hier vier Ebenen statt zwei, und jede braucht eigene
|
|
* Position und Groesse - deshalb stehen die in --aura-header-position und
|
|
* --aura-header-size neben dem Bild.
|
|
* =========================================================================== */
|
|
html.theme-aura:not(.dark) {
|
|
/* Sonne ueber dem Schleier: sie soll leuchten, nicht verblassen. */
|
|
--theme-header-image: url('/themes/aura-sun.svg'),
|
|
linear-gradient(
|
|
90deg,
|
|
rgb(255 253 247 / 0.95) 0%,
|
|
rgb(255 253 247 / 0.25) 30%,
|
|
rgb(255 253 247 / 0.2) 70%,
|
|
rgb(255 253 247 / 0.7) 100%
|
|
),
|
|
linear-gradient(transparent, transparent),
|
|
linear-gradient(180deg, #a9d6ff 0%, #d6ecff 70%, #fff3d6 100%);
|
|
--aura-header-position: right -45px top -55px, center, center, center;
|
|
--aura-header-size: 130px 130px, cover, cover, cover;
|
|
--aura-cloud-opacity: 1;
|
|
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(255 253 247 / 0.97) 0%,
|
|
rgb(255 253 247 / 0.88) 45%,
|
|
rgb(255 253 247 / 0.35) 78%,
|
|
rgb(255 253 247 / 0.5) 100%
|
|
),
|
|
url('/themes/aura-wave-front.svg'),
|
|
url('/themes/aura-wave-mid.svg'),
|
|
url('/themes/aura-wave-back.svg'),
|
|
url('/themes/aura-sidebar.svg');
|
|
|
|
--color-canvas: #fbf6ea;
|
|
--color-surface: #fffdf7;
|
|
|
|
/* Bernstein. 500/600 dunkel genug fuer weisse Schrift. */
|
|
--color-brand-50: #fff7e6;
|
|
--color-brand-100: #ffeac2;
|
|
--color-brand-200: #fdd28a;
|
|
--color-brand-300: #f9b54f;
|
|
--color-brand-400: #e48a17;
|
|
--color-brand-500: #b85f08;
|
|
--color-brand-600: #9a4d07;
|
|
--color-brand-700: #7d3f0a;
|
|
--color-brand-800: #66340c;
|
|
--color-brand-900: #522b0d;
|
|
--color-brand-accent: #e8930c;
|
|
|
|
--color-ink-50: #f8f4ec;
|
|
--color-ink-100: #efe8dc;
|
|
--color-ink-200: #e0d6c5;
|
|
--color-ink-300: #aca08e;
|
|
--color-ink-400: #6f6454;
|
|
--color-ink-500: #5b5145;
|
|
--color-ink-600: #4a4137;
|
|
--color-ink-700: #3a332b;
|
|
--color-ink-800: #2a251f;
|
|
--color-ink-900: #1c1814;
|
|
--color-ink-950: #0f0d0a;
|
|
|
|
--radius-sm: 0.35rem;
|
|
--radius-md: 0.5rem;
|
|
--radius-lg: 0.75rem;
|
|
--radius-xl: 1rem;
|
|
--radius-2xl: 1.35rem;
|
|
|
|
--shadow-card: 0 1px 2px rgb(28 24 20 / 0.04), 0 8px 24px rgb(232 147 12 / 0.1);
|
|
--shadow-lift: 0 14px 34px rgb(232 147 12 / 0.18);
|
|
}
|
|
|
|
html.theme-aura.dark {
|
|
/* Der Mond liegt wie die Sonne ueber dem Schleier - darunter verschwand er
|
|
fast. Er sitzt so weit in der Ecke, dass er den Umschalter kaum streift. */
|
|
--theme-header-image: url('/themes/aura-moon.svg'),
|
|
linear-gradient(
|
|
90deg,
|
|
rgb(19 22 42 / 0.95) 0%,
|
|
rgb(19 22 42 / 0.3) 30%,
|
|
rgb(19 22 42 / 0.25) 70%,
|
|
rgb(19 22 42 / 0.45) 100%
|
|
),
|
|
url('/themes/aura-stars.svg'),
|
|
linear-gradient(180deg, #0e1230 0%, #1b1f4a 100%);
|
|
--aura-header-position: right -45px top -55px, center, center, center;
|
|
--aura-header-size: 130px 130px, cover, cover, cover;
|
|
/* Wolken bei Nacht: blass und vom Mond angeleuchtet statt weiss. */
|
|
--aura-cloud-opacity: 0.28;
|
|
|
|
--theme-sidebar-image: linear-gradient(
|
|
180deg,
|
|
rgb(19 22 42 / 0.97) 0%,
|
|
rgb(19 22 42 / 0.9) 45%,
|
|
rgb(19 22 42 / 0.6) 78%,
|
|
rgb(19 22 42 / 0.7) 100%
|
|
),
|
|
url('/themes/aura-wave-front.svg'),
|
|
url('/themes/aura-wave-mid.svg'),
|
|
url('/themes/aura-wave-back.svg'),
|
|
url('/themes/aura-sidebar.svg');
|
|
|
|
--color-canvas: #0c0e1c;
|
|
--color-surface: #13162a;
|
|
|
|
/* Mondsilber und Lavendel */
|
|
--color-brand-50: #16183a;
|
|
--color-brand-100: #1d2150;
|
|
--color-brand-200: #2b3170;
|
|
--color-brand-300: #3a4290;
|
|
--color-brand-400: #4b55ad;
|
|
--color-brand-500: #4d57b8;
|
|
--color-brand-600: #5a64c6;
|
|
--color-brand-700: #aab2f0;
|
|
--color-brand-800: #cfd4fa;
|
|
--color-brand-900: #eceefe;
|
|
--color-brand-accent: #c9cff7;
|
|
|
|
--color-ink-50: #171a30;
|
|
--color-ink-100: #1f233c;
|
|
--color-ink-200: #2d3250;
|
|
--color-ink-300: #5b6182;
|
|
--color-ink-400: #868cab;
|
|
--color-ink-500: #a1a7c3;
|
|
--color-ink-600: #babfd6;
|
|
--color-ink-700: #d1d5e6;
|
|
--color-ink-800: #e5e8f2;
|
|
--color-ink-900: #f6f7fb;
|
|
--color-ink-950: #000000;
|
|
|
|
--radius-sm: 0.35rem;
|
|
--radius-md: 0.5rem;
|
|
--radius-lg: 0.75rem;
|
|
--radius-xl: 1rem;
|
|
--radius-2xl: 1.35rem;
|
|
|
|
--shadow-card: 0 0 0 1px rgb(170 178 240 / 0.06), 0 8px 26px rgb(0 0 0 / 0.35);
|
|
--shadow-lift: 0 0 0 1px rgb(170 178 240 / 0.12), 0 14px 36px rgb(0 0 0 / 0.45);
|
|
}
|
|
|
|
@layer base {
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--color-canvas);
|
|
color: var(--color-ink-900);
|
|
font-family: var(--font-sans);
|
|
font-weight: 400;
|
|
-webkit-font-smoothing: antialiased;
|
|
/* Farbwechsel beim Umschalten laeuft weich, ohne Layout zu bewegen */
|
|
transition:
|
|
background-color 0.2s ease,
|
|
color 0.2s ease;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6 {
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
letter-spacing: -0.015em;
|
|
}
|
|
|
|
/*
|
|
* Die Feldbeschriftungen (labelClass in components/leads/leadUi.tsx) tragen
|
|
* dieselbe Klasse, damit ein Theme sie mit einer Regel erreicht. Bei perinco
|
|
* und Outdoor ist --font-display die Grundschrift, hier aendert sich also
|
|
* nichts.
|
|
*/
|
|
.field-label {
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* Aura: vier Hintergrundebenen in der Leiste, jede mit eigener Lage.
|
|
*
|
|
* Dazu ziehende Wolken als ::before. Zwei nahtlose 800-px-Kacheln, die per
|
|
* background-position genau um ihre Breite (bzw. das Doppelte) wandern -
|
|
* beim Neustart der Animation steht dasselbe Bild, deshalb kein Ruck. Die
|
|
* vordere Lage ist doppelt so schnell, das gibt Tiefe.
|
|
*
|
|
* isolation: isolate macht die Leiste zu einem eigenen Stapelkontext. Nur
|
|
* so kann z-index: -1 die Wolken hinter Titel und Knoepfe legen, ohne dass
|
|
* sie hinter dem Hintergrund der Leiste verschwinden. overflow: hidden
|
|
* kommt bewusst nicht an die Leiste - sie enthaelt Aufklappmenues.
|
|
*/
|
|
html.theme-aura .app-header {
|
|
isolation: isolate;
|
|
background-position: var(--aura-header-position);
|
|
background-size: var(--aura-header-size);
|
|
}
|
|
|
|
html.theme-aura .app-header::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: -1;
|
|
pointer-events: none;
|
|
background-image: url('/themes/aura-clouds-near.svg'), url('/themes/aura-clouds-far.svg');
|
|
background-repeat: repeat-x;
|
|
background-size: 800px 100%;
|
|
opacity: var(--aura-cloud-opacity, 1);
|
|
/* Links unter dem Titel ausblenden, rechts vor den Knoepfen duenner. */
|
|
mask-image: linear-gradient(90deg, transparent 0, #000 22%, #000 75%, rgb(0 0 0 / 0.4) 100%);
|
|
animation: aura-clouds 150s linear infinite;
|
|
}
|
|
|
|
/*
|
|
* Rollende Wellen in der Seitenleiste (Theme Aura, beide Modi).
|
|
*
|
|
* Drei Wellenkacheln (aura-wave-*.svg) liegen unter dem Schleier und ueber
|
|
* dem Dunst. Jede ist genau eine Sinusperiode breit und wiederholt sich
|
|
* waagerecht; @keyframes aura-waves schiebt jede um genau ihre eigene
|
|
* Kachelbreite weiter, deshalb sieht das Bild am Ende der Runde aus wie am
|
|
* Anfang und es ruckt nicht. Weil die Kacheln unterschiedlich breit sind,
|
|
* laufen sie bei gleicher Dauer unterschiedlich schnell - vorne schneller
|
|
* als hinten, das gibt Tiefe.
|
|
*
|
|
* Es bewegen sich nur die Wellen: der Schleier (erste Ebene) und der Dunst
|
|
* (letzte) stehen still, sonst wanderte die Helligkeit unter den
|
|
* Menuepunkten.
|
|
*/
|
|
html.theme-aura .app-sidebar {
|
|
background-repeat: no-repeat, repeat-x, repeat-x, repeat-x, no-repeat;
|
|
background-size:
|
|
cover,
|
|
260px 165px,
|
|
320px 200px,
|
|
400px 235px,
|
|
cover;
|
|
animation: aura-waves 40s linear infinite;
|
|
}
|
|
|
|
/* Sonnenstrahl (components/AuraWeather.tsx): verjuengt zur Sonne hin. */
|
|
.aura-ray {
|
|
position: absolute;
|
|
transform-origin: 0 50%;
|
|
opacity: 0;
|
|
background: linear-gradient(
|
|
90deg,
|
|
rgb(255 214 110 / 0.9) 0%,
|
|
rgb(255 224 150 / 0.45) 35%,
|
|
rgb(255 236 190 / 0.18) 75%,
|
|
rgb(255 236 190 / 0) 100%
|
|
);
|
|
clip-path: polygon(0 46%, 100% 0, 100% 100%, 0 54%);
|
|
filter: blur(10px);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
html.theme-aura .app-header::before,
|
|
html.theme-aura .app-sidebar {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Wetterleuchten im Theme Rainy (components/RainyWeather.tsx legt das
|
|
* Element exakt ueber die obere Leiste und blendet es kurz ein).
|
|
*
|
|
* Der Trick ist die Maske: sie ist dieselbe Wolken-SVG wie das
|
|
* Hintergrundbild, gleich skaliert. Das Licht - ein Schein um eine zufaellige
|
|
* Stelle (--flash-x) - erscheint deshalb nur auf den Wolken selbst, nicht auf
|
|
* der ganzen Leiste. So leuchten die Wolken von innen auf.
|
|
*/
|
|
.rainy-flash {
|
|
opacity: 0;
|
|
background: radial-gradient(
|
|
ellipse 30% 200% at var(--flash-x, 50%) 40%,
|
|
var(--flash-color, #fff) 0%,
|
|
transparent 70%
|
|
);
|
|
mix-blend-mode: var(--flash-blend, screen);
|
|
mask-image: url('/themes/rainy-header.svg');
|
|
mask-size: cover;
|
|
mask-position: center;
|
|
mask-repeat: no-repeat;
|
|
}
|
|
|
|
/*
|
|
* Pixelschrift hat eine feste Zeichenbreite und traegt ihre Sperrung selbst;
|
|
* die negative Laufweite der Ueberschriften wuerde die Buchstaben ineinander
|
|
* schieben. Ausserdem kein Kantenglaetten - Pixel sollen Pixel bleiben.
|
|
*/
|
|
html.theme-pixel h1,
|
|
html.theme-pixel h2,
|
|
html.theme-pixel h3,
|
|
html.theme-pixel h4,
|
|
html.theme-pixel h5,
|
|
html.theme-pixel h6,
|
|
html.theme-pixel .field-label {
|
|
letter-spacing: 0;
|
|
-webkit-font-smoothing: none;
|
|
font-smooth: never;
|
|
}
|
|
|
|
/*
|
|
* Cyberpunk laesst die Ueberschriften atmen: die negative Laufweite zieht
|
|
* Chakra Petch unangenehm zusammen, gesperrt liest es sich nach Anzeigetafel.
|
|
*/
|
|
html.theme-cyberpunk h1,
|
|
html.theme-cyberpunk h2,
|
|
html.theme-cyberpunk h3,
|
|
html.theme-cyberpunk h4,
|
|
html.theme-cyberpunk h5,
|
|
html.theme-cyberpunk h6 {
|
|
letter-spacing: 0.015em;
|
|
}
|
|
|
|
html.theme-cyberpunk .field-label {
|
|
letter-spacing: 0.12em;
|
|
}
|
|
|
|
/* Fokus-Ring durchgaengig in CI-Gruen */
|
|
:focus-visible {
|
|
outline: 2px solid var(--color-brand-500);
|
|
outline-offset: 2px;
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
/*
|
|
* Das perinco Logo ist fuer helle Hintergruende gemacht - der Zusatz unter
|
|
* dem Wortzeichen ist dunkelgrau und waere im Dark Mode unsichtbar. invert
|
|
* dreht die Helligkeit, hue-rotate holt das CI-Gruen zurueck.
|
|
*/
|
|
.dark .logo-adaptive {
|
|
filter: invert(1) hue-rotate(180deg);
|
|
}
|
|
|
|
/*
|
|
* "rounded-full" laesst sich nicht ueber eine Variable abschalten - Tailwind
|
|
* schreibt dort einen festen Wert. Fuer Pixel Art muss es aber weg: runde
|
|
* Punkte, Pillen und Bilder neben eckigen Karten waeren ein Bruch. Der
|
|
* Attributselektor greift genau das eine Klassenwort und ist mit dem
|
|
* vorangestellten html spezifischer als die Utility-Klasse, deshalb ohne
|
|
* !important.
|
|
*/
|
|
html.theme-pixel [class~='rounded-full'] {
|
|
border-radius: 0;
|
|
}
|
|
|
|
.scrollbar-slim::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
.scrollbar-slim::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
.scrollbar-slim::-webkit-scrollbar-thumb {
|
|
background: var(--color-ink-200);
|
|
border-radius: 999px;
|
|
}
|
|
.scrollbar-slim::-webkit-scrollbar-thumb:hover {
|
|
background: var(--color-ink-300);
|
|
}
|
|
|
|
.line-clamp-3 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
/* Ziehende Wolken im Theme Aura: vordere Kachel 2 x 800 px, hintere 1 x 800 px. */
|
|
@keyframes aura-clouds {
|
|
from {
|
|
background-position: 0 0, 0 0;
|
|
}
|
|
to {
|
|
background-position: 1600px 0, 800px 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Rollende Wellen in der Seitenleiste (Theme Aura). Reihenfolge der Werte wie
|
|
* im Bild: Schleier, Welle vorn, Welle Mitte, Welle hinten, Dunst. Jede Welle
|
|
* wandert um genau ihre Kachelbreite - 260, 320 und 400 px - und ist damit
|
|
* nach einer Runde wieder deckungsgleich.
|
|
*/
|
|
@keyframes aura-waves {
|
|
from {
|
|
background-position:
|
|
center top,
|
|
0 bottom,
|
|
0 bottom,
|
|
0 bottom,
|
|
center bottom;
|
|
}
|
|
to {
|
|
background-position:
|
|
center top,
|
|
260px bottom,
|
|
320px bottom,
|
|
400px bottom,
|
|
center bottom;
|
|
}
|
|
}
|