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 `
-
-
-
-
${t('authDescription')}
-
-
${t('noAccess')} ${t('contactUs')}
-
- `;
- },
-
- /**
- * 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