/* ===================================================================== DOGFATHER UNIVERSE — main.css Gemeinsames Design-System für alle drei Welten (Dogfather / HasiDog / Manager Dogfather). Farben kommen aus den theme-*.css Dateien über CSS-Variablen — dieses File ist bewusst themen-neutral. ===================================================================== */ /* ---------- Reset ---------- */ *, *::before, *::after { box-sizing: border-box; } /* overflow-x:hidden gehört auf BEIDE Elemente: ist im Standards-Modus das tatsächliche Scroll-Element des Dokuments, nicht — nur auf body gesetzt, ließ sich die Seite auf schmalen Bildschirmen (Handy-Breiten wie 320-414px) trotzdem ca. 50px horizontal wegwischen und zeigte Leerraum hinter den absichtlich überbreiten Deko-Elementen (Nebel/Aurora-Hintergrund). Tagescheck-Fund vom 02.08.2026, siehe DogFather Website.md. */ html { overflow-x: hidden; } html, body { margin: 0; padding: 0; } img, svg { max-width: 100%; display: block; } a { color: inherit; text-decoration: none; } button { font: inherit; } ul { list-style: none; margin: 0; padding: 0; } /* ---------- Fallback-Theme (Dogfather) — wird von theme-*.css überschrieben ---------- */ :root { --bg: #0b0d10; --bg-alt: #12151a; --card-bg: #171b21; --text: #f3f5f7; --text-muted: #9aa4b2; --border: #262c35; --accent: #8fd9ea; /* Babyblau */ --accent-2: #8b5cf6; /* Lila */ --accent-contrast: #0b0d10; --radius: 14px; --font-head: "Poppins", "Segoe UI", system-ui, sans-serif; --font-body: "Inter", "Segoe UI", system-ui, sans-serif; --shadow: 0 10px 30px rgba(0,0,0,.35); } /* --------------------------------------------------------------------- Sprung zum Inhalt (Tastaturbedienung, WCAG 2.4.1) Der Link ist das erste Element der Seite und für Mausnutzer unsichtbar. Er darf aber NICHT mit display:none oder visibility:hidden versteckt werden -- damit wäre er auch für die Tastatur verschwunden, und genau die soll ihn ja erreichen. Deshalb wird er aus dem Bild geschoben und kehrt zurück, sobald er den Fokus bekommt. :focus statt :focus-visible -- ein Sprunglink wird ausschließlich per Tastatur angesteuert, und ältere Browser kennen :focus-visible nicht; die würden ihn dann nie zeigen. Farbe bewusst der Akzentton auf dunklem Text (nicht umgekehrt): Das ergibt rund 12:1 Kontrast, ohne dass ein greller Kasten aufblitzt. --------------------------------------------------------------------- */ .site-skip { position: absolute; left: -9999px; top: 0; z-index: 3000; background: var(--accent); color: var(--accent-contrast); font-family: var(--font-head); font-weight: 700; text-decoration: none; padding: .85rem 1.4rem; border-radius: 0 0 var(--radius) 0; box-shadow: var(--shadow); } .site-skip:focus { left: 0; } /* Nur für Bildschirmleser: sichtbar für die Vorlesesoftware, unsichtbar für das Auge. NICHT display:none oder visibility:hidden -- das würde auch den Bildschirmleser aussperren. Wird verwendet, um auf Seiten mit optisch gestalteten Kachelgruppen die Überschriftenordnung zu vervoll- ständigen (eine Gruppenüberschrift zwischen h1 und den Kachel-h3), ohne das Design zu verändern. */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } /* Das Sprungziel bekommt tabindex="-1" (siehe main.js). Ohne diese Regel malt der Browser dann einen Fokusrahmen um den halben Bildschirm. */ main[tabindex="-1"]:focus { outline: none; } body { background: var(--bg); color: var(--text); font-family: var(--font-body); line-height: 1.6; -webkit-font-smoothing: antialiased; min-height: 100vh; position: relative; overflow-x: hidden; } h1, h2, h3, h4 { font-family: var(--font-head); line-height: 1.2; margin: 0 0 .5em; font-weight: 700; } h1 { font-size: clamp(2.2rem, 5.4vw, 3.5rem); } h2 { font-size: clamp(1.95rem, 4.3vw, 2.95rem); } h3 { font-size: 1.62rem; } p { margin: 0 0 1em; color: var(--text-muted); font-size: 1.32rem; line-height: 1.85; } .lead { font-size: 1.5rem; color: var(--text); } .quote { font-size: 1.4rem; } .container { width: min(1180px, 92vw); margin: 0 auto; } section { padding: clamp(3rem, 6vw, 5.5rem) 0; } .section-tight { padding: clamp(1.5rem, 3vw, 2.5rem) 0; } .eyebrow { display: inline-block; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); font-weight: 700; margin-bottom: .8em; } /* ---------- Nebel/Partikel Hintergrund ---------- */ .fog-layer { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; } .fog-layer span { position: absolute; border-radius: 50%; background: radial-gradient(circle, var(--accent) 0%, transparent 70%); opacity: .08; filter: blur(4px); animation: drift 26s linear infinite; } @keyframes drift { 0% { transform: translateY(0) translateX(0); } 50% { transform: translateY(-40px) translateX(20px); } 100% { transform: translateY(0) translateX(0); } } @media (prefers-reduced-motion: reduce) { .fog-layer span { animation: none; } } /* ---------- Header / Navigation ---------- */ header.site-header { position: sticky; top: 0; z-index: 50; /* Kräftig deckend statt Weichzeichnen durch das Bild dahinter — die Kombination aus backdrop-filter + fest positionierter Kopfzeile führte bei Chromium-Rendern zu Darstellungsfehlern (Logo/Menü teils unsichtbar). Deckende Farbe braucht keinen Weichzeichner und ist zusätzlich schneller. */ background: var(--bg); border-bottom: 1px solid var(--border); } .nav-bar { /* Eigene, etwas breitere Kappung als .container (1180px) — die Nav braucht durch größere Schrift + mehr Abstand + Polarlicht-Padding spürbar mehr Platz, ohne dass der restliche Seiteninhalt breiter werden soll. Bugfix 04.08.2026: 1400px -> 1440px angehoben (siehe damalige Analyse). Bugfix 20.08.2026: reichte seither wieder nicht mehr — die Nav braucht inzwischen (Nav-Punkt "DogiCrew" + "BALD"-Badge dazugekommen) real ca. 1491px, der Deckel blieb bei 1440px. 1440px -> 1560px, zusammen mit der auf 1650px angehobenen Hamburger-Schwelle weiter unten (siehe Kommentar dort) — diesmal mit echtem Sicherheitsabstand statt wieder nur knapp genug für den aktuellen Stand. */ width: min(1560px, 94vw); margin: 0 auto; display: flex; align-items: center; /* Bewusst NICHT space-between: sonst landet der ganze freie Platz auf großen Bildschirmen als große Lücke zwischen Logo und "Start", und das Menü wirkt an die rechte Kante gepresst. Stattdessen rückt das Menü mit festem Abstand direkt ans Logo heran, der übrige Platz bleibt rechts nach dem Bewerben-Knopf. */ justify-content: flex-start; gap: 2rem; padding: .9rem 0; flex-wrap: nowrap; } /* Logo und Menü-Knopf dürfen NIE zusammengequetscht werden — auch nicht, wenn .nav-links (das ausgeklappte Menü) aus irgendeinem Grund kurzzeitig noch normal mitgerechnet wird, bevor die Klappt-Logik greift. */ .brand, .nav-toggle { flex-shrink: 0; } .brand { display: flex; align-items: center; gap: .65rem; font-family: var(--font-head); font-weight: 800; font-size: 1.32rem; letter-spacing: .02em; } .brand .heart { color: var(--accent); } .brand-logo { width: 42px; height: 42px; border-radius: 9px; object-fit: cover; flex-shrink: 0; } .brand small { display: block; font-size: .7rem; font-weight: 500; letter-spacing: .1em; color: var(--text-muted); text-transform: uppercase; } .nav-links { display: flex; align-items: center; /* Seit die Kategorien eigene farbige Pillen (Polarlicht-Hintergrund) haben, trennt schon die Farbfläche selbst optisch — ein kleinerer Lücken-Abstand wirkt dadurch aufgeräumter/professioneller als der vorherige große Abstand. */ gap: .7rem; } .nav-group { position: relative; } .nav-group > button { position: relative; isolation: isolate; overflow: hidden; background: none; border: none; border-radius: 999px; color: var(--text); font-weight: 600; font-size: 1.14rem; cursor: pointer; display: flex; align-items: center; gap: .3rem; padding: .5rem .55rem; transition: color .2s ease; } .nav-group > button:hover, .nav-group.open > button { color: var(--accent); } .nav-flat { position: relative; isolation: isolate; overflow: hidden; border-radius: 999px; font-weight: 600; font-size: 1.14rem; padding: .5rem .55rem; transition: color .2s ease; } .nav-flat:hover, .nav-flat.active { color: var(--accent); } /* Kein Button-/Pillen-Look im Ruhezustand mehr (0% Deckkraft) — die Kategorien sehen bei Dogi so aus wie normale Textlinks. Der Farbschein in den echten Farben der jeweiligen Welt (siehe theme-dogfather/ -hasidog/-spicymedia.css) taucht NUR bei Hover/offenem Dropdown ganz dezent auf, als kleiner Hinweis statt als ständige Box. */ .nav-group > button::before, .nav-flat::before { content: ""; position: absolute; inset: -70% -35%; z-index: -1; background: radial-gradient(circle at 28% 30%, var(--brand-1, transparent), transparent 62%), radial-gradient(circle at 74% 72%, var(--brand-2, transparent), transparent 62%); filter: blur(9px) saturate(1.25); opacity: 0; animation: nav-cta-aurora 11s ease-in-out infinite alternate; pointer-events: none; transition: opacity .3s ease; } .nav-group:hover > button::before, .nav-group.open > button::before, .nav-flat:hover::before, .nav-flat.active::before { opacity: .32; } @media (prefers-reduced-motion: reduce) { .nav-group > button::before, .nav-flat::before { animation: none; } } .nav-item-dogfather { --brand-1: rgba(143, 217, 234, .9); --brand-2: rgba(139, 92, 246, .85); } .nav-item-hasidog { --brand-1: rgba(143, 217, 234, .9); --brand-2: rgba(199, 204, 209, .8); } .nav-item-manager { --brand-1: rgba(217, 74, 92, .85); --brand-2: rgba(232, 147, 58, .8); } .nav-item-medien { --brand-1: rgba(143, 217, 234, .7); --brand-2: rgba(217, 74, 92, .6); } .nav-item-start { --brand-1: rgba(143, 217, 234, .85); --brand-2: rgba(139, 92, 246, .5); } .nav-item-links { --brand-1: rgba(143, 217, 234, .85); --brand-2: rgba(212, 175, 55, .7); } /* Aufgeklapptes Kategorie-Menü: gleiche "gläserne, dunkle Karte mit farbigem Schein"-Machart wie beim Sprachschalter-Dropdown, aber im Farbton DIESER Kategorie (--brand-1/--brand-2, vom umschließenden .nav-group geerbt) statt neutral silbern — sorgt für einen klaren, ruhigen Look statt der vorherigen schlichten grauen Box. */ .nav-dropdown { position: absolute; /* WICHTIG: KEIN margin-top/Lücke zum Knopf — sonst verliert die Maus beim Runterfahren zur Box kurz den Hover auf .nav-group, und das Menü klappt zu, bevor man einen Punkt anklicken kann (Bug gefunden 03.08.2026, durch den Caret-Abstand selbst verursacht). Box sitzt deshalb bewusst bündig an top:100%, der Verbindungs-Pfeil unten pokt einfach in die Knopf-Kante hinein statt in eine echte Lücke. */ top: 100%; left: 50%; transform: translateX(-50%); min-width: 230px; background: rgba(4, 5, 8, .96); border: 1px solid rgba(255, 255, 255, .14); border-radius: 14px; padding: .45rem; box-shadow: 0 14px 34px rgba(0, 0, 0, .6), 0 0 16px var(--brand-1, rgba(220, 226, 235, .3)), 0 0 32px var(--brand-2, rgba(190, 200, 215, .15)); display: none; flex-direction: column; /* EIGENE Animation statt der geteilten sprach-dropdown-in: eine @keyframes-Regel setzt "transform" als GANZES pro Frame, würde also das zentrierende translateX(-50%) oben komplett überschreiben und die Box nach dem Aufklappen sichtbar nach rechts verschieben (Bug gefunden 03.08.2026 — Box wirkte "nicht mittig", war es auch nicht: transform sprang nach der Animation auf reines translateY/scale). Der Sprachschalter unten ist rechtsbündig (kein translateX nötig) und behält deshalb bewusst die alte, geteilte Animation. */ animation: nav-dropdown-in .18s ease both; } /* Kleiner Verbindungs-Pfeil (Caret), mittig unter dem Kategorie-Knopf — macht auch dann unmissverständlich klar, zu welcher Kategorie das Menü gehört, wenn die Box (wegen mehr Einträgen) breiter ist als der Knopf selbst und dadurch optisch in Nachbar-Kategorien hineinragt. */ .nav-dropdown::before { content: ""; position: absolute; top: -7px; left: 50%; transform: translateX(-50%) rotate(45deg); width: 14px; height: 14px; background: rgba(4, 5, 8, .96); border-left: 1px solid rgba(255, 255, 255, .14); border-top: 1px solid rgba(255, 255, 255, .14); border-radius: 3px 0 0 0; pointer-events: none; } .nav-group.open .nav-dropdown { display: flex; } /* Auf echten Maus-Geräten (nicht Touch) öffnet sich das Menü schon beim Drüberfahren, ohne extra Klick — auf Touch/Tablet bleibt es bewusst beim Klick (dort gibt es kein echtes "Hover"). */ @media (hover: hover) and (pointer: fine) { .nav-group:hover .nav-dropdown { display: flex; } } /* Bewusst KEIN Button-Look (kein gefüllter Hintergrund, keine Pille) — nur schlichte Menü-Zeilen, die beim Hover die Farbe wechseln. Die Kategorie-Knöpfe selbst (DogFather/HasiDog/Manager/...) behalten weiterhin ihren Pillen-Stil, nur das aufgeklappte Untermenü nicht. */ .nav-dropdown a { padding: .55rem .75rem; font-size: 1.06rem; color: var(--text-muted); transition: color .2s ease; } /* translateX(-50%) MUSS in jedem Frame mit drinstehen, sonst hebt die Animation die Zentrierung von .nav-dropdown auf (siehe Kommentar oben). */ @keyframes nav-dropdown-in { from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(.96); } to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } } .nav-dropdown a:hover, .nav-dropdown a.active { color: var(--brand-1, var(--accent)); } /* =================================================================== Sprachumschalter — eigenes kleines "Schmuckstück" in der Nav-Bar statt eines schlichten Menüpunkts: eine gläserne Pille mit Polarlicht-Schein in der jeweiligen Sprachfarbe (--sprach-glut, von main.js gesetzt), eine glänzende, sich sacht drehende "Mini-Planet"-Kugel und ein Dropdown im selben Look, das beim Öffnen sanft einschwebt. */ .sprach-schalter { --sprach-glut: var(--accent); } .sprach-schalter > button { position: relative; isolation: isolate; overflow: hidden; font-size: 1.08rem; font-weight: 700; align-items: center; gap: .5rem; padding: .45rem 1.1rem .45rem .6rem; border-radius: 999px; /* Rand bewusst neutral silbern (wie beim Dropdown-Kasten) statt in der Sprachfarbe — nur die Kugel + das Glühen dahinter sind bunt, der Rahmen selbst bleibt für alle Sprachen gleich. */ border: 1px solid rgba(210, 216, 224, .55); background: rgba(4, 5, 8, .94); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05), 0 3px 10px rgba(0, 0, 0, .5), 0 0 10px color-mix(in srgb, var(--sprach-glut) 55%, transparent), 0 0 22px color-mix(in srgb, var(--sprach-glut) 35%, transparent); transition: transform .2s ease, box-shadow .3s ease, border-color .3s ease; } .sprach-schalter > button:hover, .sprach-schalter.open > button { transform: translateY(-1px); border-color: rgba(235, 239, 244, .9); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08), 0 6px 16px rgba(0, 0, 0, .4), 0 0 24px color-mix(in srgb, var(--sprach-glut) 60%, transparent); } /* Ebene: die "Landesflagge" als weiche, wandernde Aurora-Wolke im Hintergrund des Knopfs — mehrere Farbflecken statt nur eines Farbtons, dieselbe Machart wie beim Bewerben-Knopf, nur mit den 2-3 echten Farben DIESER Sprache (siehe SPRACHEN.farbstopps in main.js). */ .sprach-schalter > button::before { content: ""; position: absolute; inset: -65%; z-index: -2; background: var(--sprach-aurora); filter: blur(8px) saturate(1.3); /* Bewusst nur ein dezenter Farbschein statt einer vollflächig bunten Fläche — der Knopf selbst soll "leuchtend schwarz" wirken (Glow am Rand + hinter der Kugel), nicht komplett eingefärbt. */ opacity: .32; animation: sprach-aurora-drift 7s ease-in-out infinite alternate; pointer-events: none; } .sprach-schalter > button:hover::before, .sprach-schalter.open > button::before { opacity: .48; } @keyframes sprach-aurora-drift { from { transform: translate(-3%, -2%) rotate(0deg) scale(1); } to { transform: translate(3%, 3%) rotate(8deg) scale(1.12); } } /* Ebene: ein schmales Lichtband, das einmal quer durch den Knopf läuft — dieselbe Machart wie beim Bewerben-Knopf, nur in der Sprachfarbe. */ .sprach-schalter > button::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(115deg, transparent 35%, color-mix(in srgb, var(--sprach-glut) 55%, white 25%) 49%, transparent 63%); background-size: 240% 100%; mix-blend-mode: overlay; opacity: .8; animation: sprach-schimmer 5s linear infinite; pointer-events: none; } @keyframes sprach-schimmer { 0% { background-position: 160% 0; } 100% { background-position: -60% 0; } } /* Bugfix 20.08.2026 (Nutzer-Report per Screenshot-Vergleich: Kategorie- Menüs wie "Medien" sind mittig unter dem Knopf, der Sprachschalter aber rechtsbündig) — war bewusst rechtsbündig, seit der Sprachschalter aber nicht mehr ganz am rechten Rand sitzt (DogiCrew-/Bewerben-Knopf daneben), ist genug Platz für dieselbe zentrierte Ausrichtung wie überall sonst. left/transform hier deshalb NICHT mehr überschrieben (erbt jetzt left:50%/translateX(-50%) von der allgemeinen .nav-dropdown-Regel, genau wie der bereits zentrierte Verbindungs-Pfeil (::before) es die ganze Zeit schon war — vorher zeigte der Pfeil mittig, während die Box selbst daneben saß). Eigene Animation bleibt bestehen (siehe Kommentar der allgemeinen .nav-dropdown-Animation), jetzt aber ebenfalls mit translateX(-50%) in jedem Frame, sonst würde sie die Zentrierung wieder aufheben. */ .sprach-schalter .nav-dropdown { min-width: 190px; padding: .4rem; border-radius: 14px; border: 1px solid rgba(210, 216, 224, .55); background: rgba(4, 5, 8, .96); box-shadow: 0 14px 34px rgba(0, 0, 0, .6), 0 0 16px rgba(220, 226, 235, .35), 0 0 34px rgba(190, 200, 215, .18); animation: sprach-dropdown-in .18s ease both, sprach-silber-puls 3.6s ease-in-out infinite; } @keyframes sprach-dropdown-in { from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(.96); } to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } } /* Silberner Polarlicht-Schein um den Dropdown-Rand — bewusst neutral silber statt farbig, damit sich der schwarze Kasten von der bunten Kugel/Schrift jeder Sprache klar abhebt statt zu verschwimmen. */ @keyframes sprach-silber-puls { 0%, 100% { border-color: rgba(210, 216, 224, .5); box-shadow: 0 14px 34px rgba(0, 0, 0, .6), 0 0 14px rgba(220, 226, 235, .3), 0 0 30px rgba(190, 200, 215, .15); } 50% { border-color: rgba(235, 239, 244, .9); box-shadow: 0 14px 34px rgba(0, 0, 0, .6), 0 0 22px rgba(230, 235, 242, .55), 0 0 46px rgba(200, 210, 224, .3); } } .sprach-schalter .nav-dropdown a { display: flex; align-items: center; gap: .65rem; padding: .6rem .7rem; border-radius: 10px; border-left: 3px solid transparent; transition: background .2s ease, border-color .2s ease, transform .15s ease; } .sprach-schalter .nav-dropdown a:hover, .sprach-schalter .nav-dropdown a.active { background: rgba(255, 255, 255, .09); border-left-color: var(--sprach-glut); transform: translateX(2px); } /* Kleine "Mini-Planet"-Kugel statt eines Flaggen-Emojis — Windows stellt Flaggen-Emojis grundsätzlich nicht als Bild dar (siehe SPRACHEN oben in main.js). Ein außermittiges Glanzlicht + langsame Drehung lassen sie wie eine echte, beleuchtete Kugel wirken statt einer flachen Fläche. */ /* Kugel-Grundfarbe: conic-gradient aus den 2-3 echten Landesfarben dieser Sprache (--sprach-stopps, siehe SPRACHEN.farbstopps in main.js) — wirkt wie eine kleine, marmoriert eingefärbte Kugel statt nur einem Farbton, plus Eigendrehung, damit die Farbmischung sichtbar "lebt". Glanzlicht kommt separat über ::before oben drauf. */ .sprach-kugel { position: relative; display: inline-block; width: 20px; height: 20px; border-radius: 50%; vertical-align: -4px; overflow: hidden; background: conic-gradient(from 0deg, var(--sprach-stopps)); box-shadow: inset -3px -3px 5px rgba(0, 0, 0, .5), 0 0 8px 2px color-mix(in srgb, var(--sprach-glut) 75%, transparent), 0 0 20px 4px color-mix(in srgb, var(--sprach-glut) 45%, transparent); flex-shrink: 0; animation: sprach-glut-puls 3.2s ease-in-out infinite, sprach-kugel-dreh 7s linear infinite; } .sprach-kugel::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle at 32% 26%, rgba(255, 255, 255, .95) 0%, rgba(255, 255, 255, .35) 16%, transparent 55%); mix-blend-mode: overlay; } .sprach-schalter .nav-dropdown a .sprach-kugel { width: 16px; height: 16px; } /* Die Sprachfarbe zieht sich auch über die Schrift — kräftiger, leuchtender Text statt neutralem Weiß, plus ein sanft pulsierender Schein (dieselbe "Polarlicht"-Idee wie beim Bewerben-Knopf/den Foto-Rahmen, nur in der jeweiligen Sprachfarbe). */ .sprach-schalter > button, .sprach-schalter .nav-dropdown a { color: var(--sprach-glut, var(--text)); text-shadow: 0 0 6px color-mix(in srgb, var(--sprach-glut, transparent) 70%, transparent), 0 0 14px color-mix(in srgb, var(--sprach-glut, transparent) 45%, transparent); } .sprach-kurz { animation: sprach-glut-puls 3.2s ease-in-out infinite; display: inline-block; } @keyframes sprach-glut-puls { 0%, 100% { filter: brightness(1) saturate(1); } 50% { filter: brightness(1.3) saturate(1.35); } } @keyframes sprach-kugel-dreh { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .sprach-kugel, .sprach-kurz, .sprach-schalter > button::before, .sprach-schalter > button::after, .sprach-schalter .nav-dropdown { animation: none; } } /* "Bewerben" ist der Treffpunkt beider Welten (Team Dogi + Spicy Media) — deshalb bewusst FEST babyblau + rot, unabhängig vom Theme der gerade offenen Seite. Statt einer einfachen 50/50-Teilung ein echtes Polarlicht: mehrere weiche, wandernde Farbwolken (blau/lila/rot) plus ein durchlaufender Lichtschimmer — soll wirken wie Licht und Nebel, nicht wie zwei flache Farbflächen. */ .nav-cta { position: relative; isolation: isolate; overflow: hidden; display: inline-flex; align-items: center; white-space: nowrap; padding: .6rem 1.35rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: .95rem; background: #0b0e14; border: 1px solid rgba(255, 255, 255, .16); transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; box-shadow: 0 6px 18px rgba(0, 0, 0, .35); } .nav-cta span { position: relative; z-index: 2; text-shadow: 0 1px 3px rgba(0, 0, 0, .6), 0 0 14px rgba(0, 0, 0, .35); } /* Ebene 1: die wandernden Polarlicht-Wolken selbst */ .nav-cta::before { content: ""; position: absolute; inset: -60%; z-index: 0; background: radial-gradient(circle at 18% 30%, rgba(143, 217, 234, .95), transparent 55%), radial-gradient(circle at 45% 75%, rgba(139, 92, 246, .85), transparent 58%), radial-gradient(circle at 82% 32%, rgba(217, 74, 92, .95), transparent 55%), radial-gradient(circle at 62% 82%, rgba(232, 147, 58, .55), transparent 55%); filter: blur(9px) saturate(1.35); animation: nav-cta-aurora 9s ease-in-out infinite alternate; } /* Ebene 2: ein feiner Lichtschimmer, der einmal quer durchläuft */ .nav-cta::after { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .4) 49%, transparent 63%); background-size: 240% 100%; mix-blend-mode: overlay; animation: nav-cta-shimmer 4.5s linear infinite; pointer-events: none; } @keyframes nav-cta-aurora { from { transform: translate(-3%, -2%) rotate(0deg) scale(1); } to { transform: translate(3%, 3%) rotate(6deg) scale(1.08); } } @keyframes nav-cta-shimmer { from { background-position: 130% 0; } to { background-position: -30% 0; } } .nav-cta:hover { transform: translateY(-1px); border-color: rgba(255, 255, 255, .32); box-shadow: 0 10px 26px rgba(0, 0, 0, .45), 0 0 22px rgba(143, 217, 234, .3), 0 0 22px rgba(217, 74, 92, .28); } /* Abo-Button (Supporter-Abo) — gleicher Polarlicht-Mechanismus wie .nav-cta, aber in Babyblau/Lila (VIP-Anmutung) statt der allgemeinen Regenbogen-Aurora. Bugfix 04.08.2026: war Gold/Lila (rgba(212,175,55,...)) — dieser Knopf erscheint in der Navigationsleiste auf JEDER Seite (auch auf verwaltung.html, siehe Screenshot-Beschwerde), wurde von der 4. Runde "überall wo gelb ist, Babyblau benutzen" aber NICHT erfasst, weil er in main.css/main.js liegt statt in verwaltung.html selbst. Jetzt nachgezogen: Gold -> Babyblau (rgba(143,217,234,...), derselbe Farbwert wie beim allgemeinen .nav-cta-Polarlicht oben), Lila unverändert. Der separate, deutlich größere Gold-VIP-Look von abonnieren.html/ supporter.html/gate.html/links.html/rabattcodes.html ist davon NICHT betroffen — das ist eine eigenständige, bislang nie angesprochene Design-Entscheidung für den öffentlichen Supporter-Bereich. */ .nav-cta-abo::before { background: radial-gradient(circle at 20% 30%, rgba(143, 217, 234, .95), transparent 55%), radial-gradient(circle at 78% 70%, rgba(139, 92, 246, .85), transparent 58%); } .nav-cta-abo:hover { box-shadow: 0 10px 26px rgba(0, 0, 0, .45), 0 0 22px rgba(143, 217, 234, .35), 0 0 22px rgba(139, 92, 246, .3); } /* "Bald"-Badge auf dem Abo-Knopf, solange die Registrierung auf abonnieren.html gesperrt ist (20.08.2026, siehe .btn-gold-locked weiter unten + main.js renderAboButton/soonBadge). Sitzt als zweites Kind IN der Pille (nicht als eigenes Nav-Element), bleibt dadurch Teil desselben Klicks — der Knopf führt bewusst weiterhin ganz normal zu abonnieren.html, nur die Registrierung selbst dort ist gesperrt. Bewusst neutral-silbern (Wiederverwendung von .btn-silver-text/-spark, nur kleiner skaliert) statt Gold, damit es nicht mit der babyblau/lila-Aurora dieser Pille konkurriert — reine Status-Markierung, kein zweiter Marken-Akzent. */ .nav-cta-soon { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: .22rem; margin-left: .5rem; padding: .15rem .5rem; border-radius: 999px; font-size: .64rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .3); box-shadow: 0 0 10px rgba(230, 235, 242, .3); flex-shrink: 0; } .nav-cta-soon .btn-silver-spark { font-size: .85em; } @media (prefers-reduced-motion: reduce) { .nav-cta::before, .nav-cta::after { animation: none; } } /* TikTok-Button "Glitch/Duotone" — eigener, klar erkennbarer Stil (nicht mehr nur eine eingefärbte Kopie von .nav-cta): schwarze Pille mit einem fließenden Cyan/Pink-Rahmen (klassischer Zwei-Layer-Background-Trick, NICHT ein rotierender Masken-Ring — der verzerrt sich auf einer länglichen Pillenform zu einer krummen Schlaufe statt einer sauberen Kontur), einem dezenten Innenschimmer (KEIN nach außen strahlender Blur-Wolken-Glow mehr — der hat vorher Text/Bilder drumherum überstrahlt, Feedback vom 03.08.2026: "geht über den Text und das Bild"), einer rotierenden Notenkopf-Spielmarke und einem Text mit TikToks charakteristischem Chromatic-Aberration-/Glitch-Versatz (die Cyan/Rot- Schattenkopien, die auch im echten TikTok-Logo stecken), der alle paar Sekunden kurz "springt". Alle Effekte bleiben INNERHALB der Pille bzw. direkt an ihrer Kante — die Auffälligkeit kommt vom Button selbst, nicht von seiner Ausstrahlung. Bewusst NUR für echte TikTok-Links — die Markenfarben (Cyan #25F4EE + Pink/Rot #FE2C55) bleiben exakt gleich. */ .btn-tiktok { position: relative; isolation: isolate; overflow: hidden; display: inline-flex; align-items: center; gap: .6rem; padding: .85rem 2.2rem; border-radius: 999px; color: #fff; font-weight: 800; font-size: 1.1rem; letter-spacing: .01em; border: 2px solid transparent; background: linear-gradient(160deg, #12151b, #05070a 55%, #14171d) padding-box, linear-gradient(90deg, #25F4EE, #FE2C55, #25F4EE) border-box; background-size: 100% 100%, 260% 100%; text-decoration: none; transition: transform .25s ease, box-shadow .25s ease; box-shadow: 0 4px 12px rgba(0, 0, 0, .4), inset 0 0 10px rgba(37, 244, 238, .12), inset 0 0 10px rgba(254, 44, 85, .1); animation: btn-tiktok-border-flow 5s linear infinite; } .btn-tiktok-note { position: relative; z-index: 3; display: inline-block; font-size: 1.05em; filter: drop-shadow(0 0 3px rgba(37, 244, 238, .8)); animation: btn-tiktok-spin 3.6s linear infinite; } .btn-tiktok-text { /* Ruhezustand ist bewusst KLAR LESBAR (nur normaler Schlagschatten) — der Cyan/Rot-Chromatic-Versatz von TikToks Logo erscheint nur ganz kurz als Flicker (siehe @keyframes btn-tiktok-glitch), nicht dauerhaft, sonst verschwimmt der Text (Feedback vom 03.08.2026: "kriegt man TikTok nichtmal richtig gelesen"). */ position: relative; z-index: 3; text-shadow: 0 2px 6px rgba(0, 0, 0, .6); animation: btn-tiktok-glitch 6s ease-in-out infinite; } .btn-tiktok::before { /* Sehr dezentes Farbschimmern INNEN in der Pille — sorgt für Tiefe, bleibt aber innerhalb der Ränder (kein overflow, kein Blur-Bleed). */ content: ""; position: absolute; inset: 0; z-index: 0; border-radius: inherit; background: radial-gradient(circle at 18% 20%, rgba(37, 244, 238, .3), transparent 60%), radial-gradient(circle at 85% 80%, rgba(254, 44, 85, .28), transparent 62%); animation: nav-cta-aurora 9s ease-in-out infinite alternate; pointer-events: none; } .btn-tiktok::after { /* Diagonaler Lichtschimmer, wandert einmal quer über die Pille */ content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .4) 49%, transparent 63%); background-size: 240% 100%; mix-blend-mode: overlay; animation: nav-cta-shimmer 4.5s linear infinite; pointer-events: none; } .btn-tiktok:hover { transform: translateY(-1px) scale(1.02); box-shadow: 0 6px 16px rgba(0, 0, 0, .45), inset 0 0 14px rgba(37, 244, 238, .2), inset 0 0 14px rgba(254, 44, 85, .16); } @keyframes btn-tiktok-border-flow { to { background-position: 0 0, -260% 0; } } @keyframes btn-tiktok-spin { to { transform: rotate(360deg); } } @keyframes btn-tiktok-glitch { /* 97% der Zeit klar lesbarer Text — der Chromatic-Versatz blitzt nur für einen Wimpernschlag (~150ms von 6s) auf, statt dauerhaft zu "verwaschen". */ 0%, 96%, 100% { text-shadow: 0 2px 6px rgba(0, 0, 0, .6); transform: translateX(0); } 97% { text-shadow: -3px 0 rgba(37, 244, 238, .95), 3px 0 rgba(254, 44, 85, .95), 0 2px 6px rgba(0, 0, 0, .6); transform: translateX(-1px); } 97.5% { text-shadow: 3px 0 rgba(37, 244, 238, .95), -3px 0 rgba(254, 44, 85, .95), 0 2px 6px rgba(0, 0, 0, .6); transform: translateX(1px); } 98% { text-shadow: 0 2px 6px rgba(0, 0, 0, .6); transform: translateX(0); } } @media (prefers-reduced-motion: reduce) { .btn-tiktok, .btn-tiktok::before, .btn-tiktok::after, .btn-tiktok-note, .btn-tiktok-text { animation: none; } } /* Silberner Hervorhebungs-Button: eigener, deutlich edlerer Look als .btn-tiktok — echtes Chrome-Metallic-Textglitzern, rotierender Metallrand-Schimmer, zwei funkelnde Sparkle-Akzente und ein sanft pulsierender Halo-Glow. Für Dinge, die besonders auffallen sollen — gesperrt (abonnieren.html, "Coming soon…", ohne href und mit aria-disabled) ODER als echter Link (vanvan.html → VanVans Shop). Der :hover-Zustand unten passt deshalb nur zur verlinkten Variante; im gesperrten Fall fällt er mangels href kaum auf. */ .btn-silver { position: relative; isolation: isolate; overflow: visible; display: inline-flex; align-items: center; /* Die Beschriftung bleibt in EINER Zeile. Ohne das brach "VAN´S DIY" auf dem Handy am Apostroph mitten im Wort um ("VAN / ´S / DIY", 05.09.2026 gemessen bei 390px: Knopf 117px hoch statt 89px). Grund ist die schmale Spalte auf vanvan.html — die Sektion bleibt dort auch auf dem Handy zweispaltig, weil ein Inline-Style die Regel aus @media(max-width:620px) überschreibt. nowrap macht die Knopfbreite zur Mindestbreite der Spalte, das Gitter gibt ihm den Platz dann von selbst. */ white-space: nowrap; gap: .55rem; padding: .95rem 2.4rem; border-radius: 999px; color: #fff; font-weight: 800; font-size: 1.1rem; letter-spacing: .02em; background: linear-gradient(160deg, #14161c, #0b0e14 55%, #1a1d24); border: 1px solid rgba(255, 255, 255, .22); text-decoration: none; transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; box-shadow: 0 6px 18px rgba(0, 0, 0, .4), 0 0 0 1px rgba(255, 255, 255, .03) inset; animation: btn-silver-halo 3.2s ease-in-out infinite; } .btn-silver-text { position: relative; z-index: 2; background: linear-gradient(100deg, #9aa4b2 0%, #ffffff 28%, #e6ebf2 42%, #c7ccd1 58%, #ffffff 76%, #9aa4b2 100%); background-size: 260% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); animation: btn-silver-text-shine 3.6s linear infinite; } .btn-silver-spark { position: relative; z-index: 2; display: inline-block; font-size: .9em; filter: drop-shadow(0 0 4px rgba(255, 255, 255, .8)); animation: btn-silver-twinkle 1.8s ease-in-out infinite; } .btn-silver-spark:last-child { animation-delay: .9s; } .btn-silver::before { content: ""; position: absolute; inset: -1px; z-index: 0; border-radius: inherit; padding: 1.5px; background: conic-gradient(from 0deg, #eef1f5, #9aa4b2, #ffffff, #c7ccd1, #7d8794, #eef1f5); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: btn-silver-shine-rotate 5s linear infinite; } .btn-silver::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .5) 49%, transparent 63%); background-size: 240% 100%; mix-blend-mode: overlay; animation: nav-cta-shimmer 4.5s linear infinite; pointer-events: none; } .btn-silver:hover { transform: translateY(-1px) scale(1.02); border-color: rgba(255, 255, 255, .4); box-shadow: 0 10px 30px rgba(0, 0, 0, .5), 0 0 26px rgba(230, 235, 242, .45), 0 0 26px rgba(190, 200, 215, .35); } @keyframes btn-silver-shine-rotate { to { transform: rotate(360deg); } } @keyframes btn-silver-text-shine { 0% { background-position: 0% 50%; } 100% { background-position: 260% 50%; } } @keyframes btn-silver-twinkle { 0%, 100% { opacity: .45; transform: scale(.85) rotate(0deg); } 50% { opacity: 1; transform: scale(1.15) rotate(15deg); } } @keyframes btn-silver-halo { 0%, 100% { box-shadow: 0 6px 18px rgba(0, 0, 0, .4), 0 0 14px rgba(200, 208, 220, .18); } 50% { box-shadow: 0 6px 18px rgba(0, 0, 0, .4), 0 0 26px rgba(230, 235, 242, .4); } } @media (prefers-reduced-motion: reduce) { .btn-silver, .btn-silver::before, .btn-silver::after, .btn-silver-text, .btn-silver-spark { animation: none; } } /* "Legendärer" Button (z.B. Casperlino-Link auf streamer.html): babyblau + Silber, gleiche edle Machart wie .btn-silver (Chrome-Textglanz, rotierender Rand, Sparkles, pulsierender Halo), aber größer, kräftiger und in der Marken-Akzentfarbe --accent (Babyblau) statt neutralem Grau — soll bewusst wie ein besonderes, "episches" Highlight wirken. */ .btn-legendary { position: relative; isolation: isolate; overflow: visible; display: inline-flex; align-items: center; gap: .6rem; padding: 1.05rem 2.7rem; border-radius: 999px; color: #fff; font-weight: 800; font-size: 1.18rem; letter-spacing: .02em; background: linear-gradient(160deg, #101b20, #0b0e14 55%, #16232a); border: 1px solid rgba(143, 217, 234, .35); text-decoration: none; transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; box-shadow: 0 8px 22px rgba(0, 0, 0, .45), 0 0 0 1px rgba(143, 217, 234, .06) inset; animation: btn-legendary-halo 3s ease-in-out infinite; } .btn-legendary-text { position: relative; z-index: 2; background: linear-gradient(100deg, #8fd9ea 0%, #ffffff 26%, #c7ccd1 42%, #8fd9ea 58%, #ffffff 76%, #c7ccd1 100%); background-size: 260% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); animation: btn-legendary-text-shine 3.4s linear infinite; } .btn-legendary-spark { position: relative; z-index: 2; display: inline-block; font-size: .95em; filter: drop-shadow(0 0 5px rgba(143, 217, 234, .9)); animation: btn-legendary-twinkle 1.7s ease-in-out infinite; } .btn-legendary-spark:last-child { animation-delay: .85s; } .btn-legendary::before { content: ""; position: absolute; inset: -1.5px; z-index: 0; border-radius: inherit; padding: 2px; background: conic-gradient(from 0deg, #8fd9ea, #eef1f5, #c7ccd1, #ffffff, #8fd9ea, #7d8794, #8fd9ea); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: btn-legendary-shine-rotate 4.5s linear infinite; } .btn-legendary::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: linear-gradient(115deg, transparent 32%, rgba(143, 217, 234, .55) 49%, transparent 66%); background-size: 240% 100%; mix-blend-mode: overlay; animation: nav-cta-shimmer 4s linear infinite; pointer-events: none; } .btn-legendary:hover { transform: translateY(-2px) scale(1.03); border-color: rgba(143, 217, 234, .55); box-shadow: 0 14px 34px rgba(0, 0, 0, .5), 0 0 30px rgba(143, 217, 234, .5), 0 0 30px rgba(199, 204, 209, .35); } @keyframes btn-legendary-shine-rotate { to { transform: rotate(360deg); } } @keyframes btn-legendary-text-shine { 0% { background-position: 0% 50%; } 100% { background-position: 260% 50%; } } @keyframes btn-legendary-twinkle { 0%, 100% { opacity: .5; transform: scale(.85) rotate(0deg); } 50% { opacity: 1; transform: scale(1.2) rotate(15deg); } } @keyframes btn-legendary-halo { 0%, 100% { box-shadow: 0 8px 22px rgba(0, 0, 0, .45), 0 0 16px rgba(143, 217, 234, .22); } 50% { box-shadow: 0 8px 22px rgba(0, 0, 0, .45), 0 0 32px rgba(143, 217, 234, .5); } } @media (prefers-reduced-motion: reduce) { .btn-legendary, .btn-legendary::before, .btn-legendary::after, .btn-legendary-text, .btn-legendary-spark { animation: none; } } /* ===================================================================== "Gesperrter Tresor"-Knopf für den DogiCrew-Registrieren-Knopf (abonnieren.html, 20.08.2026, Nutzer-Wunsch: "richtig krank übertrieben geiles... weil es wird ja das geilste Bonus und überhaupt so von mir"). Bewusst KEINE Wiederverwendung von .btn-silver — der ist neutral-grau und auf DIESER Seite bereits für die Teddy-Kollektion (Nebensache) vergeben. Chrome-Text-Clip-Schimmer + Schimmer-Sweep + Halo-Puls wie .btn-silver/ .btn-legendary, aber in den ECHTEN Gold-Tönen dieser Seite (#ffe9a8/#d4af37, siehe .abo-panel .btn) und mit einem pulsierenden Schloss statt Sternen, damit die Haupt-CTA sichtbar "das Besondere, noch verschlossene" bleibt statt nur "irgendwann verfügbar". WICHTIG: Für den Rand bewusst NICHT die rotierende Conic-Gradient-Maske von .btn-silver/.btn-legendary kopiert — dieser Knopf läuft über `width:100%` auf voller Kartenbreite (~440px) bei nur ~62px Höhe, also ein sehr langgestrecktes Rechteck. Genau für diesen Fall ist die dokumentierte Lektion in Projektregeln.md Punkt 14 gedacht (03.08.2026, "TikTok-Button-Bug"): ein rotierendes maskiertes Pseudo-Element verzieht sich auf länglichen Formen zu einer krummen Schlaufe, weil ein Rechteck beim Rotieren nicht rotationssymmetrisch ist — live mit Playwright- Screenshots über mehrere Frames nachgewiesen (die Schlaufe ist der rotierende Rand bei verschiedenen Winkeln). Stattdessen derselbe sichere Zwei-Layer-Background-Trick wie bei .abo-google-frame weiter oben in dieser Datei (Füllung padding-box + Verlauf border-box, Bewegung nur über background-position) — bleibt geometrisch exakt an der Kontur, unabhängig vom Seitenverhältnis. Reine Deko/Statusanzeige — echte Deaktivierung läuft über das native disabled-Attribut am