Update imprint data and remove trust indicators
- Fix impressum.html with correct HRB 110105 and Amtsgericht Düsseldorf - Add English versions of legal pages (impressum-en.html, datenschutz-en.html) - Correct company representatives to Hendrik Gebhardt & Monami Homma - Remove incorrect Marlon Paulse references and Wiesenstraße address - Remove trust-indicators section from website (HTML, CSS, JS) - Add mobile.css and related mobile navigation files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@ -389,19 +389,34 @@ const LoginModal = {
|
||||
* Handle form submission
|
||||
* @param {Event} e - Submit event
|
||||
*/
|
||||
handleSubmit(e) {
|
||||
async handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
const password = document.getElementById('auth-password').value;
|
||||
|
||||
// Check password (temporarily hardcoded as requested)
|
||||
if (password === '123456') {
|
||||
sessionStorage.setItem(CONFIG.AUTH.SESSION_KEY, 'true');
|
||||
this.close();
|
||||
window.location.href = CONFIG.AUTH.REDIRECT_PAGE;
|
||||
} else {
|
||||
try {
|
||||
// Validate token via Insights API
|
||||
const response = await fetch('/insights/api/validate-token.php', {
|
||||
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'));
|
||||
document.getElementById('auth-password').value = '';
|
||||
document.getElementById('auth-password').focus();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -38,13 +38,6 @@ const CONFIG = {
|
||||
STORAGE_KEY: 'intelsight_language'
|
||||
},
|
||||
|
||||
// Trust Indicators Target Values
|
||||
TRUST_INDICATORS: {
|
||||
AVAILABILITY: 99.9,
|
||||
AUTHORITIES_COUNT: 500,
|
||||
SUPPORT_HOURS: 24
|
||||
},
|
||||
|
||||
// Intersection Observer Settings
|
||||
OBSERVER: {
|
||||
THRESHOLD: 0.3,
|
||||
|
||||
42
js/legal-pages.js
Normale Datei
42
js/legal-pages.js
Normale Datei
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Minimal JavaScript for legal pages (Impressum & Datenschutz)
|
||||
* Only includes necessary functionality for language switching
|
||||
*/
|
||||
|
||||
// Simple language toggle for legal pages
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 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('intelsight-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;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
196
js/mobile-nav.js
Normale Datei
196
js/mobile-nav.js
Normale Datei
@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Mobile Navigation Handler
|
||||
* Clean, accessible mobile navigation implementation
|
||||
*/
|
||||
|
||||
class MobileNavigation {
|
||||
constructor() {
|
||||
this.menuToggle = document.querySelector('.mobile-menu-toggle');
|
||||
this.mobileMenu = document.querySelector('.nav-menu-mobile');
|
||||
this.overlay = document.querySelector('.mobile-menu-overlay');
|
||||
this.menuLinks = document.querySelectorAll('.nav-menu-mobile a');
|
||||
this.closeButton = document.querySelector('.mobile-menu-close');
|
||||
this.isOpen = false;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (!this.menuToggle || !this.mobileMenu) return;
|
||||
|
||||
// Toggle button click
|
||||
this.menuToggle.addEventListener('click', () => this.toggleMenu());
|
||||
|
||||
// Close button click
|
||||
if (this.closeButton) {
|
||||
this.closeButton.addEventListener('click', () => this.closeMenu());
|
||||
}
|
||||
|
||||
// Overlay click closes menu
|
||||
this.overlay.addEventListener('click', () => this.closeMenu());
|
||||
|
||||
// Menu links click closes menu
|
||||
this.menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => this.closeMenu());
|
||||
});
|
||||
|
||||
// ESC key closes menu
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && this.isOpen) {
|
||||
this.closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent body scroll when menu is open
|
||||
this.handleBodyScroll();
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.isOpen ? this.closeMenu() : this.openMenu();
|
||||
}
|
||||
|
||||
openMenu() {
|
||||
this.isOpen = true;
|
||||
this.menuToggle.classList.add('active');
|
||||
this.mobileMenu.classList.add('active');
|
||||
this.overlay.classList.add('active');
|
||||
|
||||
// Update ARIA attributes
|
||||
this.menuToggle.setAttribute('aria-expanded', 'true');
|
||||
this.mobileMenu.setAttribute('aria-hidden', 'false');
|
||||
|
||||
// Prevent body scroll
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
// Focus management
|
||||
setTimeout(() => {
|
||||
const firstLink = this.mobileMenu.querySelector('a');
|
||||
if (firstLink) firstLink.focus();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
this.isOpen = false;
|
||||
this.menuToggle.classList.remove('active');
|
||||
this.mobileMenu.classList.remove('active');
|
||||
this.overlay.classList.remove('active');
|
||||
|
||||
// Update ARIA attributes
|
||||
this.menuToggle.setAttribute('aria-expanded', 'false');
|
||||
this.mobileMenu.setAttribute('aria-hidden', 'true');
|
||||
|
||||
// Restore body scroll
|
||||
document.body.style.overflow = '';
|
||||
|
||||
// Return focus to toggle button
|
||||
this.menuToggle.focus();
|
||||
}
|
||||
|
||||
handleBodyScroll() {
|
||||
// Save scroll position when menu opens
|
||||
let scrollPosition = 0;
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
if (this.isOpen) {
|
||||
scrollPosition = window.pageYOffset;
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.top = `-${scrollPosition}px`;
|
||||
document.body.style.width = '100%';
|
||||
} else {
|
||||
document.body.style.position = '';
|
||||
document.body.style.top = '';
|
||||
document.body.style.width = '';
|
||||
window.scrollTo(0, scrollPosition);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(this.mobileMenu, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Smooth scroll for anchor links
|
||||
class SmoothScroll {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', (e) => {
|
||||
const href = anchor.getAttribute('href');
|
||||
if (href === '#') return;
|
||||
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(href);
|
||||
|
||||
if (target) {
|
||||
const offset = 80; // Account for fixed navbar
|
||||
const targetPosition = target.offsetTop - offset;
|
||||
|
||||
window.scrollTo({
|
||||
top: targetPosition,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive image loading
|
||||
class ResponsiveImages {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
// Check if user prefers reduced motion
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
if (prefersReducedMotion) {
|
||||
// Disable animations
|
||||
document.documentElement.style.setProperty('--animation-duration', '0.01s');
|
||||
}
|
||||
|
||||
// Lazy load images on mobile
|
||||
if ('IntersectionObserver' in window && window.innerWidth <= 768) {
|
||||
const images = document.querySelectorAll('img[data-src]');
|
||||
|
||||
const imageObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
img.src = img.dataset.src;
|
||||
img.removeAttribute('data-src');
|
||||
imageObserver.unobserve(img);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
images.forEach(img => imageObserver.observe(img));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on DOM load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new MobileNavigation();
|
||||
new SmoothScroll();
|
||||
new ResponsiveImages();
|
||||
|
||||
// Hide mobile menu button styles until JS loads
|
||||
document.documentElement.classList.add('js-loaded');
|
||||
});
|
||||
|
||||
// Handle orientation change
|
||||
window.addEventListener('orientationchange', () => {
|
||||
// Close mobile menu on orientation change
|
||||
const mobileNav = document.querySelector('.nav-menu-mobile');
|
||||
if (mobileNav && mobileNav.classList.contains('active')) {
|
||||
const event = new Event('click');
|
||||
document.querySelector('.mobile-menu-overlay').dispatchEvent(event);
|
||||
}
|
||||
});
|
||||
@ -6,14 +6,29 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Check if user is on a mobile device
|
||||
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
|
||||
('ontouchstart' in window) ||
|
||||
(navigator.maxTouchPoints > 0);
|
||||
|
||||
// Exit early if on mobile device - no protection
|
||||
if (isMobile) {
|
||||
console.log('Mobile device detected - protection disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable right-click context menu
|
||||
document.addEventListener('contextmenu', function(e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Disable text selection
|
||||
// Disable text selection - except for auth password field
|
||||
document.addEventListener('selectstart', function(e) {
|
||||
// Allow text selection in the authentication password field
|
||||
if (e.target && e.target.id === 'auth-password') {
|
||||
return true;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
@ -24,23 +39,31 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
// Disable copy
|
||||
// Disable copy - except for auth password field
|
||||
document.addEventListener('copy', function(e) {
|
||||
// Allow copy in the authentication password field
|
||||
if (e.target && e.target.id === 'auth-password') {
|
||||
return true;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Disable cut
|
||||
// Disable cut - except for auth password field
|
||||
document.addEventListener('cut', function(e) {
|
||||
// Allow cut in the authentication password field
|
||||
if (e.target && e.target.id === 'auth-password') {
|
||||
return true;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Disable paste
|
||||
document.addEventListener('paste', function(e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
// Allow paste everywhere - removed restriction
|
||||
// document.addEventListener('paste', function(e) {
|
||||
// e.preventDefault();
|
||||
// return false;
|
||||
// });
|
||||
|
||||
// Disable print
|
||||
window.addEventListener('beforeprint', function(e) {
|
||||
@ -116,11 +139,11 @@
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Ctrl+V (Paste)
|
||||
if (e.ctrlKey && e.keyCode === 86) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Ctrl+V (Paste) - Allow paste
|
||||
// if (e.ctrlKey && e.keyCode === 86) {
|
||||
// e.preventDefault();
|
||||
// return false;
|
||||
// }
|
||||
});
|
||||
|
||||
// Disable image dragging
|
||||
|
||||
@ -41,6 +41,8 @@ const translations = {
|
||||
|
||||
// Who We Are
|
||||
whoWeAreTitle: 'Unternehmen',
|
||||
companyCardTitle1: 'Spezialist für Behördensoftware',
|
||||
companyCardTitle2: 'Unser Ansatz',
|
||||
whoWeArePara1: 'IntelSight UG ist Ihr <strong>Spezialist für hochsichere, maßgeschneiderte IT-Lösungen</strong> aus Nordrhein-Westfalen. Wir entwickeln innovative Software speziell für staatliche Sicherheits- und Ermittlungsbehörden.',
|
||||
whoWeArePara2: 'Unser Ansatz vereint modernste Technologie mit einem tiefen Verständnis für die besonderen Anforderungen von Behörden. Dabei steht die Balance zwischen Sicherheit, Effizienz und rechtskonformer Umsetzung im Mittelpunkt unserer Arbeit.',
|
||||
locationBadge: 'Nordrhein-Westfalen, Deutschland',
|
||||
@ -154,7 +156,7 @@ const translations = {
|
||||
|
||||
en: {
|
||||
// Page meta
|
||||
pageTitle: 'IntelSight - Security Made in Germany',
|
||||
pageTitle: 'IntelSight - Sicherheit Made in Germany',
|
||||
|
||||
// Navigation
|
||||
skipNav: 'Skip to main content',
|
||||
@ -165,7 +167,7 @@ const translations = {
|
||||
langSwitch: 'EN | DE',
|
||||
|
||||
// Hero Section
|
||||
heroTitle: 'SECURITY MADE IN GERMANY',
|
||||
heroTitle: 'SICHERHEIT MADE IN GERMANY',
|
||||
heroSubtitle: 'Specialist for highly secure, customized IT solutions for government agencies',
|
||||
|
||||
// Trust Indicators
|
||||
@ -188,6 +190,8 @@ const translations = {
|
||||
|
||||
// Who We Are
|
||||
whoWeAreTitle: 'Company',
|
||||
companyCardTitle1: 'Government Software Specialist',
|
||||
companyCardTitle2: 'Our Approach',
|
||||
whoWeArePara1: 'IntelSight UG is your <strong>specialist for highly secure, customized IT solutions</strong> from North Rhine-Westphalia. We develop innovative software specifically for government security and law enforcement agencies.',
|
||||
whoWeArePara2: 'Our approach combines cutting-edge technology with a deep understanding of the special requirements of government agencies. The balance between security, efficiency and legally compliant implementation is at the center of our work.',
|
||||
locationBadge: 'North Rhine-Westphalia, Germany',
|
||||
@ -373,6 +377,9 @@ function applyTranslations(language) {
|
||||
|
||||
// Update expand button text if it exists
|
||||
updateExpandButtonText(language);
|
||||
|
||||
// Update footer legal links based on language
|
||||
updateFooterLinks(language);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,4 +414,32 @@ function getTranslation(key) {
|
||||
*/
|
||||
function getCurrentLanguage() {
|
||||
return currentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update footer legal links based on language
|
||||
* @param {string} language - Current language code
|
||||
*/
|
||||
function updateFooterLinks(language) {
|
||||
// Get footer links
|
||||
const impressumLink = document.querySelector('a[href="impressum.html"], a[href="impressum-en.html"]');
|
||||
const datenschutzLink = document.querySelector('a[href="datenschutz.html"], a[href="datenschutz-en.html"]');
|
||||
|
||||
if (language === 'en') {
|
||||
// Switch to English versions
|
||||
if (impressumLink) {
|
||||
impressumLink.href = 'impressum-en.html';
|
||||
}
|
||||
if (datenschutzLink) {
|
||||
datenschutzLink.href = 'datenschutz-en.html';
|
||||
}
|
||||
} else {
|
||||
// Switch to German versions
|
||||
if (impressumLink) {
|
||||
impressumLink.href = 'impressum.html';
|
||||
}
|
||||
if (datenschutzLink) {
|
||||
datenschutzLink.href = 'datenschutz.html';
|
||||
}
|
||||
}
|
||||
}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren