From d00bb4ba1d482931ee79e853b9e7f8730d1b30d5 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Sun, 10 May 2026 15:17:47 +0200 Subject: [PATCH] SEO Quick-Wins: Schema.org, Meta-Hygiene, llms.txt, Performance, Aufraeumen - Title Iran-Konflikt mit Bindestrich (Konsistenz mit OG/Schema) - Meta-Hygiene auf 12 Seiten: robots index/follow + max-image-preview:large, theme-color #0A1832, author AegisSight UG - sitemap.xml: lastmod-Tag pro URL (besseres Crawl-Signal) - Hauptseite (DE+EN): Schema.org WebSite + SoftwareApplication ergaenzt (Sitelinks, Rich Result fuer Software-Produkt) - Lagen-Seiten (6): Schema.org BreadcrumbList (Home -> Topic) - llms.txt: Site-Struktur fuer KI-Crawler (mit Hinweis Live-Search-Bots erlaubt, Training-Bots geblockt) - Performance: Hero-Slides 2-5 preload=metadata -> none (Slide 1 bleibt auto/LCP) - Aufraeumen: 5 tote CSS-Files, 7 tote JS-Files, robots-launch.txt + sitemap-launch.xml entfernt --- CLAUDE.md | 15 +- css/about-modern.css | 612 ------------------------- css/animations-enhanced.css | 222 --------- css/animations.css | 271 ----------- css/products-modern.css | 502 -------------------- css/section-transitions.css | 437 ------------------ datenschutz.html | 3 + en/index.html | 71 ++- en/legal-notice.html | 3 + en/privacy.html | 3 + en/situations/cyber-attacks/index.html | 24 + en/situations/deepfakes/index.html | 24 + en/situations/iran-conflict/index.html | 24 + impressum.html | 3 + index.html | 71 ++- js/animations-enhanced.js | 233 ---------- js/animations.js | 403 ---------------- js/components.js | 515 --------------------- js/hero-videos.js | 209 --------- js/legal-pages.js | 54 --- js/main.js | 305 ------------ js/section-transitions.js | 130 ------ lagen/cyberangriffe/index.html | 24 + lagen/deepfakes/index.html | 24 + lagen/iran-konflikt/index.html | 26 +- llms.txt | 43 ++ robots-launch.txt | 99 ---- sitemap-launch.xml | 100 ---- sitemap.xml | 12 + 29 files changed, 356 insertions(+), 4106 deletions(-) delete mode 100644 css/about-modern.css delete mode 100644 css/animations-enhanced.css delete mode 100644 css/animations.css delete mode 100644 css/products-modern.css delete mode 100644 css/section-transitions.css delete mode 100644 js/animations-enhanced.js delete mode 100644 js/animations.js delete mode 100644 js/components.js delete mode 100644 js/hero-videos.js delete mode 100644 js/legal-pages.js delete mode 100644 js/main.js delete mode 100644 js/section-transitions.js create mode 100644 llms.txt delete mode 100644 robots-launch.txt delete mode 100644 sitemap-launch.xml diff --git a/CLAUDE.md b/CLAUDE.md index d77b57b..2bfcee6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,7 +46,7 @@ STRUCTURE: - accountforger-video.html: Geschützte Produkt-Demo (auth_request gegen Security-Dashboard) - cookie-consent.js, cookie-consent.css: GDPR Cookie-System (liest selbständig) - analytics-events.js: Umami-Custom-Events - - favicon.svg, de.svg, en.svg, robots.txt, robots-launch.txt, sitemap-launch.xml + - favicon.svg, de.svg, en.svg, robots.txt, sitemap.xml, llms.txt - LAUNCH-CHECKLIST.md, DATENSCHUTZ_ANALYTICS.md, COOKIE_CONSENT_IMPLEMENTATION.md, PROFESSIONAL_TOOLBOX_CONTENT.md, VIDEO_UPLOAD_INSTRUCTIONS.md: interne Doku directories: @@ -79,16 +79,14 @@ STRUCTURE: - mobile.css: Mobile Responsive - fonts.css: Typografie - lang-switcher.css: Sprachumschalter-Komponente (DE/EN) - legacy_nicht_eingebunden: - - about-modern.css, animations.css, animations-enhanced.css, products-modern.css, section-transitions.css + # Legacy CSS-Files am 2026-05-10 entfernt js/: aktiv_eingebunden: - app.js: Hero-Slider, Smooth-Scroll, Mobile-Menü, 3D-Karussell, Leaflet-Karte, Live-Daten, Kontaktformular - config.js: globale Konfiguration - mobile-nav.js: Mobile-Menü-Helfer - legacy_nicht_eingebunden: - - main.js, components.js, animations.js, animations-enhanced.js, hero-videos.js, legal-pages.js, section-transitions.js + # Legacy JS-Files am 2026-05-10 entfernt docs/: Legacy-PDFs aus IntelSight-Zeit, von der aktuellen Seite nicht mehr verlinkt - datenschutzerklaerung_intelsight_de_de.pdf, impressum_intelsight_de_de.pdf, Sitemap_IntelSight_UG.docx @@ -213,6 +211,13 @@ CHANGE_LOG: - "STRUCTURE: aktive vs. legacy CSS/JS getrennt, videos/, downloads/, insights/, accountforger-video.html, weitere Top-Level-Files ergänzt" - "Lagen-Layout: cyberangriffe und deepfakes binden Lagebild-CSS/JS aus iran-konflikt ein (zentrale Assets)" - "SERVICES: sync-lagebild und insights ergänzt" + - "SEO Quick-Wins: Title-Konsistenz Iran-Konflikt; Meta-Hygiene auf 12 Seiten (robots index/follow + max-image-preview:large, theme-color, author)" + - "Sitemap mit lastmod-Tag pro URL" + - "Hauptseite Schema.org erweitert: WebSite + SoftwareApplication (mit featureList und offers)" + - "Lagen-Seiten Schema.org BreadcrumbList ergänzt (Home -> Topic)" + - "llms.txt angelegt (Site-Struktur für KI-Crawler)" + - "Performance: Hero-Slides 2-5 preload=metadata -> none (Slide 1 bleibt auto)" + - "Repo aufgeräumt: 5 tote CSS-Files in /css/, 7 tote JS-Files in /js/, robots-launch.txt + sitemap-launch.xml entfernt" - "SEO Stufe 1: noindex/nofollow von 12 indexierbaren Seiten entfernt; robots.txt scharf geschaltet (Live-Search-AI-Bots erlaubt, Training-Bots geblockt); sitemap.xml deployt" - "Lagen-Seiten: description, canonical, Open Graph, Twitter Card, Schema.org Article ergänzt; Topic-Default in #incident-title als Crawler-Fallback" diff --git a/css/about-modern.css b/css/about-modern.css deleted file mode 100644 index 750bb94..0000000 --- a/css/about-modern.css +++ /dev/null @@ -1,612 +0,0 @@ -/* Modern About Section Redesign */ - -/* About Section Background */ -.about-section { - background: linear-gradient(135deg, var(--color-white) 0%, var(--color-gray-50) 100%); - position: relative; - overflow: hidden; - padding: var(--space-4xl) 0; -} - -.about-section::before { - content: ''; - position: absolute; - top: -50%; - right: -20%; - width: 60%; - height: 60%; - background: radial-gradient(circle, rgba(10, 24, 50, 0.04) 0%, transparent 70%); - border-radius: 50%; - animation: float-slow 20s ease-in-out infinite; -} - -@keyframes float-slow { - 0%, 100% { transform: translate(0, 0) scale(1); } - 33% { transform: translate(-30px, -30px) scale(1.05); } - 66% { transform: translate(30px, -20px) scale(0.95); } -} - -/* Modern Tab Navigation */ -.about-tabs { - display: flex; - justify-content: center; - gap: 20px; - margin-bottom: 4rem; - position: relative; - padding: 10px; - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(10px); - border-radius: 100px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08); - max-width: 800px; - margin-left: auto; - margin-right: auto; - border: none; -} - -.about-tab { - background: transparent; - border: none; - color: var(--color-gray-600); - padding: 15px 30px; - cursor: pointer; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - font-size: 1rem; - font-weight: 600; - border-radius: 50px; - position: relative; - overflow: hidden; - z-index: 1; -} - -.about-tab::before { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 0; - height: 0; - border-radius: 50px; - background: var(--color-navy); - transform: translate(-50%, -50%); - transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); - z-index: -1; -} - -.about-tab.active::before { - width: 100%; - height: 100%; -} - -.about-tab.active { - color: var(--color-white); - transform: scale(1.05); - box-shadow: 0 8px 20px rgba(10, 24, 50, 0.3); -} - -.about-tab:hover:not(.active) { - color: var(--color-gold-dark); - transform: translateY(-2px); - background: rgba(200, 168, 81, 0.08); -} - -/* Tab Content Panels */ -.about-content { - max-width: 1200px; - margin: 0 auto; - position: relative; -} - -.about-panel { - display: none; - animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1); -} - -.about-panel.active { - display: block; -} - -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -/* Company Tab - Cards Layout */ -#who-we-are .panel-text { - display: flex; - gap: 40px; - align-items: stretch; - min-height: 500px; -} - -.company-cards-wrapper { - display: flex; - flex-direction: column; - gap: 30px; - width: 50%; - justify-content: space-between; -} - -.company-card { - background: white; - border-radius: 20px; - padding: 40px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08); - position: relative; - overflow: hidden; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - flex: 1; - display: flex; - flex-direction: column; -} - -.company-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 4px; - height: 100%; - background: #0A1832; - transform: scaleY(0); - transition: transform 0.4s; -} - -.company-card:hover::before { - transform: scaleY(1); -} - -.company-card:hover { - transform: translateX(6px); - box-shadow: 0 12px 32px rgba(10, 24, 50, 0.1); -} - -.company-card h4 { - color: var(--color-navy); - font-size: 1.4rem; - margin-bottom: 15px; - display: flex; - align-items: center; - gap: 15px; -} - -.company-card-icon { - width: 70px; - height: 70px; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.1), rgba(0, 64, 110, 0.05)); - border-radius: 20px; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - transition: all 0.4s; -} - -.company-card:hover .company-card-icon { - transform: scale(1.1) rotate(5deg); - background: #0A1832; -} - -.company-card-icon img { - width: 35px; - height: 35px; - filter: brightness(0) saturate(100%) invert(42%) sepia(82%) saturate(723%) hue-rotate(178deg) brightness(98%) contrast(92%); - transition: filter 0.4s; -} - -.company-card:hover .company-card-icon img { - filter: brightness(0) saturate(100%) invert(100%); -} - -/* Mission & Values - Modern Grid */ -.mission-grid { - text-align: left; -} - -.mission-header { - background: #0A1832; - color: white; - padding: 60px; - border-radius: 30px; - margin-bottom: 40px; - position: relative; - overflow: hidden; -} - -.mission-header::after { - content: ''; - position: absolute; - top: -50%; - right: -10%; - width: 50%; - height: 200%; - background: rgba(255, 255, 255, 0.1); - transform: rotate(45deg); -} - -.mission-header h3 { - font-size: 2.5rem; - margin-bottom: 20px; - position: relative; - z-index: 1; - color: #ffffff; -} - -.mission-header p { - font-size: 1.2rem; - position: relative; - z-index: 1; - opacity: 0.95; -} - -.values-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 30px; - margin: 3rem 0; -} - -.value-card { - background: white; - border-radius: 24px; - padding: 35px; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - position: relative; - overflow: hidden; - border: 2px solid transparent; - cursor: pointer; -} - -.value-card::after { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.1) 0%, transparent 100%); - opacity: 0; - transition: opacity 0.4s; -} - -.value-card:hover::after { - opacity: 1; -} - -.value-card:hover { - transform: translateY(-4px); - box-shadow: 0 12px 32px rgba(10, 24, 50, 0.12); - border-color: var(--color-navy); -} - -.value-icon { - width: 100px; - height: 100px; - margin-bottom: 20px; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.1), rgba(0, 64, 110, 0.05)); - border-radius: 30px; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.4s; -} - -.value-icon img { - width: 50px; - height: 50px; - filter: brightness(0) saturate(100%) invert(42%) sepia(82%) saturate(723%) hue-rotate(178deg) brightness(98%) contrast(92%); - transition: filter 0.4s; -} - -.value-card:hover .value-icon { - transform: scale(1.1) rotate(5deg); - background: #0A1832; -} - -.value-card:hover .value-icon img { - filter: brightness(0) saturate(100%) invert(100%); -} - -/* Competencies - Timeline Style */ -.competencies-list { - position: relative; - padding-left: 40px; -} - -.competencies-list::before { - content: ''; - position: absolute; - left: 10px; - top: 0; - width: 3px; - height: 100%; - background: #0A1832; - border-radius: 2px; -} - -.competency-item { - display: grid; - grid-template-columns: auto 1fr; - gap: 30px; - align-items: center; - padding: 30px; - margin-bottom: 30px; - background: white; - border-radius: 20px; - position: relative; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05); -} - -.competency-item::before { - content: ''; - position: absolute; - left: -30px; - top: 50%; - transform: translateY(-50%); - width: 20px; - height: 20px; - background: white; - border: 4px solid #0f72b5; - border-radius: 50%; - z-index: 1; -} - -.competency-item:hover { - transform: translateX(10px); - box-shadow: 0 8px 24px rgba(10, 24, 50, 0.1); -} - -.competency-number { - font-size: 3rem; - font-weight: 700; - background: linear-gradient(135deg, #C8A851, #B39645); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - opacity: 1; -} - -/* Why AegisSight - 2x2 Grid */ -.why-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 30px; - grid-auto-rows: minmax(250px, auto); -} - -.why-card { - grid-column: span 1; - grid-row: span 1; -} - -.why-card { - background: white; - border-radius: 24px; - padding: 35px; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - position: relative; - overflow: hidden; - display: flex; - flex-direction: column; - justify-content: space-between; - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08); - border: 2px solid transparent; -} - -.why-card:hover { - transform: translateY(-4px); - box-shadow: 0 12px 24px rgba(10, 24, 50, 0.1); - border-color: rgba(10, 24, 50, 0.2); -} - -.why-icon { - width: 100px; - height: 100px; - margin: 0 auto 25px; - display: flex; - align-items: center; - justify-content: center; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.1), rgba(0, 64, 110, 0.05)); - border-radius: 30px; - transition: all 0.4s; -} - -.why-icon img { - width: 50px; - height: 50px; - filter: brightness(0) saturate(100%) invert(42%) sepia(82%) saturate(723%) hue-rotate(178deg) brightness(98%) contrast(92%); - transition: filter 0.4s; -} - -/* German Flag Icon Special Styling */ -.german-flag-icon { - background: transparent !important; - padding: 15px; -} - -.german-flag-icon img { - width: 70px !important; - height: 42px !important; - border-radius: 4px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - filter: none !important; -} - -.why-card:hover .german-flag-icon { - background: transparent !important; - transform: scale(1.15); -} - -.why-card:hover .german-flag-icon img { - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); - filter: none !important; -} - -.why-card:hover .why-icon { - transform: scale(1.1) rotate(5deg); - background: #0A1832; -} - -.why-card:hover .why-icon img { - filter: brightness(0) saturate(100%) invert(100%); -} - -.why-card h4 { - font-size: 1.6rem; - margin-bottom: 20px; - color: var(--color-navy); - text-align: center; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.why-card p { - color: var(--color-gray-600); - line-height: 1.8; - flex-grow: 1; - text-align: center; - font-size: 1.05rem; -} - -/* Location Section with Map */ -.location-section { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 45%; - margin-left: auto; - height: 100%; -} - -.mini-germany-map { - flex: 1; - width: 100%; - max-width: 350px; - padding: 30px; - background: white; - border-radius: 20px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08); - display: flex; - align-items: center; - justify-content: center; - transition: all 0.3s; - margin-bottom: 20px; - position: relative; - overflow: hidden; -} - -.mini-germany-map::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: radial-gradient(circle at 35% 45%, rgba(10, 24, 50, 0.3) 0%, transparent 40%); - opacity: 0; - transition: opacity 0.4s ease; - pointer-events: none; - z-index: 2; -} - -.mini-germany-map:hover::before { - opacity: 1; -} - -.mini-germany-map:hover { - transform: scale(1.02); - box-shadow: 0 15px 50px rgba(10, 24, 50, 0.15); -} - -.mini-germany-map img { - width: 100%; - height: auto; - max-height: 100%; - object-fit: contain; - transition: all 0.4s ease; - position: relative; - z-index: 1; -} - -.mini-germany-map:hover img { - filter: brightness(1.1) contrast(1.1); -} - -/* Pulsing glow effect for NRW region */ -@keyframes nrwPulse { - 0%, 100% { - filter: drop-shadow(0 0 10px rgba(10, 24, 50, 0.5)); - } - 50% { - filter: drop-shadow(0 0 25px rgba(10, 24, 50, 0.8)); - } -} - -.mini-germany-map:hover img { - animation: nrwPulse 2s ease-in-out infinite; -} - -/* Location Badge Enhancement */ -.location-badge { - display: inline-flex; - align-items: center; - gap: 12px; - padding: 12px 24px; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.1), rgba(0, 64, 110, 0.05)); - border-radius: 100px; - color: #0f72b5; - font-weight: 600; - border: 2px solid rgba(15, 114, 181, 0.2); - transition: all 0.3s; -} - -.location-badge:hover { - background: #0A1832; - color: white; - transform: scale(1.05); - box-shadow: 0 10px 30px rgba(15, 114, 181, 0.3); -} - -.location-badge svg { - width: 24px; - height: 24px; - transition: all 0.3s; -} - -.location-badge:hover svg { - animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite; -} - -@keyframes ping { - 0%, 100% { - transform: scale(1); - opacity: 1; - } - 50% { - transform: scale(1.2); - opacity: 0.8; - } -} - -/* Responsive Design */ -@media (max-width: 768px) { - .about-tabs { - flex-direction: column; - border-radius: 20px; - gap: 10px; - } - - .why-grid { - grid-template-columns: 1fr; - } - - .competencies-list { - padding-left: 20px; - } -} \ No newline at end of file diff --git a/css/animations-enhanced.css b/css/animations-enhanced.css deleted file mode 100644 index 23efc87..0000000 --- a/css/animations-enhanced.css +++ /dev/null @@ -1,222 +0,0 @@ -/* Enhanced Modern Animations & Effects */ - -/* Glassmorphism Base */ -.glass { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); -} - -.glass-dark { - background: rgba(0, 0, 0, 0.3); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.1); -} - -/* Smooth Fade In Animations */ -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes fadeInScale { - from { - opacity: 0; - transform: scale(0.9); - } - to { - opacity: 1; - transform: scale(1); - } -} - -@keyframes slideInRight { - from { - opacity: 0; - transform: translateX(-50px); - } - to { - opacity: 1; - transform: translateX(0); - } -} - -/* Staggered Animation Classes */ -.animate-in { - opacity: 0; - animation: fadeInUp 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; -} - -.animate-in-scale { - opacity: 0; - animation: fadeInScale 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; -} - -.stagger-1 { animation-delay: 0.1s; } -.stagger-2 { animation-delay: 0.2s; } -.stagger-3 { animation-delay: 0.3s; } -.stagger-4 { animation-delay: 0.4s; } -.stagger-5 { animation-delay: 0.5s; } - -/* Floating Animation */ -@keyframes float { - 0%, 100% { transform: translateY(0px); } - 50% { transform: translateY(-20px); } -} - -.floating { - animation: float 6s ease-in-out infinite; -} - -/* Pulse Glow Animation - Dezent */ -@keyframes pulseGlow { - 0%, 100% { - box-shadow: - 0 0 5px rgba(10, 24, 50, 0.2), - 0 0 10px rgba(10, 24, 50, 0.1); - } - 50% { - box-shadow: - 0 0 10px rgba(10, 24, 50, 0.3), - 0 0 20px rgba(10, 24, 50, 0.15); - } -} - -.pulse-glow { - animation: pulseGlow 3s ease-in-out infinite; -} - -/* Gradient Animation */ -@keyframes gradientShift { - 0% { background-position: 0% 50%; } - 50% { background-position: 100% 50%; } - 100% { background-position: 0% 50%; } -} - -.gradient-animated { - background: linear-gradient( - -45deg, - var(--color-navy), - var(--color-navy-light), - var(--color-navy), - var(--color-blue) - ); - background-size: 400% 400%; - animation: gradientShift 15s ease infinite; -} - -/* Text Reveal Animation */ -@keyframes textReveal { - from { - clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); - } - to { - clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); - } -} - -.text-reveal { - animation: textReveal 1.5s cubic-bezier(0.77, 0, 0.175, 1) forwards; -} - -/* Card Hover Effects - Subtil */ -.card-hover-lift { - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.card-hover-lift:hover { - transform: translateY(-4px); - box-shadow: 0 12px 24px rgba(10, 24, 50, 0.12); -} - -/* Magnetic Button Effect */ -.magnetic-button { - position: relative; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); -} - -.magnetic-button::before { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 0; - height: 0; - border-radius: 50%; - background: rgba(255, 255, 255, 0.3); - transform: translate(-50%, -50%); - transition: width 0.6s, height 0.6s; -} - -.magnetic-button:hover::before { - width: 300px; - height: 300px; -} - -/* Parallax Layers */ -.parallax-slow { transform: translateZ(-1px) scale(1.5); } -.parallax-medium { transform: translateZ(-2px) scale(2); } -.parallax-fast { transform: translateZ(-3px) scale(2.5); } - -/* Reveal on Scroll */ -.reveal { - opacity: 0; - transform: translateY(50px); - transition: all 1s cubic-bezier(0.4, 0, 0.2, 1); -} - -.reveal.active { - opacity: 1; - transform: translateY(0); -} - -/* Smooth Scroll Indicator */ -@keyframes scrollDown { - 0% { - transform: translateY(0); - opacity: 0; - } - 40% { - opacity: 1; - } - 80% { - transform: translateY(20px); - opacity: 0; - } - 100% { - opacity: 0; - } -} - -.scroll-indicator-animated { - animation: scrollDown 2s infinite; -} - -/* Loading Shimmer - Für Gold-Akzente */ -@keyframes shimmer { - 0% { - background-position: -1000px 0; - } - 100% { - background-position: 1000px 0; - } -} - -.shimmer { - background: linear-gradient( - 90deg, - rgba(200, 168, 81, 0) 0%, - rgba(200, 168, 81, 0.2) 50%, - rgba(200, 168, 81, 0) 100% - ); - background-size: 1000px 100%; - animation: shimmer 3s infinite; -} diff --git a/css/animations.css b/css/animations.css deleted file mode 100644 index a0b4152..0000000 --- a/css/animations.css +++ /dev/null @@ -1,271 +0,0 @@ -/* Global Styles */ -:root { - --primary-blue: #0f72b5; - --dark-blue: #00406e; - --accent-blue: #0f72b5; - --secondary-blue: #00406e; - --light-gray: #f4f4f4; - --white: #FFFFFF; - --text-dark: #333333; - --border-gray: #e0e0e0; - --alert-red: #FF4444; - --success-green: #4CAF50; - --warning-yellow: #FFC107; -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; - background-color: var(--white); - color: var(--text-dark); - overflow-x: hidden; - line-height: 1.6; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 20px; -} - -/* Typography */ -h1, h2, h3, h4 { - font-family: 'Bebas Neue', cursive; - letter-spacing: 1px; -} - -.section-title { - font-size: 3.5rem; - text-align: center; - margin-bottom: 1rem; - position: relative; - display: inline-block; - width: 100%; -} - -.section-subtitle { - font-size: 1.2rem; - text-align: center; - opacity: 0.8; - margin-bottom: 3rem; - font-weight: 300; -} - -/* Navigation */ -.navbar { - position: fixed; - top: 0; - width: 100%; - z-index: 1000; - transition: all 0.3s ease; - background: var(--white); - border-bottom: 1px solid var(--border-gray); - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.nav-container { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1.5rem 2rem; -} - -.logo-img { - height: 55px; - width: auto; - filter: none; -} - -.nav-menu { - display: flex; - list-style: none; - gap: 2rem; -} - -.nav-menu a { - color: var(--text-dark); - text-decoration: none; - font-weight: 500; - font-size: 1rem; - transition: all 0.3s ease; - position: relative; -} - -.nav-menu a::after { - content: ''; - position: absolute; - bottom: -5px; - left: 0; - width: 0; - height: 2px; - background: var(--primary-blue); - transition: width 0.3s ease; -} - -.nav-menu a:hover::after { - width: 100%; -} - -.nav-extras { - display: flex; - align-items: center; - gap: 1rem; -} - -.lang-toggle { - background: transparent; - border: 1px solid var(--primary-blue); - color: var(--primary-blue); - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - transition: all 0.3s ease; - font-weight: 500; -} - -.lang-toggle:hover { - background: var(--primary-blue); - color: var(--white); -} - -.cta-button, .primary-button, .secondary-button { - padding: 0.75rem 1.5rem; - border: none; - border-radius: 4px; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - text-transform: none; - letter-spacing: 0.5px; -} - -.cta-button, .primary-button { - background: var(--primary-blue); - color: var(--white); -} - -.cta-button:hover, .primary-button:hover { - background: var(--dark-blue); - transform: translateY(-2px); - box-shadow: 0 5px 20px rgba(15, 114, 181, 0.3); -} - -.secondary-button { - background: transparent; - color: var(--primary-blue); - border: 2px solid var(--primary-blue); -} - -.secondary-button:hover { - background: var(--primary-blue); - color: var(--white); -} - -.large { - padding: 1rem 2rem; - font-size: 1.1rem; -} - -/* Hero Section */ -.hero { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - position: relative; - overflow: hidden; - padding-top: 100px; - background: #000000; -} - -/* Clean transition */ -.hero::after { - display: none; -} - -/* Video Background */ -.hero-video { - position: absolute; - top: 50%; - left: 50%; - min-width: 100%; - min-height: 100%; - width: auto; - height: auto; - transform: translate(-50%, -50%); - z-index: 0; - object-fit: cover; -} - -/* Video Overlay to match brand colors */ -.video-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(135deg, - rgba(15, 114, 181, 0.7) 0%, - rgba(0, 64, 110, 0.7) 50%, - rgba(15, 114, 181, 0.7) 100%); - mix-blend-mode: multiply; - z-index: 1; -} - -#particleCanvas { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 2; -} - -.hero-content { - text-align: center; - z-index: 3; - position: relative; -} - -.hero-title { - margin-bottom: 2rem; -} - -.subtitle { - display: block; - font-size: 1.2rem; - margin-bottom: 0.5rem; - color: var(--text-dark); - font-weight: 400; - letter-spacing: 1px; -} - -.main-title { - display: block; - font-size: 3.5rem; - letter-spacing: 2px; - color: var(--primary-blue); - font-weight: 700; -} - -.hero-text { - font-size: 1.1rem; - margin-bottom: 3rem; - color: var(--text-dark); -} - - -.hero-cta { - display: flex; - gap: 1rem; - justify-content: center; - margin-top: 2rem; -} - - - diff --git a/css/products-modern.css b/css/products-modern.css deleted file mode 100644 index bb2e062..0000000 --- a/css/products-modern.css +++ /dev/null @@ -1,502 +0,0 @@ -/* Modern Products Section Design */ - -.products-section { - background: var(--color-navy); - position: relative; - padding: var(--space-4xl) 0; - overflow: hidden; -} - -/* Animated Background */ -.products-section::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: - radial-gradient(circle at 20% 50%, rgba(19, 40, 68, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 50%, rgba(19, 40, 68, 0.2) 0%, transparent 50%), - radial-gradient(circle at 50% 100%, rgba(200, 168, 81, 0.05) 0%, transparent 50%); - animation: backgroundShift 20s ease-in-out infinite; -} - -@keyframes backgroundShift { - 0%, 100% { transform: translate(0, 0) scale(1); } - 33% { transform: translate(-20px, -20px) scale(1.1); } - 66% { transform: translate(20px, -10px) scale(0.95); } -} - -/* Section Title */ -.products-section .section-title { - color: #ffffff; - font-size: 3.5rem; - text-transform: uppercase; - letter-spacing: 3px; - margin-bottom: 20px; - position: relative; - display: inline-block; - animation: titleGlow 3s ease-in-out infinite; -} - -@keyframes titleGlow { - 0%, 100% { text-shadow: 0 0 15px rgba(200, 168, 81, 0.3); } - 50% { text-shadow: 0 0 25px rgba(200, 168, 81, 0.5), 0 0 40px rgba(200, 168, 81, 0.2); } -} - -.products-section .section-subtitle { - color: rgba(255, 255, 255, 0.7); - font-size: 1.3rem; - margin-bottom: 80px; -} - -/* Products Container */ -.products-container { - max-width: 1400px; - margin: 0 auto; - padding: 0 20px; - position: relative; - z-index: 2; -} - -/* Products Grid */ -.products-grid { - display: flex; - flex-direction: column; - align-items: center; - gap: 30px; - margin-bottom: 60px; -} - -/* Product Card */ -.product-card { - background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(245, 245, 245, 0.95)); - border: 1px solid rgba(200, 168, 81, 0.3); - border-radius: var(--radius-lg); - padding: 0; - position: relative; - overflow: visible; - transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); - cursor: pointer; - width: 90%; - max-width: 900px; - display: flex; - flex-direction: column; - backdrop-filter: blur(10px); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); -} - -.product-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: linear-gradient(135deg, transparent 0%, rgba(15, 114, 181, 0.05) 100%); - opacity: 0; - transition: opacity 0.5s; - border-radius: 20px; -} - -.product-card:hover::before { - opacity: 1; -} - -.product-card:hover { - transform: translateY(-6px); - background: linear-gradient(135deg, rgba(255, 255, 255, 1), rgba(250, 250, 250, 1)); - border-color: var(--color-gold); - box-shadow: - 0 20px 40px rgba(0, 0, 0, 0.3), - 0 0 40px rgba(200, 168, 81, 0.1); -} - -/* Product Header */ -.product-header { - padding: 40px 40px 30px; - background: linear-gradient(135deg, rgba(10, 24, 50, 0.1) 0%, transparent 50%); - border-bottom: 1px solid rgba(200, 168, 81, 0.2); - display: grid; - grid-template-columns: 80px 1fr; - align-items: center; - gap: 25px; -} - -.product-icon-wrapper { - width: 80px; - height: 80px; - position: relative; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.product-icon-bg { - position: absolute; - width: 100%; - height: 100%; - background: linear-gradient(135deg, var(--color-navy), var(--color-gold)); - border-radius: var(--radius-lg); - opacity: 0.1; - transition: all 0.5s; -} - -.product-card:hover .product-icon-bg { - opacity: 0.25; - transform: rotate(5deg) scale(1.05); - background: linear-gradient(135deg, var(--color-navy), var(--color-gold-dark)); -} - -.product-icon { - position: relative; - z-index: 1; - width: 50px; - height: 50px; - filter: brightness(0) saturate(100%) invert(8%) sepia(13%) saturate(4290%) hue-rotate(189deg) brightness(95%) contrast(97%); - transition: all 0.5s; -} - -.product-card:hover .product-icon { - transform: scale(1.1); - filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%); -} - -.product-title-wrapper { - display: flex; - flex-direction: column; - gap: 5px; - align-items: center; - text-align: center; - padding-right: 105px; -} - -.product-title { - color: #0A1832; - font-size: 1.8rem; - font-weight: 700; - margin: 0; - transition: all 0.3s; -} - -/* Specific styling for product titles */ -.product-title[data-translate="productAccountForgerTitle"], -.product-title[data-translate="productOsintMonitorTitle"] { - color: #0A1832; -} - -.product-card:hover .product-title { - color: var(--color-navy); -} - -.product-tagline { - color: rgba(0, 0, 0, 0.6); - font-size: 0.9rem; - text-transform: uppercase; - letter-spacing: 2px; - font-weight: 500; - margin: 0; -} - -/* Product Body */ -.product-body { - padding: 30px 40px; - flex-grow: 1; - display: flex; - flex-direction: column; -} - -.product-description { - color: rgba(0, 0, 0, 0.7); - line-height: 1.8; - margin-bottom: 30px; - flex-grow: 1; -} - -/* Product Features */ -.product-features { - list-style: none; - padding: 0; - margin: 0 0 30px 0; -} - -.product-features li { - color: rgba(255, 255, 255, 0.7); - padding: 8px 0; - padding-left: 30px; - position: relative; - transition: all 0.3s; -} - -.product-features li::before { - content: '▸'; - position: absolute; - left: 0; - color: var(--color-gold); - font-size: 1.2rem; - transition: all 0.3s; -} - -.product-card:hover .product-features li { - color: rgba(255, 255, 255, 0.9); - transform: translateX(5px); -} - -.product-card:hover .product-features li::before { - color: var(--color-gold-light); - transform: translateX(3px); -} - -/* Product Footer */ -.product-footer { - padding: 30px 40px; - background: rgba(10, 24, 50, 0.05); - border-top: 1px solid rgba(200, 168, 81, 0.2); - display: flex; - justify-content: space-between; - align-items: center; -} - -.product-status { - display: flex; - align-items: center; - gap: 10px; -} - -.status-dot { - width: 8px; - height: 8px; - background: #00ff00; - border-radius: 50%; - animation: pulse 2s infinite; -} - -@keyframes pulse { - 0%, 100% { opacity: 1; transform: scale(1); } - 50% { opacity: 0.5; transform: scale(1.2); } -} - -.status-text { - color: rgba(255, 255, 255, 0.6); - font-size: 0.9rem; -} - -/* Learn More Button */ -.product-learn-more { - background: var(--color-gold); - border: 2px solid var(--color-gold); - color: var(--color-navy); - padding: 10px 25px; - border-radius: 50px; - cursor: pointer; - transition: all 0.3s; - font-size: 0.95rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 1px; - position: relative; - overflow: hidden; -} - -.product-learn-more::before { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 0; - height: 0; - background: var(--color-navy); - transform: translate(-50%, -50%); - transition: all 0.5s; - border-radius: 50px; -} - -.product-learn-more:hover::before { - width: 100%; - height: 100%; -} - -.product-learn-more:hover { - color: var(--color-gold); - border-color: var(--color-gold); - transform: translateY(-2px); - box-shadow: 0 10px 30px rgba(200, 168, 81, 0.3); -} - -.product-learn-more span { - position: relative; - z-index: 1; -} - -/* Tools Grid Styling - Inside Product Body */ -.product-body .tools-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 15px; - margin-top: 20px; - max-height: 0; - overflow: hidden; - opacity: 0; - transition: max-height 0.6s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease-in-out; - visibility: hidden; -} - -.product-body .tools-grid.expanded { - max-height: 2000px; - opacity: 1; - visibility: visible; -} - -/* Responsive grid adjustment */ -@media (max-width: 768px) { - .product-body .tools-grid { - grid-template-columns: 1fr; - } -} - -@media (min-width: 769px) and (max-width: 1024px) { - .product-body .tools-grid { - grid-template-columns: repeat(2, 1fr); - } -} - -.tools-grid .tool-card { - background: rgba(0, 0, 0, 0.03); - border-radius: 12px; - padding: 20px; - transition: all 0.3s; - border: 1px solid rgba(0, 0, 0, 0.1); -} - -.tools-grid .tool-card:hover { - transform: translateY(-3px); - background: rgba(0, 0, 0, 0.05); - border-color: rgba(200, 168, 81, 0.3); - box-shadow: 0 5px 15px rgba(10, 24, 50, 0.1); -} - -.tools-grid .tool-icon { - width: 60px; - height: 60px; - margin-bottom: 15px; - display: flex; - align-items: center; - justify-content: center; - background: linear-gradient(135deg, rgba(15, 114, 181, 0.15), rgba(0, 64, 110, 0.1)); - border-radius: 15px; -} - -.tools-grid .tool-icon img { - width: 35px; - height: 35px; - filter: brightness(0) saturate(100%) invert(52%) sepia(82%) saturate(723%) hue-rotate(178deg) brightness(108%) contrast(92%); -} - -.tools-grid h4 { - color: var(--color-navy); - font-size: 1.2rem; - margin-bottom: 15px; - font-weight: 600; -} - -.tools-grid .tool-features ul { - list-style: none; - padding: 0; -} - -.tools-grid .tool-features li { - color: rgba(0, 0, 0, 0.7); - padding: 5px 0; - font-size: 0.9rem; - position: relative; - padding-left: 20px; - line-height: 1.5; -} - -.tools-grid .tool-features li::before { - content: '▸'; - position: absolute; - left: 0; - color: var(--color-gold); - font-weight: bold; -} - -/* Responsive Design */ -@media (max-width: 968px) { - .products-grid { - grid-template-columns: 1fr; - } - - .product-card.featured { - grid-column: span 1; - } - - .products-section .section-title { - font-size: 2.5rem; - } -} - -/* Floating Tech Particles */ -.tech-particles { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - overflow: hidden; - pointer-events: none; -} - -.particle { - position: absolute; - background: rgba(200, 168, 81, 0.3); - border-radius: 50%; - pointer-events: none; -} - -.particle:nth-child(1) { - width: 3px; - height: 3px; - top: 10%; - left: 20%; - animation: float1 15s infinite; -} - -.particle:nth-child(2) { - width: 2px; - height: 2px; - top: 70%; - left: 80%; - animation: float2 20s infinite; -} - -.particle:nth-child(3) { - width: 4px; - height: 4px; - top: 40%; - left: 60%; - animation: float3 18s infinite; -} - -@keyframes float1 { - 0%, 100% { transform: translate(0, 0); opacity: 0; } - 10% { opacity: 1; } - 90% { opacity: 1; } - 100% { transform: translate(100px, -100px); opacity: 0; } -} - -@keyframes float2 { - 0%, 100% { transform: translate(0, 0); opacity: 0; } - 10% { opacity: 1; } - 90% { opacity: 1; } - 100% { transform: translate(-100px, -150px); opacity: 0; } -} - -@keyframes float3 { - 0%, 100% { transform: translate(0, 0); opacity: 0; } - 10% { opacity: 1; } - 90% { opacity: 1; } - 100% { transform: translate(50px, -120px); opacity: 0; } -} \ No newline at end of file diff --git a/css/section-transitions.css b/css/section-transitions.css deleted file mode 100644 index d680490..0000000 --- a/css/section-transitions.css +++ /dev/null @@ -1,437 +0,0 @@ -/* Modern Section Transitions & Dividers */ - -/* Simple fade transition between sections */ -.section-fade { - position: relative; - opacity: 0; - transform: translateY(30px); - transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1); -} - -.section-fade.visible { - opacity: 1; - transform: translateY(0); -} - -/* Subtle gradient overlay at section edges */ -.section-gradient-top { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100px; - background: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); - pointer-events: none; - z-index: 1; -} - -.section-gradient-bottom { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 100px; - background: linear-gradient(to top, rgba(244,244,244,1) 0%, rgba(244,244,244,0) 100%); - pointer-events: none; - z-index: 1; -} - -/* Animated Gradient Divider */ -.gradient-divider { - position: relative; - height: 200px; - margin: -100px 0; - background: linear-gradient( - 135deg, - transparent 0%, - rgba(15, 114, 181, 0.03) 25%, - rgba(15, 114, 181, 0.08) 50%, - rgba(15, 114, 181, 0.03) 75%, - transparent 100% - ); - z-index: 5; - overflow: hidden; -} - -.gradient-divider::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 200%; - height: 100%; - background: linear-gradient( - 90deg, - transparent, - rgba(15, 114, 181, 0.2), - transparent - ); - animation: shimmerDivider 8s infinite; -} - -@keyframes shimmerDivider { - 0% { transform: translateX(-100%); } - 100% { transform: translateX(100%); } -} - -/* Diagonal Section Transitions */ -.diagonal-section { - position: relative; - padding: 120px 0 80px; - margin-top: -50px; - clip-path: polygon(0 50px, 100% 0, 100% 100%, 0 100%); -} - -.diagonal-section-reverse { - position: relative; - padding: 120px 0 80px; - margin-top: -50px; - clip-path: polygon(0 0, 100% 50px, 100% 100%, 0 100%); -} - -/* Blob Divider */ -.blob-divider { - position: absolute; - bottom: -150px; - left: 0; - width: 100%; - height: 300px; - z-index: 5; - pointer-events: none; -} - -.blob-shape { - position: absolute; - width: 100%; - height: 100%; - background: linear-gradient(135deg, var(--color-blue), var(--color-blue-hover)); - opacity: 0.1; - border-radius: 40% 60% 60% 40% / 60% 30% 70% 40%; - animation: morphBlob 20s ease-in-out infinite; -} - -@keyframes morphBlob { - 0%, 100% { - border-radius: 40% 60% 60% 40% / 60% 30% 70% 40%; - transform: translate(0, 0) scale(1); - } - 33% { - border-radius: 60% 40% 30% 70% / 60% 70% 30% 40%; - transform: translate(-30px, -20px) scale(1.1); - } - 66% { - border-radius: 30% 70% 70% 30% / 30% 60% 40% 70%; - transform: translate(30px, 20px) scale(0.9); - } -} - -/* Particle Bridge */ -.particle-bridge { - position: absolute; - width: 100%; - height: 200px; - bottom: -100px; - left: 0; - z-index: 8; - overflow: hidden; -} - -.particle { - position: absolute; - width: 4px; - height: 4px; - background: var(--color-blue); - border-radius: 50%; - opacity: 0.6; -} - -@keyframes floatParticle { - 0% { - transform: translateY(100px) translateX(0); - opacity: 0; - } - 10% { - opacity: 0.6; - } - 90% { - opacity: 0.6; - } - 100% { - transform: translateY(-100px) translateX(100px); - opacity: 0; - } -} - -/* Curved Section */ -.curved-section { - position: relative; - padding-top: 100px; - margin-top: -80px; -} - -.curved-section::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 80px; - background: inherit; - border-radius: 0 0 50% 50% / 0 0 100% 100%; - transform: scaleX(1.5); -} - -/* Glass Transition */ -.glass-transition { - position: relative; - margin: 50px 0; - padding: 40px 0; - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.1) 0%, - rgba(255, 255, 255, 0.05) 100% - ); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-top: 1px solid rgba(15, 114, 181, 0.1); - border-bottom: 1px solid rgba(15, 114, 181, 0.1); -} - -/* Zigzag Border */ -.zigzag-top { - position: relative; - padding-top: 40px; -} - -.zigzag-top::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 30px; - background: linear-gradient( - 135deg, - transparent 33.33%, - var(--color-blue) 33.33%, - var(--color-blue) 66.66%, - transparent 66.66% - ); - background-size: 30px 60px; - opacity: 0.1; -} - -/* Flowing Lines */ -.flow-lines { - position: absolute; - width: 100%; - height: 200px; - bottom: -100px; - left: 0; - overflow: hidden; - z-index: 5; -} - -.flow-line { - position: absolute; - height: 2px; - background: linear-gradient(90deg, transparent, var(--color-blue), transparent); - animation: flowLine 6s infinite; -} - -.flow-line:nth-child(1) { - top: 20%; - animation-delay: 0s; - width: 60%; -} - -.flow-line:nth-child(2) { - top: 40%; - animation-delay: 1s; - width: 80%; -} - -.flow-line:nth-child(3) { - top: 60%; - animation-delay: 2s; - width: 70%; -} - -.flow-line:nth-child(4) { - top: 80%; - animation-delay: 3s; - width: 90%; -} - -@keyframes flowLine { - 0% { - transform: translateX(-100%); - opacity: 0; - } - 50% { - opacity: 1; - } - 100% { - transform: translateX(200%); - opacity: 0; - } -} - -/* Reveal Sections with Mask */ -.section-reveal { - position: relative; - overflow: hidden; -} - -.section-reveal::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient( - 90deg, - transparent, - rgba(255, 255, 255, 0.4), - transparent - ); - animation: revealMask 2s ease-out forwards; -} - -@keyframes revealMask { - to { - left: 100%; - } -} - -/* Geometric Pattern Divider */ -.geometric-divider { - position: relative; - height: 100px; - margin: 40px 0; - background-image: - repeating-linear-gradient( - 45deg, - transparent, - transparent 10px, - rgba(15, 114, 181, 0.05) 10px, - rgba(15, 114, 181, 0.05) 20px - ), - repeating-linear-gradient( - -45deg, - transparent, - transparent 10px, - rgba(15, 114, 181, 0.05) 10px, - rgba(15, 114, 181, 0.05) 20px - ); -} - -/* Animated Border */ -.animated-border { - position: relative; - padding: var(--space-4xl) 0; -} - -.animated-border::before, -.animated-border::after { - content: ''; - position: absolute; - left: 0; - width: 100%; - height: 2px; - background: linear-gradient( - 90deg, - transparent, - var(--color-blue) 20%, - var(--color-blue) 80%, - transparent - ); -} - -.animated-border::before { - top: 0; - animation: borderSlide 4s infinite; -} - -.animated-border::after { - bottom: 0; - animation: borderSlide 4s infinite reverse; -} - -@keyframes borderSlide { - 0%, 100% { - transform: translateX(-100%); - } - 50% { - transform: translateX(100%); - } -} - -/* Section Fade Transitions */ -.fade-section { - opacity: 0; - transform: translateY(50px); - transition: all 1s cubic-bezier(0.4, 0, 0.2, 1); -} - -.fade-section.visible { - opacity: 1; - transform: translateY(0); -} - -/* Parallax Background Sections */ -.parallax-section { - position: relative; - min-height: 500px; - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; -} - -.parallax-bg { - position: absolute; - top: -20%; - left: 0; - width: 100%; - height: 120%; - background-image: linear-gradient(135deg, rgba(15, 114, 181, 0.05) 0%, transparent 100%); - background-attachment: fixed; - background-position: center; - background-repeat: no-repeat; - background-size: cover; - will-change: transform; -} - -/* Split Color Section */ -.split-section { - position: relative; - overflow: hidden; -} - -.split-section::before { - content: ''; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 45deg, - transparent 48%, - rgba(15, 114, 181, 0.05) 49%, - rgba(15, 114, 181, 0.05) 51%, - transparent 52% - ); - animation: rotateSplit 20s linear infinite; -} - -@keyframes rotateSplit { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/datenschutz.html b/datenschutz.html index 6601ba6..677619e 100644 --- a/datenschutz.html +++ b/datenschutz.html @@ -3,6 +3,9 @@ + + + Datenschutz – AegisSight diff --git a/en/index.html b/en/index.html index 5aa2633..150c251 100644 --- a/en/index.html +++ b/en/index.html @@ -3,6 +3,9 @@ + + + AegisSight Monitor – Real-time situation reports from open sources @@ -57,6 +60,66 @@ + + + @@ -129,7 +192,7 @@
-
@@ -138,7 +201,7 @@
-
@@ -153,7 +216,7 @@
-
@@ -168,7 +231,7 @@
-
diff --git a/en/legal-notice.html b/en/legal-notice.html index 775a4c7..e484a9e 100644 --- a/en/legal-notice.html +++ b/en/legal-notice.html @@ -3,6 +3,9 @@ + + + Legal notice – AegisSight diff --git a/en/privacy.html b/en/privacy.html index 5b8ab37..a2411c0 100644 --- a/en/privacy.html +++ b/en/privacy.html @@ -3,6 +3,9 @@ + + + Privacy policy – AegisSight diff --git a/en/situations/cyber-attacks/index.html b/en/situations/cyber-attacks/index.html index f900945..7262d23 100644 --- a/en/situations/cyber-attacks/index.html +++ b/en/situations/cyber-attacks/index.html @@ -3,6 +3,9 @@ + + + Situation report: Cyberattacks on German infrastructure - AegisSight @@ -73,6 +76,27 @@ + +
diff --git a/en/situations/deepfakes/index.html b/en/situations/deepfakes/index.html index 97f5c2e..2436338 100644 --- a/en/situations/deepfakes/index.html +++ b/en/situations/deepfakes/index.html @@ -3,6 +3,9 @@ + + + Research: Legal status of deepfakes in Germany - AegisSight @@ -73,6 +76,27 @@ + + diff --git a/en/situations/iran-conflict/index.html b/en/situations/iran-conflict/index.html index 9f23875..9281748 100644 --- a/en/situations/iran-conflict/index.html +++ b/en/situations/iran-conflict/index.html @@ -3,6 +3,9 @@ + + + Situation report: Iran conflict - AegisSight @@ -73,6 +76,27 @@ + + diff --git a/impressum.html b/impressum.html index 4759e31..d6fa9a6 100644 --- a/impressum.html +++ b/impressum.html @@ -3,6 +3,9 @@ + + + Impressum – AegisSight diff --git a/index.html b/index.html index fee50f7..4249991 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,9 @@ + + + AegisSight Monitor – Echtzeit-Lagebilder aus offenen Quellen @@ -57,6 +60,66 @@ + + + @@ -129,7 +192,7 @@
-
@@ -138,7 +201,7 @@
-
@@ -153,7 +216,7 @@
-
@@ -168,7 +231,7 @@
-
diff --git a/js/animations-enhanced.js b/js/animations-enhanced.js deleted file mode 100644 index 2650052..0000000 --- a/js/animations-enhanced.js +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Enhanced Animations and Interactions - * Premium effects for modern web experience - */ - -const EnhancedAnimations = { - init() { - this.initScrollAnimations(); - this.initParallaxEffects(); - this.initMagneticButtons(); - this.initTextAnimations(); - this.initCardTilt(); - this.initSmoothScroll(); - this.initCursorEffects(); - this.initRevealOnScroll(); - this.initNavbarEffects(); - }, - - // Smooth scroll with easing - initSmoothScroll() { - document.querySelectorAll('a[href^="#"]').forEach(anchor => { - anchor.addEventListener('click', function (e) { - e.preventDefault(); - const target = document.querySelector(this.getAttribute('href')); - if (target) { - const offset = 100; - const targetPosition = target.offsetTop - offset; - window.scrollTo({ - top: targetPosition, - behavior: 'smooth' - }); - } - }); - }); - }, - - // Parallax scrolling effects - initParallaxEffects() { - const parallaxElements = document.querySelectorAll('.parallax'); - let ticking = false; - - function updateParallax() { - const scrolled = window.pageYOffset; - - parallaxElements.forEach(element => { - const speed = element.dataset.speed || 0.5; - const yPos = -(scrolled * speed); - element.style.transform = `translateY(${yPos}px)`; - }); - - ticking = false; - } - - function requestTick() { - if (!ticking) { - window.requestAnimationFrame(updateParallax); - ticking = true; - } - } - - window.addEventListener('scroll', requestTick); - }, - - // Magnetic button effects - initMagneticButtons() { - const magneticButtons = document.querySelectorAll('.primary-button, .secondary-button, .cta-button'); - - magneticButtons.forEach(button => { - button.addEventListener('mousemove', (e) => { - const rect = button.getBoundingClientRect(); - const x = e.clientX - rect.left - rect.width / 2; - const y = e.clientY - rect.top - rect.height / 2; - - button.style.transform = `translate(${x * 0.2}px, ${y * 0.2}px) scale(1.05)`; - }); - - button.addEventListener('mouseleave', () => { - button.style.transform = ''; - }); - }); - }, - - // Advanced text animations - initTextAnimations() { - // Typewriter effect for hero title - DISABLED to prevent duplication - // The title already has CSS animations applied - - /* Commented out to fix duplication issue - const heroTitle = document.querySelector('.main-title'); - if (heroTitle && !heroTitle.dataset.animated) { - heroTitle.dataset.animated = 'true'; - const text = heroTitle.textContent; - heroTitle.textContent = ''; - heroTitle.style.opacity = '1'; - - let index = 0; - const typeWriter = () => { - if (index < text.length) { - heroTitle.textContent += text.charAt(index); - index++; - setTimeout(typeWriter, 50); - } - }; - - // Start typewriter after a short delay - setTimeout(typeWriter, 500); - } - */ - - // Word-by-word reveal for hero text - const heroText = document.querySelector('.hero-text'); - if (heroText) { - const words = heroText.textContent.split(' '); - heroText.innerHTML = words.map(word => - `${word}` - ).join(' '); - - const wordSpans = heroText.querySelectorAll('.word-reveal'); - wordSpans.forEach((word, index) => { - setTimeout(() => { - word.style.opacity = '1'; - word.style.transform = 'translateY(0)'; - }, 1000 + index * 100); - }); - } - }, - - // Card tilt removed - zu verspielt für Behördenkontext - initCardTilt() { - // Deaktiviert - CSS hover-Effekte reichen aus - }, - - // Custom cursor effects - DISABLED - initCursorEffects() { - // Cursor removed as requested - return; - }, - - - // Reveal elements on scroll - initRevealOnScroll() { - const revealElements = document.querySelectorAll('.about-panel, .tool-card, .value-card, .why-card, .competency-item'); - - revealElements.forEach((element, index) => { - element.style.opacity = '0'; - element.style.transform = 'translateY(50px)'; - element.style.transition = 'all 0.8s cubic-bezier(0.4, 0, 0.2, 1)'; - }); - - const revealOnScroll = () => { - const windowHeight = window.innerHeight; - - revealElements.forEach((element, index) => { - const elementTop = element.getBoundingClientRect().top; - const elementVisible = 100; - - if (elementTop < windowHeight - elementVisible) { - setTimeout(() => { - element.style.opacity = '1'; - element.style.transform = 'translateY(0)'; - }, index * 50); - } - }); - }; - - window.addEventListener('scroll', revealOnScroll); - revealOnScroll(); // Check on initial load - }, - - // Scroll-based animations - initScrollAnimations() { - let lastScrollY = window.scrollY; - let ticking = false; - - function updateScrollAnimations() { - const scrollY = window.scrollY; - const scrollDirection = scrollY > lastScrollY ? 'down' : 'up'; - - // Hero parallax - const hero = document.querySelector('.hero-content'); - if (hero) { - hero.style.transform = `translateY(${scrollY * 0.5}px)`; - hero.style.opacity = 1 - (scrollY / 800); - } - - // Video parallax - const heroVideos = document.querySelector('.hero-video-container'); - if (heroVideos) { - heroVideos.style.transform = `translateY(${scrollY * 0.3}px) scale(${1 + scrollY * 0.0003})`; - } - - lastScrollY = scrollY; - ticking = false; - } - - function requestTick() { - if (!ticking) { - window.requestAnimationFrame(updateScrollAnimations); - ticking = true; - } - } - - window.addEventListener('scroll', requestTick); - }, - - // Enhanced navbar effects - initNavbarEffects() { - const navbar = document.querySelector('.navbar'); - let lastScrollY = window.scrollY; - - window.addEventListener('scroll', () => { - const scrollY = window.scrollY; - - if (scrollY > 50) { - navbar.classList.add('scrolled'); - } else { - navbar.classList.remove('scrolled'); - } - - // Keep navbar always visible - navbar.style.transform = 'translateY(0)'; - - lastScrollY = scrollY; - }); - } -}; - -// Initialize when DOM is ready -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', () => EnhancedAnimations.init()); -} else { - EnhancedAnimations.init(); -} \ No newline at end of file diff --git a/js/animations.js b/js/animations.js deleted file mode 100644 index ee3ac80..0000000 --- a/js/animations.js +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Animation module for AegisSight website - * Contains all animation logic and visual effects - */ - -// Particle Animation System -const ParticleAnimation = { - canvas: null, - ctx: null, - particles: [], - - /** - * Initialize particle animation - */ - init() { - this.canvas = document.querySelector(SELECTORS.PARTICLE_CANVAS); - if (!this.canvas) return; - - this.ctx = this.canvas.getContext('2d'); - this.resizeCanvas(); - this.createParticles(); - this.animate(); - - // Handle window resize - window.addEventListener('resize', () => this.resizeCanvas()); - }, - - /** - * Resize canvas to window size - */ - resizeCanvas() { - this.canvas.width = window.innerWidth; - this.canvas.height = window.innerHeight; - }, - - /** - * Create particle objects - */ - createParticles() { - this.particles = []; - for (let i = 0; i < CONFIG.ANIMATION.PARTICLE_COUNT; i++) { - this.particles.push(new Particle(this.canvas)); - } - }, - - /** - * Main animation loop - */ - animate() { - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - - // Update and draw particles - this.particles.forEach(particle => { - particle.update(this.canvas); - particle.draw(this.ctx); - }); - - // Draw connections between particles - this.drawConnections(); - - requestAnimationFrame(() => this.animate()); - }, - - /** - * Draw connections between nearby particles - */ - drawConnections() { - for (let a = 0; a < this.particles.length; a++) { - for (let b = a + 1; b < this.particles.length; b++) { - const distance = Math.sqrt( - Math.pow(this.particles[a].x - this.particles[b].x, 2) + - Math.pow(this.particles[a].y - this.particles[b].y, 2) - ); - - if (distance < CONFIG.ANIMATION.CONNECTION_DISTANCE) { - const opacity = 0.15 * (1 - distance / CONFIG.ANIMATION.CONNECTION_DISTANCE); - // Use darker blue for better visibility on light background - this.ctx.strokeStyle = `rgba(15, 114, 181, ${opacity})`; - this.ctx.lineWidth = 1; - this.ctx.beginPath(); - this.ctx.moveTo(this.particles[a].x, this.particles[a].y); - this.ctx.lineTo(this.particles[b].x, this.particles[b].y); - this.ctx.stroke(); - } - } - } - } -}; - -/** - * Particle class for animation - */ -class Particle { - constructor(canvas) { - this.x = Math.random() * canvas.width; - this.y = Math.random() * canvas.height; - this.size = Math.random() * (CONFIG.ANIMATION.PARTICLE_SIZE_MAX - CONFIG.ANIMATION.PARTICLE_SIZE_MIN) + CONFIG.ANIMATION.PARTICLE_SIZE_MIN; - this.speedX = (Math.random() - 0.5) * CONFIG.ANIMATION.PARTICLE_SPEED; - this.speedY = (Math.random() - 0.5) * CONFIG.ANIMATION.PARTICLE_SPEED; - this.opacity = Math.random() * 0.5 + 0.2; - } - - update(canvas) { - this.x += this.speedX; - this.y += this.speedY; - - // Wrap around screen edges - if (this.x > canvas.width) this.x = 0; - else if (this.x < 0) this.x = canvas.width; - - if (this.y > canvas.height) this.y = 0; - else if (this.y < 0) this.y = canvas.height; - } - - draw(ctx) { - // Use darker blue for better visibility on light background - ctx.fillStyle = `rgba(15, 114, 181, ${this.opacity * 0.7})`; - ctx.beginPath(); - ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); - ctx.fill(); - } -} - -// Counter Animation -const CounterAnimation = { - /** - * Animate all counter elements - */ - animateAll() { - const counters = document.querySelectorAll(SELECTORS.INDICATOR_VALUE); - counters.forEach(counter => this.animateCounter(counter)); - }, - - /** - * Animate a single counter - * @param {HTMLElement} counter - Counter element to animate - */ - animateCounter(counter) { - const target = parseFloat(counter.getAttribute(DATA_ATTRS.TARGET)); - const increment = target / CONFIG.ANIMATION.COUNTER_SPEED; - let current = 0; - - const updateCounter = () => { - current += increment; - - if (current < target) { - counter.innerText = Math.ceil(current); - setTimeout(updateCounter, CONFIG.TIMING.COUNTER_UPDATE_INTERVAL); - } else { - // Set final value with proper formatting - if (target === CONFIG.TRUST_INDICATORS.AVAILABILITY) { - counter.innerText = target + '%'; - } else if (target === CONFIG.TRUST_INDICATORS.AUTHORITIES_COUNT) { - counter.innerText = target + '+'; - } else if (target === CONFIG.TRUST_INDICATORS.SUPPORT_HOURS) { - counter.innerText = target + '/7'; - } - } - }; - - updateCounter(); - } -}; - -// Scroll Animations -const ScrollAnimations = { - scrollIndicator: null, - - /** - * Initialize scroll-based animations - */ - init() { - this.scrollIndicator = document.querySelector(SELECTORS.SCROLL_INDICATOR); - this.setupScrollIndicator(); - this.setupIntersectionObserver(); - }, - - /** - * Setup scroll indicator behavior - */ - setupScrollIndicator() { - if (!this.scrollIndicator) return; - - // Click to scroll to about section - this.scrollIndicator.addEventListener('click', () => { - const aboutSection = document.querySelector('#about'); - if (aboutSection) { - aboutSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }); - - // Hide/show based on scroll position - let scrollTimeout; - window.addEventListener('scroll', () => { - const hero = document.querySelector(SELECTORS.HERO); - - if (window.scrollY > CONFIG.ANIMATION.SCROLL_THRESHOLD) { - if (hero) hero.classList.add(CLASSES.SCROLLED); - if (this.scrollIndicator) this.scrollIndicator.style.opacity = '0'; - } else { - if (hero) hero.classList.remove(CLASSES.SCROLLED); - if (this.scrollIndicator) this.scrollIndicator.style.opacity = '1'; - } - - clearTimeout(scrollTimeout); - scrollTimeout = setTimeout(() => { - if (window.scrollY > CONFIG.ANIMATION.SCROLL_THRESHOLD && this.scrollIndicator) { - this.scrollIndicator.style.display = 'none'; - } else if (this.scrollIndicator) { - this.scrollIndicator.style.display = 'flex'; - } - }, CONFIG.TIMING.SCROLL_HIDE_DELAY); - }); - }, - - /** - * Setup intersection observer for scroll-triggered animations - */ - setupIntersectionObserver() { - const observerOptions = { - threshold: CONFIG.OBSERVER.THRESHOLD, - rootMargin: CONFIG.OBSERVER.ROOT_MARGIN - }; - - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - // Trust indicators animation - if (entry.target.classList.contains('trust-indicators')) { - CounterAnimation.animateAll(); - observer.unobserve(entry.target); - } - - // Timeline animation - if (entry.target.classList.contains('timeline')) { - const items = entry.target.querySelectorAll('.timeline-item'); - items.forEach((item, index) => { - setTimeout(() => { - item.classList.add(CLASSES.VISIBLE); - }, index * 300); - }); - observer.unobserve(entry.target); - } - - // Feature nodes animation - if (entry.target.classList.contains('feature-nodes')) { - const nodes = entry.target.querySelectorAll('.node'); - nodes.forEach((node, index) => { - setTimeout(() => { - node.style.opacity = '1'; - node.style.transform = 'translateY(0)'; - }, index * 150); - }); - observer.unobserve(entry.target); - } - } - }); - }, observerOptions); - - // Observe elements - const trustIndicators = document.querySelector(SELECTORS.TRUST_INDICATORS); - if (trustIndicators) { - trustIndicators.style.opacity = '0'; - observer.observe(trustIndicators); - } - - const timeline = document.querySelector('.timeline'); - if (timeline) observer.observe(timeline); - - const featureNodes = document.querySelector('.feature-nodes'); - if (featureNodes) { - document.querySelectorAll('.node').forEach(node => { - node.style.opacity = '0'; - node.style.transform = 'translateY(30px)'; - node.style.transition = 'all 0.6s ease'; - }); - observer.observe(featureNodes); - } - } -}; - -// Glitch Effect -const GlitchEffect = { - /** - * Apply glitch effect to element on hover - * @param {HTMLElement} element - Element to apply effect to - */ - apply(element) { - if (!element) return; - - let glitchInterval; - element.addEventListener('mouseenter', () => { - let count = 0; - glitchInterval = setInterval(() => { - element.style.textShadow = ` - ${Math.random() * 5}px ${Math.random() * 5}px 0 rgba(0, 212, 255, 0.5), - ${Math.random() * -5}px ${Math.random() * 5}px 0 rgba(255, 0, 128, 0.5) - `; - count++; - if (count > CONFIG.ANIMATION.GLITCH_ITERATIONS) { - clearInterval(glitchInterval); - element.style.textShadow = 'none'; - } - }, CONFIG.ANIMATION.GLITCH_INTERVAL); - }); - } -}; - -// Interactive Elements -const InteractiveElements = { - /** - * Initialize all interactive element animations - */ - init() { - this.setupNodeHoverEffects(); - this.setupWidgetHoverEffects(); - this.setupInteractiveIcon(); - }, - - /** - * Setup hover effects for node elements - */ - setupNodeHoverEffects() { - document.querySelectorAll('.node').forEach(node => { - node.addEventListener('mouseenter', function() { - const icon = this.querySelector('.node-icon'); - if (icon) icon.style.transform = 'scale(1.2) rotate(5deg)'; - }); - - node.addEventListener('mouseleave', function() { - const icon = this.querySelector('.node-icon'); - if (icon) icon.style.transform = 'scale(1) rotate(0deg)'; - }); - }); - }, - - /** - * Setup hover effects for widget elements - */ - setupWidgetHoverEffects() { - document.querySelectorAll('.widget').forEach(widget => { - widget.addEventListener('mouseenter', function() { - this.style.boxShadow = '0 5px 20px rgba(0, 212, 255, 0.3)'; - }); - - widget.addEventListener('mouseleave', function() { - this.style.boxShadow = 'none'; - }); - }); - }, - - /** - * Setup 3D interactive icon effect - */ - setupInteractiveIcon() { - const icon = document.querySelector(SELECTORS.INTERACTIVE_ICON); - if (!icon) return; - - document.addEventListener('mousemove', (e) => { - const rect = icon.getBoundingClientRect(); - const centerX = rect.left + rect.width / 2; - const centerY = rect.top + rect.height / 2; - - const mouseX = (e.clientX - centerX) / 20; - const mouseY = (e.clientY - centerY) / 20; - - icon.style.transform = `perspective(1000px) rotateY(${mouseX}deg) rotateX(${-mouseY}deg)`; - }); - } -}; - -// Initialize all animations -const Animations = { - /** - * Initialize all animation systems - */ - init() { - // Core animations - ParticleAnimation.init(); - ScrollAnimations.init(); - InteractiveElements.init(); - - // Apply glitch effect to main title - const mainTitle = document.querySelector('.main-title'); - if (mainTitle) { - GlitchEffect.apply(mainTitle); - } - - // Page load animations - window.addEventListener('load', () => { - document.body.classList.add(CLASSES.LOADED); - - // Fade in hero content - setTimeout(() => { - const heroContent = document.querySelector(SELECTORS.HERO_CONTENT); - if (heroContent) { - heroContent.style.opacity = '1'; - heroContent.style.transform = 'translateY(0)'; - } - }, 100); - }); - } -}; \ No newline at end of file diff --git a/js/components.js b/js/components.js deleted file mode 100644 index 3c9be96..0000000 --- a/js/components.js +++ /dev/null @@ -1,515 +0,0 @@ -/** - * UI Components module for AegisSight website - * Contains all interactive UI component logic - */ - -// Language Toggle Component -const LanguageToggle = { - element: null, - - /** - * Initialize language toggle - */ - init() { - this.element = document.querySelector(SELECTORS.LANG_TOGGLE); - if (!this.element) return; - - this.element.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - this.toggle(); - }); - }, - - /** - * Toggle between languages - */ - toggle() { - const newLanguage = getCurrentLanguage() === 'de' ? 'en' : 'de'; - switchLanguage(newLanguage); - - // Update expand button text after language change - ProductShowcase.updateExpandButtonText(); - } -}; - -// Navigation Component -const Navigation = { - navbar: null, - - /** - * Initialize navigation component - */ - init() { - this.navbar = document.querySelector(SELECTORS.NAVBAR); - this.setupSmoothScrolling(); - this.setupMobileMenu(); - }, - - /** - * Setup smooth scrolling for anchor links - */ - setupSmoothScrolling() { - document.querySelectorAll(SELECTORS.SMOOTH_LINKS).forEach(anchor => { - anchor.addEventListener('click', function(e) { - e.preventDefault(); - const targetId = this.getAttribute('href'); - const target = document.querySelector(targetId); - - if (target) { - target.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - } - }); - }); - }, - - /** - * Setup mobile menu functionality - */ - setupMobileMenu() { - // Mobile menu logic would go here if needed - // Currently not implemented as per YAGNI principle - } -}; - -// About Section Tabs -const AboutTabs = { - tabs: null, - panels: null, - - /** - * Initialize about section tabs - */ - init() { - this.tabs = document.querySelectorAll(SELECTORS.ABOUT_TABS); - this.panels = document.querySelectorAll(SELECTORS.ABOUT_PANELS); - - if (!this.tabs.length) return; - - this.tabs.forEach(tab => { - tab.addEventListener('click', () => this.switchTab(tab)); - }); - }, - - /** - * Switch to selected tab - * @param {HTMLElement} selectedTab - Tab element that was clicked - */ - switchTab(selectedTab) { - const targetPanelId = selectedTab.getAttribute(DATA_ATTRS.TAB); - - // Remove active class from all tabs and panels - this.tabs.forEach(tab => tab.classList.remove(CLASSES.ACTIVE)); - this.panels.forEach(panel => panel.classList.remove(CLASSES.ACTIVE)); - - // Add active class to selected tab and corresponding panel - selectedTab.classList.add(CLASSES.ACTIVE); - const targetPanel = document.getElementById(targetPanelId); - if (targetPanel) { - targetPanel.classList.add(CLASSES.ACTIVE); - } - } -}; - -// Product Showcase Component -const ProductShowcase = { - expandButton: null, - toolsGrid: null, - - /** - * Initialize product showcase - */ - init() { - this.expandButton = document.querySelector(SELECTORS.EXPAND_BUTTON); - this.toolsGrid = document.querySelector(SELECTORS.TOOLS_GRID); - - if (!this.expandButton || !this.toolsGrid) return; - - this.expandButton.addEventListener('click', () => this.toggleExpand()); - }, - - /** - * Toggle expand/collapse state - */ - toggleExpand() { - const isExpanded = this.expandButton.getAttribute(DATA_ATTRS.EXPANDED) === 'true'; - - if (isExpanded) { - this.collapse(); - } else { - this.expand(); - } - }, - - /** - * Expand the tools grid - */ - expand() { - this.toolsGrid.classList.remove(CLASSES.COLLAPSED); - this.expandButton.setAttribute(DATA_ATTRS.EXPANDED, 'true'); - this.updateExpandButtonText(); - }, - - /** - * Collapse the tools grid - */ - collapse() { - this.toolsGrid.classList.add(CLASSES.COLLAPSED); - this.expandButton.setAttribute(DATA_ATTRS.EXPANDED, 'false'); - this.updateExpandButtonText(); - }, - - /** - * Update expand button text based on state - */ - updateExpandButtonText() { - const expandText = this.expandButton?.querySelector('.expand-text'); - if (!expandText) return; - - const isExpanded = this.expandButton.getAttribute(DATA_ATTRS.EXPANDED) === 'true'; - expandText.textContent = getTranslation(isExpanded ? 'hideDetails' : 'expandDetails'); - } -}; - -// Login Modal Component -const LoginModal = { - modalElement: null, - modalStyles: null, - - /** - * Show login modal - */ - show() { - this.createModal(); - this.attachEventListeners(); - }, - - /** - * Create modal HTML and styles - */ - createModal() { - // Create modal element - this.modalElement = document.createElement('div'); - this.modalElement.className = 'login-modal'; - this.modalElement.innerHTML = this.getModalHTML(); - document.body.appendChild(this.modalElement); - - // Add modal styles if not already added - if (!this.modalStyles) { - this.addModalStyles(); - } - }, - - /** - * Get modal HTML content - * @returns {string} Modal HTML - */ - getModalHTML() { - const t = getTranslation; - return ` - - `; - }, - - /** - * Add modal styles to document - */ - addModalStyles() { - this.modalStyles = document.createElement('style'); - this.modalStyles.textContent = ` - .login-modal { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(10, 24, 50, 0.85); - backdrop-filter: blur(12px); - display: flex; - align-items: center; - justify-content: center; - z-index: 10000; - animation: fadeIn 0.3s ease; - } - .modal-content { - background: #0A1832; - border-radius: 12px; - padding: 2.5rem; - max-width: 400px; - width: 90%; - position: relative; - border: 1px solid rgba(200, 168, 81, 0.3); - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); - } - .modal-header { - text-align: center; - margin-bottom: 1.5rem; - } - .modal-header .lock-icon { - width: 48px; - height: 48px; - color: #C8A851; - margin-bottom: 1rem; - } - .modal-close { - position: absolute; - top: 1rem; - right: 1rem; - background: none; - border: none; - color: rgba(255, 255, 255, 0.4); - font-size: 2rem; - cursor: pointer; - transition: all 0.3s ease; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - } - .modal-close:hover { - background: rgba(255, 255, 255, 0.1); - color: #fff; - } - .modal-content h3 { - color: #FFFFFF; - margin-bottom: 0.5rem; - font-size: 1.5rem; - font-weight: 600; - } - .modal-content p { - color: rgba(255, 255, 255, 0.6); - margin-bottom: 2rem; - text-align: center; - } - .modal-content .form-group { - margin-bottom: 1.5rem; - } - .modal-content label { - display: block; - color: rgba(255, 255, 255, 0.8); - margin-bottom: 0.5rem; - font-weight: 500; - } - .modal-content input { - width: 100%; - padding: 0.875rem; - background: rgba(255, 255, 255, 0.05); - border: 2px solid rgba(255, 255, 255, 0.15); - border-radius: 8px; - color: #FFFFFF; - font-size: 1rem; - transition: all 0.3s ease; - } - .modal-content input:focus { - outline: none; - border-color: #C8A851; - background: rgba(255, 255, 255, 0.08); - } - .modal-content input::placeholder { - color: rgba(255, 255, 255, 0.3); - } - .modal-content .primary-button { - width: 100%; - padding: 0.875rem; - background: #C8A851; - color: #0A1832; - border: none; - border-radius: 8px; - font-size: 1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - } - .modal-content .primary-button:hover { - background: #D4B96A; - transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(200, 168, 81, 0.4); - } - .auth-note { - text-align: center; - margin-top: 1.5rem; - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.4); - } - .auth-note a { - color: #C8A851; - text-decoration: none; - } - .auth-note a:hover { - text-decoration: underline; - } - `; - document.head.appendChild(this.modalStyles); - }, - - /** - * Attach event listeners to modal - */ - attachEventListeners() { - // Close button - const closeBtn = this.modalElement.querySelector('.modal-close'); - closeBtn.addEventListener('click', () => this.close()); - - // Form submission - const form = this.modalElement.querySelector('#loginForm'); - form.addEventListener('submit', (e) => this.handleSubmit(e)); - - // Click outside to close - this.modalElement.addEventListener('click', (e) => { - if (e.target === this.modalElement) { - this.close(); - } - }); - }, - - /** - * Handle form submission - * @param {Event} e - Submit event - */ - async handleSubmit(e) { - e.preventDefault(); - const password = document.getElementById('auth-password').value; - - try { - // Validate token via Insights API - const response = await fetch('/insights/api/validate-token', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ token: password }) - }); - - const result = await response.json(); - - if (result.valid) { - sessionStorage.setItem(CONFIG.AUTH.SESSION_KEY, 'true'); - this.close(); - window.location.href = CONFIG.AUTH.REDIRECT_PAGE; - } else { - alert(getTranslation('wrongCode')); - document.getElementById('auth-password').value = ''; - document.getElementById('auth-password').focus(); - } - } catch (error) { - console.error('Token validation error:', error); - alert(getTranslation('wrongCode')); - } - }, - - /** - * Close and remove modal - */ - close() { - if (this.modalElement) { - this.modalElement.remove(); - this.modalElement = null; - } - } -}; - -// Contact Form Component -const ContactForm = { - form: null, - - /** - * Initialize contact form - */ - init() { - this.form = document.querySelector(SELECTORS.CONTACT_FORM); - if (!this.form) return; - - this.form.addEventListener('submit', (e) => this.handleSubmit(e)); - }, - - /** - * Handle form submission - * @param {Event} e - Submit event - */ - handleSubmit(e) { - e.preventDefault(); - - // Get form data - const formData = new FormData(this.form); - const data = Object.fromEntries(formData.entries()); - - // In production, this would send data to server - console.log('Form submission:', data); - - // Show success message - alert(getTranslation('contactFormSuccess')); - this.form.reset(); - } -}; - -// Demo Request Handler -const DemoRequest = { - /** - * Initialize demo request buttons - */ - init() { - document.querySelectorAll('.primary-button, .secondary-button, .cta-button').forEach(button => { - if (button.textContent.toLowerCase().includes('demo')) { - button.addEventListener('click', (e) => this.handleDemoRequest(e)); - } - }); - }, - - /** - * Handle demo request - * @param {Event} e - Click event - */ - handleDemoRequest(e) { - e.preventDefault(); - alert(getTranslation('demoRequestAlert')); - } -}; - -// Initialize all components -const Components = { - /** - * Initialize all UI components - */ - init() { - LanguageToggle.init(); - Navigation.init(); - AboutTabs.init(); - ProductShowcase.init(); - ContactForm.init(); - DemoRequest.init(); - } -}; - -// Make showLoginModal globally available for onclick attribute -window.showLoginModal = function() { - LoginModal.show(); -}; - -// Make closeLoginModal globally available for onclick attribute -window.closeLoginModal = function() { - LoginModal.close(); -}; \ No newline at end of file diff --git a/js/hero-videos.js b/js/hero-videos.js deleted file mode 100644 index 336d850..0000000 --- a/js/hero-videos.js +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Hero Video Rotation System - * Manages rotating background videos in hero section - */ - -const HeroVideoRotation = { - videos: [], - currentIndex: 0, - rotationInterval: null, - isTransitioning: false, - - /** - * Initialize the video rotation system - */ - init() { - // Get all video elements - this.videos = document.querySelectorAll('.hero-video'); - - if (!this.videos.length) return; - - // Setup event listeners - this.setupEventListeners(); - - // Start rotation - this.startRotation(); - - // Ensure first video is playing - this.playVideo(0); - }, - - /** - * Setup event listeners for videos - */ - setupEventListeners() { - // Indicators removed - no click handlers needed - - // Pause rotation on hover (optional) - const heroSection = document.querySelector('.hero'); - if (heroSection) { - heroSection.addEventListener('mouseenter', () => { - // Optional: pause rotation on hover - // this.stopRotation(); - }); - - heroSection.addEventListener('mouseleave', () => { - // Optional: resume rotation - // this.startRotation(); - }); - } - - // Handle video load errors gracefully - this.videos.forEach((video, index) => { - video.addEventListener('error', () => { - console.warn(`Video ${index} failed to load, skipping...`); - // If current video fails, move to next - if (index === this.currentIndex) { - this.nextVideo(); - } - }); - - // Ensure videos are ready to play - video.addEventListener('loadeddata', () => { - console.log(`Video ${index} loaded successfully`); - }); - }); - }, - - /** - * Start automatic rotation - */ - startRotation() { - // Clear any existing interval - this.stopRotation(); - - // Set new interval - this.rotationInterval = setInterval(() => { - this.nextVideo(); - }, CONFIG.HERO_VIDEOS.ROTATION_INTERVAL); - }, - - /** - * Stop automatic rotation - */ - stopRotation() { - if (this.rotationInterval) { - clearInterval(this.rotationInterval); - this.rotationInterval = null; - } - }, - - /** - * Switch to next video - */ - nextVideo() { - const nextIndex = (this.currentIndex + 1) % this.videos.length; - this.switchToVideo(nextIndex); - }, - - /** - * Switch to previous video - */ - previousVideo() { - const prevIndex = (this.currentIndex - 1 + this.videos.length) % this.videos.length; - this.switchToVideo(prevIndex); - }, - - /** - * Switch to specific video by index - * @param {number} index - Video index to switch to - */ - switchToVideo(index) { - if (this.isTransitioning || index === this.currentIndex) return; - - this.isTransitioning = true; - - const currentVideo = this.videos[this.currentIndex]; - const nextVideo = this.videos[index]; - - // Indicators removed - no update needed - - // Prepare next video - this.prepareVideo(nextVideo); - - // Fade out current video - currentVideo.classList.add('fading-out'); - - // After half the fade duration, start fading in the next video - setTimeout(() => { - nextVideo.classList.add('active'); - nextVideo.classList.remove('fading-out'); - - // Play next video - this.playVideo(index); - }, CONFIG.HERO_VIDEOS.FADE_DURATION / 2); - - // Complete transition - setTimeout(() => { - currentVideo.classList.remove('active', 'fading-out'); - this.currentIndex = index; - this.isTransitioning = false; - }, CONFIG.HERO_VIDEOS.FADE_DURATION); - }, - - - /** - * Prepare video for playback - * @param {HTMLVideoElement} video - Video element to prepare - */ - prepareVideo(video) { - // Reset video to beginning - video.currentTime = 0; - - // Ensure video is ready to play - const playPromise = video.play(); - if (playPromise !== undefined) { - playPromise.catch(error => { - console.warn('Video autoplay was prevented:', error); - }); - } - }, - - /** - * Play specific video - * @param {number} index - Index of video to play - */ - playVideo(index) { - const video = this.videos[index]; - if (video) { - const playPromise = video.play(); - if (playPromise !== undefined) { - playPromise.catch(error => { - console.warn(`Could not play video ${index}:`, error); - }); - } - } - }, - - /** - * Pause all videos - */ - pauseAllVideos() { - this.videos.forEach(video => { - video.pause(); - }); - }, - - /** - * Handle page visibility change (pause when tab is not visible) - */ - handleVisibilityChange() { - if (document.hidden) { - this.stopRotation(); - this.pauseAllVideos(); - } else { - this.playVideo(this.currentIndex); - this.startRotation(); - } - } -}; - -// Initialize when DOM is ready -document.addEventListener('DOMContentLoaded', () => { - HeroVideoRotation.init(); -}); - -// Handle page visibility API -document.addEventListener('visibilitychange', () => { - HeroVideoRotation.handleVisibilityChange(); -}); \ No newline at end of file diff --git a/js/legal-pages.js b/js/legal-pages.js deleted file mode 100644 index 76650f3..0000000 --- a/js/legal-pages.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Minimal JavaScript for legal pages (Impressum & Datenschutz) - * Only includes necessary functionality for language switching - */ - -// Set current year in footer -function setCurrentYear() { - const currentYear = new Date().getFullYear(); - const yearElements = document.querySelectorAll('.current-year'); - yearElements.forEach(element => { - element.textContent = currentYear; - }); -} - -// Simple language toggle for legal pages -document.addEventListener('DOMContentLoaded', function() { - // Set current year immediately - setCurrentYear(); - - // Get the language toggle button - const langToggle = document.querySelector('.lang-toggle'); - - if (langToggle) { - langToggle.addEventListener('click', function(e) { - e.preventDefault(); - - // Get current language from button - const currentLang = this.getAttribute('data-lang') || 'de'; - const newLang = currentLang === 'de' ? 'en' : 'de'; - - // Store language preference - if (typeof(Storage) !== 'undefined') { - localStorage.setItem('aegissight_language', newLang); - } - - // Get current page name - const currentPage = window.location.pathname.split('/').pop(); - - // Determine redirect URL - let redirectUrl = ''; - - if (currentPage === 'impressum.html' || currentPage === 'impressum-en.html') { - redirectUrl = newLang === 'en' ? 'impressum-en.html' : 'impressum.html'; - } else if (currentPage === 'datenschutz.html' || currentPage === 'datenschutz-en.html') { - redirectUrl = newLang === 'en' ? 'datenschutz-en.html' : 'datenschutz.html'; - } - - // Redirect to the appropriate version - if (redirectUrl) { - window.location.href = redirectUrl; - } - }); - } -}); \ No newline at end of file diff --git a/js/main.js b/js/main.js deleted file mode 100644 index ea96e7b..0000000 --- a/js/main.js +++ /dev/null @@ -1,305 +0,0 @@ -/** - * Main application entry point for AegisSight website - * Initializes all modules and coordinates application startup - */ - -/** - * Toggle tools grid visibility - */ -function toggleTools(button) { - // Find the tools grid within the same product card - const productCard = button.closest('.product-card'); - const toolsGrid = productCard.querySelector('.tools-grid'); - - if (toolsGrid) { - const isExpanded = toolsGrid.classList.contains('expanded'); - const currentLang = getCurrentLanguage ? getCurrentLanguage() : 'de'; - - if (isExpanded) { - toolsGrid.classList.remove('expanded'); - toolsGrid.classList.add('collapsed'); - button.setAttribute('data-expanded', 'false'); - button.querySelector('span').textContent = currentLang === 'de' ? 'Details anzeigen' : 'Show Details'; - } else { - // Force browser reflow before adding expanded class - toolsGrid.style.display = 'grid'; - void toolsGrid.offsetHeight; // Trigger reflow - - toolsGrid.classList.remove('collapsed'); - toolsGrid.classList.add('expanded'); - button.setAttribute('data-expanded', 'true'); - button.querySelector('span').textContent = currentLang === 'de' ? 'Details verbergen' : 'Hide Details'; - - // Ensure all tool cards are visible - setTimeout(() => { - const toolCards = toolsGrid.querySelectorAll('.tool-card'); - toolCards.forEach((card, index) => { - card.style.opacity = '1'; - card.style.transform = 'translateY(0)'; - }); - }, 100); - } - } -} - -/** - * Application initialization - */ -const App = { - /** - * Initialize the entire application - */ - init() { - // Check DOM ready state - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', () => this.start()); - } else { - // DOM is already ready - this.start(); - } - }, - - /** - * Start the application after DOM is ready - */ - start() { - console.log('AegisSight Website Initializing...'); - - // Initialize modules in correct order - try { - // 1. Initialize translations first (includes year replacement) - initTranslations(); - console.log('✓ Translations initialized'); - - // 2. Initialize UI components - Components.init(); - console.log('✓ Components initialized'); - - // 3. Initialize animations - Animations.init(); - console.log('✓ Animations initialized'); - - // 4. Setup error handling - this.setupErrorHandling(); - - // 5. Setup performance monitoring - this.setupPerformanceMonitoring(); - - console.log('AegisSight Website Ready!'); - - } catch (error) { - console.error('Failed to initialize application:', error); - this.handleInitError(error); - } - }, - - /** - * Setup global error handling - */ - setupErrorHandling() { - window.addEventListener('error', (event) => { - console.error('Global error:', event.error); - // In production, this would send errors to monitoring service - }); - - window.addEventListener('unhandledrejection', (event) => { - console.error('Unhandled promise rejection:', event.reason); - // In production, this would send errors to monitoring service - }); - }, - - /** - * Setup performance monitoring - */ - setupPerformanceMonitoring() { - // Monitor page load performance - window.addEventListener('load', () => { - if (window.performance && window.performance.timing) { - const timing = window.performance.timing; - const loadTime = timing.loadEventEnd - timing.navigationStart; - console.log(`Page load time: ${loadTime}ms`); - - // Log other performance metrics - const metrics = { - domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart, - domComplete: timing.domComplete - timing.navigationStart, - firstPaint: this.getFirstPaintTime() - }; - - console.log('Performance metrics:', metrics); - } - }); - }, - - /** - * Set current year in footer and update translations dynamically - */ - setCurrentYear() { - const currentYear = new Date().getFullYear(); - - // Set current year in main footer span element - const yearElement = document.getElementById('currentYear'); - if (yearElement) { - yearElement.textContent = currentYear; - } - - // Set current year in legal pages footer spans - const legalYearElements = document.querySelectorAll('.current-year'); - legalYearElements.forEach(element => { - element.textContent = currentYear; - }); - - // Update copyright translation with current year - if (window.translations) { - Object.keys(window.translations).forEach(lang => { - if (window.translations[lang].copyright) { - window.translations[lang].copyright = window.translations[lang].copyright.replace('{year}', currentYear); - } - }); - } - }, - - /** - * Get first paint time if available - * @returns {number|null} First paint time in milliseconds - */ - getFirstPaintTime() { - if (window.performance && window.performance.getEntriesByType) { - const paintEntries = window.performance.getEntriesByType('paint'); - const firstPaint = paintEntries.find(entry => entry.name === 'first-paint'); - return firstPaint ? Math.round(firstPaint.startTime) : null; - } - return null; - }, - - /** - * Handle initialization errors - * @param {Error} error - The error that occurred - */ - handleInitError(error) { - // Create a fallback error message for users - const errorContainer = document.createElement('div'); - errorContainer.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - background: #ff4444; - color: white; - padding: 15px 20px; - border-radius: 5px; - z-index: 10000; - max-width: 300px; - box-shadow: 0 2px 10px rgba(0,0,0,0.2); - `; - errorContainer.textContent = 'Ein Fehler ist aufgetreten. Bitte laden Sie die Seite neu.'; - document.body.appendChild(errorContainer); - - // Auto-remove after 5 seconds - setTimeout(() => { - errorContainer.remove(); - }, 5000); - } -}; - -/** - * Utility functions - */ -const Utils = { - /** - * Debounce function to limit function calls - * @param {Function} func - Function to debounce - * @param {number} wait - Wait time in milliseconds - * @returns {Function} Debounced function - */ - debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }, - - /** - * Throttle function to limit function calls - * @param {Function} func - Function to throttle - * @param {number} limit - Time limit in milliseconds - * @returns {Function} Throttled function - */ - throttle(func, limit) { - let inThrottle; - return function(...args) { - if (!inThrottle) { - func.apply(this, args); - inThrottle = true; - setTimeout(() => inThrottle = false, limit); - } - }; - }, - - /** - * Check if element is in viewport - * @param {HTMLElement} element - Element to check - * @returns {boolean} True if element is in viewport - */ - isInViewport(element) { - const rect = element.getBoundingClientRect(); - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - ); - }, - - /** - * Load script dynamically - * @param {string} src - Script source URL - * @returns {Promise} Promise that resolves when script is loaded - */ - loadScript(src) { - return new Promise((resolve, reject) => { - const script = document.createElement('script'); - script.src = src; - script.onload = resolve; - script.onerror = reject; - document.head.appendChild(script); - }); - }, - - /** - * Get cookie value by name - * @param {string} name - Cookie name - * @returns {string|null} Cookie value or null - */ - getCookie(name) { - const value = `; ${document.cookie}`; - const parts = value.split(`; ${name}=`); - if (parts.length === 2) { - return parts.pop().split(';').shift(); - } - return null; - }, - - /** - * Set cookie - * @param {string} name - Cookie name - * @param {string} value - Cookie value - * @param {number} days - Days until expiration - */ - setCookie(name, value, days) { - const date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - const expires = `expires=${date.toUTCString()}`; - document.cookie = `${name}=${value};${expires};path=/`; - } -}; - -// Make Utils globally available if needed -window.Utils = Utils; - -// Start the application -App.init(); \ No newline at end of file diff --git a/js/section-transitions.js b/js/section-transitions.js deleted file mode 100644 index e0ac19d..0000000 --- a/js/section-transitions.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Section Transitions & Effects - * Modern animations for section dividers - */ - -const SectionTransitions = { - init() { - this.initParticleBridge(); - this.initScrollReveal(); - this.initWaveAnimation(); - this.initParallaxDividers(); - }, - - // Animated particles between sections - initParticleBridge() { - const bridge = document.getElementById('particleBridge'); - if (!bridge) return; - - // Create floating particles - for (let i = 0; i < 30; i++) { - const particle = document.createElement('div'); - particle.className = 'particle'; - particle.style.left = Math.random() * 100 + '%'; - particle.style.animationDelay = Math.random() * 5 + 's'; - particle.style.animationDuration = (5 + Math.random() * 5) + 's'; - particle.style.animation = `floatParticle ${5 + Math.random() * 5}s linear infinite`; - bridge.appendChild(particle); - } - }, - - // Reveal sections on scroll - initScrollReveal() { - const sections = document.querySelectorAll('.fade-section'); - - const revealSection = (entries, observer) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('visible'); - - // Add shimmer effect on reveal - const shimmer = document.createElement('div'); - shimmer.style.cssText = ` - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(15, 114, 181, 0.2), transparent); - animation: shimmerPass 1s ease-out forwards; - pointer-events: none; - z-index: 100; - `; - entry.target.style.position = 'relative'; - entry.target.appendChild(shimmer); - - setTimeout(() => shimmer.remove(), 1000); - } - }); - }; - - const observer = new IntersectionObserver(revealSection, { - threshold: 0.1, - rootMargin: '0px 0px -100px 0px' - }); - - sections.forEach(section => observer.observe(section)); - }, - - // Animate wave dividers - initWaveAnimation() { - const waves = document.querySelectorAll('.wave-divider path'); - - waves.forEach(wave => { - let time = 0; - const animateWave = () => { - time += 0.02; - const points = []; - - for (let i = 0; i <= 10; i++) { - const x = (i / 10) * 1200; - const y = Math.sin((i / 10) * Math.PI * 2 + time) * 10 + 56; - points.push(`${x},${y}`); - } - - // Create smooth wave path - const d = `M0,56 Q${points[2]} T${points[4]} T${points[6]} T${points[8]} T1200,56 L1200,0 L0,0 Z`; - wave.setAttribute('d', d); - - requestAnimationFrame(animateWave); - }; - - // Start wave animation - // animateWave(); // Commented out for performance, uncomment for wave motion - }); - }, - - // Parallax effect for dividers - initParallaxDividers() { - const dividers = document.querySelectorAll('.blob-divider, .gradient-divider, .flow-lines'); - - window.addEventListener('scroll', () => { - const scrolled = window.pageYOffset; - - dividers.forEach(divider => { - const speed = divider.dataset.speed || 0.5; - const yPos = -(scrolled * speed); - divider.style.transform = `translateY(${yPos}px)`; - }); - }); - } -}; - -// Add shimmer animation -const style = document.createElement('style'); -style.textContent = ` - @keyframes shimmerPass { - to { - left: 100%; - opacity: 0; - } - } -`; -document.head.appendChild(style); - -// Initialize when DOM is ready -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', () => SectionTransitions.init()); -} else { - SectionTransitions.init(); -} \ No newline at end of file diff --git a/lagen/cyberangriffe/index.html b/lagen/cyberangriffe/index.html index d37daa9..726135e 100644 --- a/lagen/cyberangriffe/index.html +++ b/lagen/cyberangriffe/index.html @@ -3,6 +3,9 @@ + + + Lagebild: Cyberangriffe auf deutsche Infrastruktur - AegisSight @@ -72,6 +75,27 @@ + +
diff --git a/lagen/deepfakes/index.html b/lagen/deepfakes/index.html index a92f2a0..1511be5 100644 --- a/lagen/deepfakes/index.html +++ b/lagen/deepfakes/index.html @@ -3,6 +3,9 @@ + + + Recherche: Rechtliche Lage von Deepfakes in Deutschland - AegisSight @@ -72,6 +75,27 @@ + + diff --git a/lagen/iran-konflikt/index.html b/lagen/iran-konflikt/index.html index 2562307..facb009 100644 --- a/lagen/iran-konflikt/index.html +++ b/lagen/iran-konflikt/index.html @@ -3,7 +3,10 @@ - Lagebild Irankonflikt - AegisSight + + + + Lagebild Iran-Konflikt - AegisSight @@ -72,6 +75,27 @@ + + diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000..4540293 --- /dev/null +++ b/llms.txt @@ -0,0 +1,43 @@ +# AegisSight - OSINT-Monitoring aus Deutschland + +> AegisSight Monitor liefert KI-gestuetzte Echtzeit-Lagebilder aus offenen +> Quellen. Hunderte Quellen werden kontinuierlich ueberwacht, jede zentrale +> Behauptung wird automatisch gegen unabhaengige Quellen geprueft. Die +> Lagen-Daten der Live-Lagebilder werden alle 5 Minuten aktualisiert. + +Anbieter: AegisSight UG (haftungsbeschraenkt), Langenfeld, Deutschland. +Kontakt: info@aegis-sight.de + +## Hauptseiten + +- [Startseite (DE)](https://aegis-sight.de/): Produktuebersicht, Hero-Video-Slider, Live-Demos der Lagebilder +- [Startseite (EN)](https://aegis-sight.de/en/): Same content, English version +- [Impressum (DE)](https://aegis-sight.de/impressum.html) +- [Legal notice (EN)](https://aegis-sight.de/en/legal-notice.html) +- [Datenschutz (DE)](https://aegis-sight.de/datenschutz.html) +- [Privacy policy (EN)](https://aegis-sight.de/en/privacy.html) + +## Live-Lagebilder + +- [Iran-Konflikt (DE)](https://aegis-sight.de/lagen/iran-konflikt/): Live-Lagebild mit Faktencheck-Liste, Quellenliste, geografischer Verortung und Timeline. Daten ueber hunderte Quellen, Updates alle 5 Minuten. +- [Iran Conflict (EN)](https://aegis-sight.de/en/situations/iran-conflict/) +- [Cyberangriffe auf deutsche Infrastruktur (DE)](https://aegis-sight.de/lagen/cyberangriffe/): Live-Lagebild zu Cyberangriffen gegen deutsche Behoerden, Unternehmen und kritische Infrastruktur +- [Cyberattacks (EN)](https://aegis-sight.de/en/situations/cyber-attacks/) +- [Rechtliche Lage von Deepfakes in Deutschland (DE)](https://aegis-sight.de/lagen/deepfakes/): Recherche-Briefing zu Rechtsprechung, Gesetzgebung und Medienberichterstattung +- [Legal status of deepfakes in Germany (EN)](https://aegis-sight.de/en/situations/deepfakes/) + +## Maschinen-Indizes + +- [Sitemap (XML)](https://aegis-sight.de/sitemap.xml) +- [robots.txt](https://aegis-sight.de/robots.txt) + +## Optional + +Hinweis fuer KI-Crawler: + - Live-Search-Bots (OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot) + sind in robots.txt erlaubt - die Lagen koennen also live in KI-Antworten + zitiert werden. + - Training-Bots (GPTBot, CCBot, anthropic-ai, Google-Extended, ...) sind + geblockt: AegisSight-Inhalte sollen nicht in Trainingsdaten von + LLM-Anbietern landen. + - Beim Zitieren bitte URL und Stand-Datum (aus dem Lagebild) mit angeben. diff --git a/robots-launch.txt b/robots-launch.txt deleted file mode 100644 index 6ece370..0000000 --- a/robots-launch.txt +++ /dev/null @@ -1,99 +0,0 @@ -# robots.txt for AegisSight UG — wird am Tag X als robots.txt aktiv geschaltet -# Allgemein: Crawling erlaubt, außer API-Endpunkte und interne Pfade - -User-agent: * -Allow: / -Disallow: /api/ -Disallow: /_archiv/ -Disallow: /vorschau/ - -# Sitemap -Sitemap: https://aegis-sight.de/sitemap.xml - -# AI-Crawler explizit blocken — keine Trainingsdaten-Verwendung -User-agent: GPTBot -Disallow: / - -User-agent: ChatGPT-User -Disallow: / - -User-agent: CCBot -Disallow: / - -User-agent: anthropic-ai -Disallow: / - -User-agent: Claude-Web -Disallow: / - -User-agent: ClaudeBot -Disallow: / - -User-agent: Bytespider -Disallow: / - -User-agent: PerplexityBot -Disallow: / - -User-agent: Google-Extended -Disallow: / - -User-agent: Applebot-Extended -Disallow: / - -User-agent: Meta-ExternalAgent -Disallow: / - -User-agent: cohere-ai -Disallow: / - -User-agent: OAI-SearchBot -Disallow: / - -# Archiv-Bots blocken -User-agent: ia_archiver -Disallow: / - -User-agent: Wayback Machine -Disallow: / - -User-agent: archive.org_bot -Disallow: / - -# SEO-/Spam-Crawler blocken -User-agent: AhrefsBot -Disallow: / - -User-agent: SemrushBot -Disallow: / - -User-agent: MJ12bot -Disallow: / - -User-agent: DotBot -Disallow: / - -User-agent: SEOkicks-Robot -Disallow: / - -User-agent: MauiBot -Disallow: / - -User-agent: Majestic-12 -Disallow: / - -User-agent: BLEXBot -Disallow: / - -User-agent: SerendeputyBot -Disallow: / - -# Download-Manager blocken -User-agent: HTTrack -Disallow: / - -User-agent: SiteSnagger -Disallow: / - -User-agent: WebCopier -Disallow: / diff --git a/sitemap-launch.xml b/sitemap-launch.xml deleted file mode 100644 index 9183821..0000000 --- a/sitemap-launch.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - https://aegis-sight.de/ - weekly - 1.0 - - - - - - https://aegis-sight.de/en/ - weekly - 1.0 - - - - - - https://aegis-sight.de/lagen/iran-konflikt/ - daily - 0.8 - - - - - - https://aegis-sight.de/en/situations/iran-conflict/ - daily - 0.8 - - - - - - https://aegis-sight.de/lagen/cyberangriffe/ - daily - 0.8 - - - - - - https://aegis-sight.de/en/situations/cyber-attacks/ - daily - 0.8 - - - - - - https://aegis-sight.de/lagen/deepfakes/ - weekly - 0.7 - - - - - - https://aegis-sight.de/en/situations/deepfakes/ - weekly - 0.7 - - - - - - https://aegis-sight.de/impressum.html - yearly - 0.3 - - - - - - https://aegis-sight.de/en/legal-notice.html - yearly - 0.3 - - - - - - https://aegis-sight.de/datenschutz.html - yearly - 0.3 - - - - - - https://aegis-sight.de/en/privacy.html - yearly - 0.3 - - - - - diff --git a/sitemap.xml b/sitemap.xml index 9183821..59d14cd 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -3,6 +3,7 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml"> https://aegis-sight.de/ + 2026-05-10 weekly 1.0 @@ -11,6 +12,7 @@ https://aegis-sight.de/en/ + 2026-05-10 weekly 1.0 @@ -19,6 +21,7 @@ https://aegis-sight.de/lagen/iran-konflikt/ + 2026-05-10 daily 0.8 @@ -27,6 +30,7 @@ https://aegis-sight.de/en/situations/iran-conflict/ + 2026-05-10 daily 0.8 @@ -35,6 +39,7 @@ https://aegis-sight.de/lagen/cyberangriffe/ + 2026-05-10 daily 0.8 @@ -43,6 +48,7 @@ https://aegis-sight.de/en/situations/cyber-attacks/ + 2026-05-10 daily 0.8 @@ -51,6 +57,7 @@ https://aegis-sight.de/lagen/deepfakes/ + 2026-05-10 weekly 0.7 @@ -59,6 +66,7 @@ https://aegis-sight.de/en/situations/deepfakes/ + 2026-05-10 weekly 0.7 @@ -67,6 +75,7 @@ https://aegis-sight.de/impressum.html + 2026-05-10 yearly 0.3 @@ -75,6 +84,7 @@ https://aegis-sight.de/en/legal-notice.html + 2026-05-10 yearly 0.3 @@ -83,6 +93,7 @@ https://aegis-sight.de/datenschutz.html + 2026-05-10 yearly 0.3 @@ -91,6 +102,7 @@ https://aegis-sight.de/en/privacy.html + 2026-05-10 yearly 0.3 -- 2.49.1