From aa6da557e45fe5a49fd9916a04b93dab293f7086 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Mon, 6 Apr 2026 17:38:18 +0200 Subject: [PATCH] feat: Neue Produktseite AegisSight Monitor unter /vorschau/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Produktfokussierte Landing Page mit: - Hero: Klare Produktbotschaft und CTAs - Problem/Solution: Warum OSINT-Automation nötig ist - Features: 6 Kernfähigkeiten des Monitors - Live-Demos: 3 Lagen-Cards (Iran live + 2 Platzhalter) - Trust-Signale: Made in Germany, DSGVO, Hosting DE - Light-Mode Design mit Navy/Gold Akzenten - Live-Daten-Fetch aus /lagen/iran-konflikt/data/current.json - Responsive (Desktop/Tablet/Mobile) Co-Authored-By: Claude Opus 4.6 (1M context) --- vorschau/css/style.css | 722 +++++++++++++++++++++++++++++++++++++++++ vorschau/index.html | 441 +++++++++++++------------ vorschau/js/app.js | 107 ++++++ 3 files changed, 1067 insertions(+), 203 deletions(-) create mode 100644 vorschau/css/style.css create mode 100644 vorschau/js/app.js diff --git a/vorschau/css/style.css b/vorschau/css/style.css new file mode 100644 index 0000000..a5bf232 --- /dev/null +++ b/vorschau/css/style.css @@ -0,0 +1,722 @@ +/* AegisSight Monitor - Product Page (Light Mode) */ + +/* Fonts */ +@font-face { + font-family: 'Inter'; + src: url('/assets/fonts/Inter-Regular.woff2') format('woff2'), + url('/assets/fonts/Inter-Regular.ttf') format('truetype'); + font-weight: 400; + font-display: swap; +} +@font-face { + font-family: 'Inter'; + src: url('/assets/fonts/Inter-SemiBold.woff2') format('woff2'), + url('/assets/fonts/Inter-SemiBold.ttf') format('truetype'); + font-weight: 600; + font-display: swap; +} +@font-face { + font-family: 'Inter'; + src: url('/assets/fonts/Inter-Bold.woff2') format('woff2'), + url('/assets/fonts/Inter-Bold.ttf') format('truetype'); + font-weight: 700; + font-display: swap; +} +@font-face { + font-family: 'Inter'; + src: url('/assets/fonts/Inter-Light.woff2') format('woff2'), + url('/assets/fonts/Inter-Light.ttf') format('truetype'); + font-weight: 300; + font-display: swap; +} + +/* Variables */ +:root { + --navy: #0A1832; + --navy-light: #132844; + --gold: #C8A851; + --gold-light: #D4B96A; + --gold-dark: #B39645; + --white: #FFFFFF; + --gray-50: #F8FAFB; + --gray-100: #F0F2F5; + --gray-200: #E0E4E8; + --gray-400: #9AA5B4; + --gray-600: #5A6478; + --text: #333333; + --text-light: #5A6478; + --radius: 8px; + --radius-lg: 12px; + --shadow: 0 2px 8px rgba(10, 24, 50, 0.08); + --shadow-lg: 0 8px 24px rgba(10, 24, 50, 0.12); + --nav-height: 72px; +} + +/* Reset */ +*, *::before, *::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: var(--nav-height); +} + +body { + font-family: 'Inter', system-ui, -apple-system, sans-serif; + font-size: 16px; + line-height: 1.6; + color: var(--text); + background: var(--white); + -webkit-font-smoothing: antialiased; +} + +img { max-width: 100%; height: auto; } +a { color: inherit; text-decoration: none; } + +/* Container */ +.container { + max-width: 1120px; + margin: 0 auto; + padding: 0 24px; +} + +/* ==================== NAVIGATION ==================== */ +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + height: var(--nav-height); + background: var(--white); + z-index: 1000; + transition: box-shadow 0.3s; +} + +.navbar.scrolled { + box-shadow: 0 1px 12px rgba(10, 24, 50, 0.1); +} + +.nav-container { + max-width: 1120px; + margin: 0 auto; + padding: 0 24px; + height: 100%; + display: flex; + align-items: center; + justify-content: space-between; +} + +.nav-logo { display: flex; align-items: center; } +.logo-img { height: 36px; width: auto; } + +.nav-menu { + list-style: none; + display: flex; + gap: 32px; +} + +.nav-menu a { + font-size: 0.9rem; + font-weight: 500; + color: var(--navy); + transition: color 0.2s; + letter-spacing: 0.01em; +} + +.nav-menu a:hover { color: var(--gold); } + +/* Mobile Menu Toggle */ +.mobile-menu-toggle { + display: none; + background: none; + border: none; + cursor: pointer; + width: 32px; + height: 24px; + position: relative; + flex-direction: column; + justify-content: space-between; +} + +.mobile-menu-toggle span { + display: block; + width: 100%; + height: 2px; + background: var(--navy); + border-radius: 2px; + transition: transform 0.3s, opacity 0.3s; +} + +.mobile-menu-toggle.active span:nth-child(1) { + transform: rotate(45deg) translate(7px, 7px); +} +.mobile-menu-toggle.active span:nth-child(2) { + opacity: 0; +} +.mobile-menu-toggle.active span:nth-child(3) { + transform: rotate(-45deg) translate(7px, -7px); +} + +/* Mobile Menu */ +.mobile-menu { + position: fixed; + top: var(--nav-height); + left: 0; + right: 0; + background: var(--white); + padding: 16px 24px 24px; + box-shadow: var(--shadow-lg); + transform: translateY(-100%); + opacity: 0; + transition: transform 0.3s, opacity 0.3s; + z-index: 999; + pointer-events: none; +} + +.mobile-menu.open { + transform: translateY(0); + opacity: 1; + pointer-events: all; +} + +.mobile-menu ul { list-style: none; } + +.mobile-menu li { border-bottom: 1px solid var(--gray-100); } + +.mobile-menu a { + display: block; + padding: 14px 0; + font-size: 1rem; + font-weight: 500; + color: var(--navy); +} + +.mobile-overlay { + position: fixed; + inset: 0; + background: rgba(10, 24, 50, 0.3); + z-index: 998; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s; +} + +.mobile-overlay.open { + opacity: 1; + pointer-events: all; +} + +/* ==================== HERO ==================== */ +.hero { + position: relative; + min-height: 85vh; + display: flex; + align-items: center; + padding-top: var(--nav-height); + overflow: hidden; +} + +.hero-bg { + position: absolute; + inset: 0; + background: + radial-gradient(ellipse at 80% 20%, rgba(200, 168, 81, 0.06) 0%, transparent 50%), + radial-gradient(ellipse at 20% 80%, rgba(10, 24, 50, 0.04) 0%, transparent 50%), + linear-gradient(135deg, var(--white) 0%, var(--gray-50) 100%); + z-index: 0; +} + +.hero-content { + position: relative; + z-index: 1; + max-width: 720px; + padding: 80px 24px; +} + +.hero-title { + font-size: 3.2rem; + font-weight: 700; + color: var(--navy); + line-height: 1.1; + margin-bottom: 20px; + letter-spacing: -0.02em; +} + +.hero-claim { + font-size: 1.4rem; + font-weight: 300; + color: var(--text); + line-height: 1.5; + margin-bottom: 16px; +} + +.gold { color: var(--gold); font-weight: 600; } + +.hero-sub { + font-size: 1.05rem; + color: var(--text-light); + line-height: 1.7; + margin-bottom: 36px; +} + +.hero-cta { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +/* ==================== BUTTONS ==================== */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 12px 28px; + border-radius: var(--radius); + font-family: inherit; + font-size: 0.95rem; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; + border: 2px solid transparent; + text-decoration: none; +} + +.btn-primary { + background: var(--gold); + color: var(--navy); + border-color: var(--gold); +} + +.btn-primary:hover { + background: var(--gold-dark); + border-color: var(--gold-dark); +} + +.btn-outline { + background: transparent; + color: var(--navy); + border-color: var(--navy); +} + +.btn-outline:hover { + background: var(--navy); + color: var(--white); +} + +.btn-lg { + padding: 16px 40px; + font-size: 1.05rem; +} + +.btn-block { width: 100%; } + +/* ==================== SECTIONS ==================== */ +.section { + padding: 96px 0; +} + +.section-gray { + background: var(--gray-50); +} + +.section-dark { + background: var(--navy); + color: var(--white); +} + +.section-title { + font-size: 2rem; + font-weight: 700; + color: var(--navy); + text-align: center; + margin-bottom: 16px; + letter-spacing: -0.01em; +} + +.section-dark .section-title { + color: var(--white); +} + +.section-subtitle { + font-size: 1.05rem; + color: var(--text-light); + text-align: center; + max-width: 600px; + margin: 0 auto 56px; +} + +/* ==================== GRID ==================== */ +.grid-3 { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 32px; + margin-top: 48px; +} + +/* ==================== PROBLEM CARDS ==================== */ +.problem-card { + text-align: center; + padding: 32px 24px; +} + +.problem-icon { + width: 64px; + height: 64px; + margin: 0 auto 20px; + display: flex; + align-items: center; + justify-content: center; + background: var(--white); + border-radius: 50%; + box-shadow: var(--shadow); +} + +.problem-card h3 { + font-size: 1.15rem; + font-weight: 700; + color: var(--navy); + margin-bottom: 10px; +} + +.problem-card p { + font-size: 0.95rem; + color: var(--text-light); + line-height: 1.6; +} + +/* ==================== WORKFLOW ==================== */ +.workflow { + display: flex; + align-items: flex-start; + justify-content: center; + gap: 0; + margin-top: 56px; +} + +.workflow-step { + flex: 1; + max-width: 300px; + text-align: center; + padding: 0 24px; +} + +.step-number { + width: 48px; + height: 48px; + margin: 0 auto 20px; + display: flex; + align-items: center; + justify-content: center; + background: var(--gold); + color: var(--navy); + font-size: 1.2rem; + font-weight: 700; + border-radius: 50%; +} + +.workflow-step h3 { + font-size: 1.15rem; + font-weight: 700; + color: var(--navy); + margin-bottom: 10px; +} + +.workflow-step p { + font-size: 0.95rem; + color: var(--text-light); + line-height: 1.6; +} + +.workflow-connector { + width: 60px; + height: 2px; + background: var(--gold); + margin-top: 23px; + flex-shrink: 0; + opacity: 0.5; +} + +/* ==================== FEATURE CARDS ==================== */ +.feature-card { + background: var(--white); + border-radius: var(--radius-lg); + padding: 32px 28px; + box-shadow: var(--shadow); + transition: box-shadow 0.3s, transform 0.3s; +} + +.feature-card:hover { + box-shadow: var(--shadow-lg); + transform: translateY(-2px); +} + +.feature-icon { + width: 52px; + height: 52px; + display: flex; + align-items: center; + justify-content: center; + background: var(--gray-50); + border-radius: var(--radius); + margin-bottom: 16px; +} + +.feature-card h3 { + font-size: 1.05rem; + font-weight: 700; + color: var(--navy); + margin-bottom: 8px; +} + +.feature-card p { + font-size: 0.9rem; + color: var(--text-light); + line-height: 1.6; +} + +/* ==================== DEMO CARDS ==================== */ +.demos-grid { + margin-top: 48px; +} + +.demo-card { + background: var(--white); + border-radius: var(--radius-lg); + padding: 32px 28px; + box-shadow: var(--shadow); + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.demo-card-live { + border: 2px solid var(--gold); +} + +.demo-card-placeholder { + border: 2px dashed var(--gray-200); + opacity: 0.6; +} + +.demo-badge { + display: inline-block; + padding: 4px 14px; + border-radius: 20px; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 16px; + width: fit-content; + background: var(--gold); + color: var(--navy); +} + +.badge-soon { + background: var(--gray-100); + color: var(--gray-400); +} + +.demo-title { + font-size: 1.3rem; + font-weight: 700; + color: var(--navy); + margin-bottom: 20px; +} + +.demo-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + margin-bottom: 20px; +} + +.demo-stat { + text-align: center; + padding: 12px 8px; + background: var(--gray-50); + border-radius: var(--radius); +} + +.stat-value { + display: block; + font-size: 1.5rem; + font-weight: 700; + color: var(--navy); + line-height: 1.2; +} + +.stat-label { + display: block; + font-size: 0.75rem; + color: var(--text-light); + margin-top: 4px; +} + +.demo-updated { + font-size: 0.85rem; + color: var(--text-light); + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 1px solid var(--gray-100); +} + +.demo-placeholder-text { + font-size: 1rem; + color: var(--gray-400); + flex: 1; + display: flex; + align-items: center; + justify-content: center; + min-height: 120px; +} + +/* ==================== TRUST ==================== */ +.trust-grid { + margin-top: 0; +} + +.trust-card { + text-align: center; + padding: 24px; +} + +.trust-icon { + margin-bottom: 16px; + filter: brightness(0) invert(1); +} + +.trust-card h3 { + font-size: 1.1rem; + font-weight: 700; + margin-bottom: 8px; +} + +.trust-card p { + font-size: 0.9rem; + opacity: 0.75; +} + +/* ==================== CTA ==================== */ +.cta-container { + text-align: center; + max-width: 600px; +} + +.cta-text { + font-size: 1.1rem; + color: var(--text-light); + margin-bottom: 32px; +} + +.cta-email { + font-size: 0.9rem; + color: var(--text-light); + margin-top: 16px; +} + +/* ==================== FOOTER ==================== */ +.footer { + background: var(--navy); + color: rgba(255, 255, 255, 0.7); + padding: 40px 0; + font-size: 0.85rem; +} + +.footer-content { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 24px; + padding-bottom: 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.footer-company { + font-weight: 600; + color: var(--white); + margin-bottom: 4px; +} + +.footer-links { + display: flex; + gap: 24px; +} + +.footer-links a { + color: rgba(255, 255, 255, 0.7); + transition: color 0.2s; +} + +.footer-links a:hover { color: var(--white); } + +.footer-copyright { + text-align: center; + font-size: 0.8rem; + opacity: 0.5; +} + +/* ==================== RESPONSIVE ==================== */ + +/* Tablet */ +@media (max-width: 1024px) { + .grid-3 { grid-template-columns: repeat(2, 1fr); } + .hero-title { font-size: 2.6rem; } + .section { padding: 72px 0; } + .workflow-connector { width: 40px; } +} + +/* Mobile */ +@media (max-width: 768px) { + .nav-menu { display: none; } + .mobile-menu-toggle { display: flex; } + + .grid-3 { grid-template-columns: 1fr; gap: 20px; } + .hero { min-height: 70vh; } + .hero-content { padding: 48px 24px; } + .hero-title { font-size: 2rem; } + .hero-claim { font-size: 1.15rem; } + .section { padding: 56px 0; } + .section-title { font-size: 1.6rem; } + + .workflow { + flex-direction: column; + align-items: center; + gap: 8px; + } + + .workflow-connector { + width: 2px; + height: 32px; + margin: 0; + } + + .workflow-step { + max-width: 100%; + padding: 16px 0; + } + + .hero-cta { + flex-direction: column; + } + + .hero-cta .btn { width: 100%; } + + .footer-content { + flex-direction: column; + text-align: center; + gap: 16px; + } + + .demo-stats { grid-template-columns: repeat(3, 1fr); } +} + +/* Small Mobile */ +@media (max-width: 480px) { + .hero-title { font-size: 1.7rem; } + .container { padding: 0 16px; } +} diff --git a/vorschau/index.html b/vorschau/index.html index c39fee6..e843821 100644 --- a/vorschau/index.html +++ b/vorschau/index.html @@ -3,223 +3,258 @@ - AegisSight - Vorschau + AegisSight Monitor - Echtzeit-Lagebilder aus offenen Quellen - + + - -
- + - -
-
- + - + +
+
+ + +
+
+ + diff --git a/vorschau/js/app.js b/vorschau/js/app.js new file mode 100644 index 0000000..73747d1 --- /dev/null +++ b/vorschau/js/app.js @@ -0,0 +1,107 @@ +/* AegisSight Monitor - Product Page JS */ + +(function () { + 'use strict'; + + /* ==================== NAVBAR SHADOW ==================== */ + var navbar = document.getElementById('navbar'); + window.addEventListener('scroll', function () { + if (window.scrollY > 10) { + navbar.classList.add('scrolled'); + } else { + navbar.classList.remove('scrolled'); + } + }); + + /* ==================== MOBILE MENU ==================== */ + var toggle = document.querySelector('.mobile-menu-toggle'); + var menu = document.getElementById('mobile-menu'); + var overlay = document.getElementById('mobile-overlay'); + + function openMenu() { + toggle.classList.add('active'); + menu.classList.add('open'); + overlay.classList.add('open'); + toggle.setAttribute('aria-expanded', 'true'); + menu.setAttribute('aria-hidden', 'false'); + } + + function closeMenu() { + toggle.classList.remove('active'); + menu.classList.remove('open'); + overlay.classList.remove('open'); + toggle.setAttribute('aria-expanded', 'false'); + menu.setAttribute('aria-hidden', 'true'); + } + + toggle.addEventListener('click', function () { + if (menu.classList.contains('open')) { + closeMenu(); + } else { + openMenu(); + } + }); + + overlay.addEventListener('click', closeMenu); + + // Close on link click + menu.querySelectorAll('a').forEach(function (link) { + link.addEventListener('click', closeMenu); + }); + + /* ==================== SMOOTH SCROLL ==================== */ + document.querySelectorAll('a[href^="#"]').forEach(function (link) { + link.addEventListener('click', function (e) { + var target = document.querySelector(this.getAttribute('href')); + if (target) { + e.preventDefault(); + target.scrollIntoView({ behavior: 'smooth' }); + } + }); + }); + + /* ==================== LIVE DATA FETCH ==================== */ + function timeAgo(dateStr) { + var now = new Date(); + var then = new Date(dateStr); + var diffMs = now - then; + var diffMin = Math.floor(diffMs / 60000); + + if (diffMin < 1) return 'Gerade eben aktualisiert'; + if (diffMin < 60) return 'Aktualisiert vor ' + diffMin + ' Min.'; + var diffH = Math.floor(diffMin / 60); + if (diffH < 24) return 'Aktualisiert vor ' + diffH + ' Std.'; + var diffD = Math.floor(diffH / 24); + return 'Aktualisiert vor ' + diffD + (diffD === 1 ? ' Tag' : ' Tagen'); + } + + function loadLiveData() { + fetch('/lagen/iran-konflikt/data/current.json?t=' + Date.now()) + .then(function (res) { + if (!res.ok) throw new Error('HTTP ' + res.status); + return res.json(); + }) + .then(function (data) { + var incident = data.incident || {}; + var lagebild = data.current_lagebild || {}; + + var elArticles = document.getElementById('stat-articles'); + var elSources = document.getElementById('stat-sources'); + var elFactchecks = document.getElementById('stat-factchecks'); + var elUpdated = document.getElementById('demo-updated'); + + if (elArticles) elArticles.textContent = incident.article_count || '—'; + if (elSources) elSources.textContent = incident.source_count || '—'; + if (elFactchecks) elFactchecks.textContent = incident.factcheck_count || '—'; + if (elUpdated && lagebild.updated_at) { + elUpdated.textContent = timeAgo(lagebild.updated_at); + } + }) + .catch(function () { + var elUpdated = document.getElementById('demo-updated'); + if (elUpdated) elUpdated.textContent = 'Daten derzeit nicht verfügbar'; + }); + } + + loadLiveData(); +})();