diff --git a/assets/css/main.css b/assets/css/main.css index fce24ee..08b5863 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -191,33 +191,113 @@ header.site-header { } .nav-dropdown a:hover, .nav-dropdown a.active { background: var(--bg-alt); color: var(--accent); } -/* Sprachumschalter — schmalerer Dropdown reicht (nur Flagge + 2-stelliges - Kürzel pro Zeile), rechtsbündig statt zentriert, damit er nicht über - den Seitenrand hinausragt. */ -.sprach-schalter > button { font-size: 1.02rem; align-items: center; } -.sprach-schalter .nav-dropdown { min-width: 175px; left: auto; right: 0; transform: none; } -.sprach-schalter .nav-dropdown a { display: flex; align-items: center; gap: .6rem; } -/* Kleine "Weltkugel", die die Farben der jeweils aktiven Sprache annimmt - (Landesfarben als Verlauf) statt eines Flaggen-Emojis — Windows stellt +/* =================================================================== + 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: 1rem; + font-weight: 700; + align-items: center; + gap: .5rem; + padding: .4rem 1rem .4rem .55rem; + border-radius: 999px; + border: 1px solid color-mix(in srgb, var(--sprach-glut) 55%, rgba(255, 255, 255, .18)); + background: + radial-gradient(circle at 28% 25%, color-mix(in srgb, var(--sprach-glut) 30%, transparent), transparent 65%), + rgba(255, 255, 255, .04); + box-shadow: + inset 0 0 0 1px rgba(255, 255, 255, .05), + 0 3px 10px rgba(0, 0, 0, .35), + 0 0 16px color-mix(in srgb, var(--sprach-glut) 40%, 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: color-mix(in srgb, var(--sprach-glut) 80%, white 10%); + 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: 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; } +} +.sprach-schalter .nav-dropdown { + min-width: 190px; + left: auto; + right: 0; + transform: none; + padding: .4rem; + border-radius: 14px; + border-color: color-mix(in srgb, var(--sprach-glut) 45%, var(--border)); + background: color-mix(in srgb, var(--card-bg) 92%, var(--sprach-glut) 8%); + box-shadow: 0 14px 34px rgba(0, 0, 0, .5), 0 0 26px color-mix(in srgb, var(--sprach-glut) 25%, transparent); + transform-origin: top right; + animation: sprach-dropdown-in .18s ease both; +} +@keyframes sprach-dropdown-in { + from { opacity: 0; transform: translateY(-6px) scale(.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} +.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: color-mix(in srgb, var(--sprach-glut) 20%, var(--bg-alt)); + 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 selbst eingefärbter Farbverlauf funktioniert dagegen - garantiert überall gleich. Glanzlicht + Schatten sorgen dafür, dass es - wie eine kleine Kugel statt einer flachen Fläche wirkt. */ + main.js). Ein außermittiges Glanzlicht + langsame Drehung lassen sie + wie eine echte, beleuchtete Kugel wirken statt einer flachen Fläche. */ .sprach-kugel { display: inline-block; - width: 15px; - height: 15px; + width: 18px; + height: 18px; border-radius: 50%; - vertical-align: -2px; + vertical-align: -4px; + background: + radial-gradient(circle at 32% 26%, #fff 0%, color-mix(in srgb, var(--sprach-glut) 85%, white 15%) 16%, var(--sprach-glut) 52%, color-mix(in srgb, var(--sprach-glut) 55%, black 45%) 100%); box-shadow: - inset -2px -2px 4px rgba(0, 0, 0, .45), - inset 2px 2px 3px rgba(255, 255, 255, .55), - 0 0 7px 1px color-mix(in srgb, var(--sprach-glut, transparent) 85%, transparent), - 0 0 16px 2px color-mix(in srgb, var(--sprach-glut, transparent) 55%, transparent); + 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; + animation: sprach-glut-puls 3.2s ease-in-out infinite, sprach-kugel-dreh 7s linear infinite; } -/* Die Sprachfarbe zieht sich jetzt auch über die Schrift — kräftiger, +.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). */ @@ -228,17 +308,17 @@ header.site-header { 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-schalter .nav-dropdown a:hover, -.sprach-schalter .nav-dropdown a.active { - background: color-mix(in srgb, var(--sprach-glut, var(--bg-alt)) 16%, var(--bg-alt)); -} .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.25) saturate(1.3); } + 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 { animation: none; } + .sprach-kugel, .sprach-kurz, .sprach-schalter > button::after, .sprach-schalter .nav-dropdown { animation: none; } } /* "Bewerben" ist der Treffpunkt beider Welten (Team Dogi + Spicy Media) — diff --git a/assets/js/main.js b/assets/js/main.js index 37aaaaf..dab7349 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -36,17 +36,18 @@ "GB EN" (Flagge≠Sprachcode bei Englisch) usw. Ein einzelnes Globus-Symbol im Knopf plus volle Sprachnamen im Dropdown ist eindeutig und funktioniert auf jedem Betriebssystem gleich. */ - /* Pro Sprache eine kräftige, gut leuchtende Akzentfarbe (glut) für Text - + Kugel-Glanz, plus einen zweifarbigen Verlauf (farben) für die Kugel - selbst — angelehnt an die jeweilige Landesfarbe, aber bewusst - gesättigter/heller gewählt (nicht die originalen, oft eher stumpfen - Flaggenfarben), damit der Polarlicht-Leuchteffekt gut trägt. */ + /* Pro Sprache eine kräftige, gut leuchtende Akzentfarbe (glut) — für + Schrift-Leuchten, Knopf-Aurora und die glänzende Kugel (deren + Farbverlauf wird rein in CSS aus dieser einen Farbe gebaut, siehe + .sprach-kugel in main.css). Angelehnt an die jeweilige Landesfarbe, + aber bewusst gesättigter/heller (nicht die originalen, oft eher + stumpfen Flaggenfarben), damit der Polarlicht-Effekt gut trägt. */ const SPRACHEN = [ - { code: "de", kurz: "DE", name: "Deutsch", glut: "#ffb300", farben: "linear-gradient(160deg, #ffe066 0%, #ff8c00 100%)" }, - { code: "de-CH", kurz: "CH", name: "Schwiizerdütsch", glut: "#ff3b3b", farben: "linear-gradient(160deg, #ff8080 0%, #d90000 100%)" }, - { code: "en", kurz: "EN", name: "English", glut: "#2f6bff", farben: "linear-gradient(160deg, #7fa8ff 0%, #1a3fd6 100%)" }, - { code: "fr", kurz: "FR", name: "Français", glut: "#00c2ff", farben: "linear-gradient(160deg, #7fe3ff 0%, #0090cc 100%)" }, - { code: "pt", kurz: "PT", name: "Português", glut: "#20d97a", farben: "linear-gradient(160deg, #7cf5b0 0%, #0a9e4c 100%)" }, + { code: "de", kurz: "DE", name: "Deutsch", glut: "#ffb300" }, + { code: "de-CH", kurz: "CH", name: "Schwiizerdütsch", glut: "#ff3b3b" }, + { code: "en", kurz: "EN", name: "English", glut: "#2f6bff" }, + { code: "fr", kurz: "FR", name: "Français", glut: "#00c2ff" }, + { code: "pt", kurz: "PT", name: "Português", glut: "#20d97a" }, ]; const SPRACHE_SCHLUESSEL = "dogi-sprache"; @@ -259,15 +260,15 @@ const aktuell = getSprache(); const aktiv = SPRACHEN.find((s) => s.code === aktuell) || SPRACHEN[0]; return ` - `;