From 06c99fe4dbdbd9248dac70e6cea2ccfba1c4328c Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 7 Mar 2026 16:01:43 +0100 Subject: [PATCH] Lagebild: Sticky Section-Nav und Scroll-Spy entfernt Co-Authored-By: Claude Opus 4.6 --- lagebild/index.html | 358 ++++--- lagebild/lagebild.css | 2267 ++++++++++++++++++++--------------------- lagebild/lagebild.js | 1469 +++++++++++++------------- 3 files changed, 1989 insertions(+), 2105 deletions(-) diff --git a/lagebild/index.html b/lagebild/index.html index 7e01d4e..a54c7f8 100644 --- a/lagebild/index.html +++ b/lagebild/index.html @@ -1,183 +1,177 @@ - - - - - - Lagebild Irankonflikt - AegisSight - - - - - - - - - - - - - - -
- - -
-
-
-
- - LIVE-LAGEBILD -
-

LAGEBILD

-

- - -
-
-
- - -
-
-
-
-
-
- -
-
- - -
- -
-
-
-
-

Lagebild

- -
-
-
-
-
-
-
-
- -
-
-
- - -
-
-
-

Karte

-

Geografische Einordnung der Meldungen

-
-
-
-
- - -
-
-
-
-

Faktenchecks

-

KI-gestützte Verifizierung aller zentralen Aussagen gegen unabhängige Quellen

-
-
-
-
- - -
-
-
-

Artikel

-

Alle vom AegisSight Monitor aggregierten Artikel

-
-
-
-
-
-
- - -
-
- - -
-
- - - - - - - - + + + + + + Lagebild Irankonflikt - AegisSight + + + + + + + + + + + + + + +
+ + +
+
+
+
+ + LIVE-LAGEBILD +
+

LAGEBILD

+

+ + +
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+ +
+
+
+
+

Lagebild

+ +
+
+
+
+
+
+
+
+ +
+
+
+ + +
+
+
+

Karte

+

Geografische Einordnung der Meldungen

+
+
+
+
+ + +
+
+
+
+

Faktenchecks

+

KI-gestützte Verifizierung aller zentralen Aussagen gegen unabhängige Quellen

+
+
+
+
+ + +
+
+
+

Artikel

+

Alle vom AegisSight Monitor aggregierten Artikel

+
+
+
+
+
+
+ + +
+
+ + +
+
+ + + + + + + + \ No newline at end of file diff --git a/lagebild/lagebild.css b/lagebild/lagebild.css index b8af9b8..5d066cc 100644 --- a/lagebild/lagebild.css +++ b/lagebild/lagebild.css @@ -1,1158 +1,1111 @@ -/* ========================================================================== - AegisSight Lagebild Page - Dark Theme / Scroll-Narrative - ========================================================================== */ - -/* ---------- Variables ---------- */ -.lagebild-page { - --lb-bg: #0B1121; - --lb-bg-card: #151D2E; - --lb-bg-secondary: #1A2440; - --lb-border: #1E2D45; - --lb-text: #E8ECF4; - --lb-text-sec: #8896AB; - --lb-accent: #C8A851; - --lb-accent-hover: #B5923E; - --lb-success: #10B981; - --lb-warning: #F59E0B; - --lb-error: #EF4444; - --navbar-height: 72px; -} - -/* ---------- Page Base ---------- */ -.lagebild-page { - background: var(--lb-bg); - min-height: 100vh; - color: var(--lb-text); -} - -/* ---------- Navigation Dark Override ---------- */ -.lagebild-page .navbar { - background: rgba(11, 17, 33, 0.95) !important; - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border-bottom: 1px solid var(--lb-border) !important; - box-shadow: none !important; -} -.lagebild-page .logo-img { - background: rgba(160, 175, 200, 0.85); - padding: 4px 10px; - border-radius: 6px; -} -.lagebild-page .nav-menu a { - color: var(--lb-text) !important; -} -.lagebild-page .nav-menu a:hover { - color: var(--lb-accent) !important; -} -.lagebild-page .nav-menu a.nav-active { - color: var(--lb-accent) !important; -} -.lagebild-page .lang-toggle { - color: var(--lb-text-sec) !important; - border-color: var(--lb-border) !important; -} -.lagebild-page .lang-toggle:hover { - color: var(--lb-accent) !important; - border-color: var(--lb-accent) !important; -} -.lagebild-page .hamburger span { - background: var(--lb-text) !important; -} - -/* ---------- Footer Dark Override ---------- */ -.lagebild-page .footer { - background: #080D1A !important; - border-top: 1px solid var(--lb-border); -} -.lagebild-page .footer h4 { - color: var(--lb-accent) !important; -} -.lagebild-page .footer p, -.lagebild-page .footer a, -.lagebild-page .footer li, -.lagebild-page .footer ul li a { - color: var(--lb-text-sec) !important; -} -.lagebild-page .footer a:hover { - color: var(--lb-accent) !important; -} -.lagebild-page .copyright { - color: var(--lb-text-sec) !important; - opacity: 0.5; -} - -/* ---------- Hero Section ---------- */ -.lagebild-hero { - background: linear-gradient(135deg, #0a0f1c 0%, #111B30 50%, #0B1121 100%); - padding: 150px 20px 70px; - text-align: center; - color: #fff; - position: relative; - overflow: hidden; -} -.hero-bg-pattern { - position: absolute; - inset: 0; - background: - radial-gradient(circle at 20% 80%, rgba(200, 168, 81, 0.08) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(200, 168, 81, 0.05) 0%, transparent 50%), - radial-gradient(circle at 50% 50%, rgba(15, 114, 181, 0.06) 0%, transparent 60%); - pointer-events: none; -} -.lagebild-hero .container { - position: relative; - z-index: 1; -} - -/* Hero Badge */ -.hero-badge { - display: inline-flex; - align-items: center; - gap: 8px; - background: rgba(200, 168, 81, 0.12); - border: 1px solid rgba(200, 168, 81, 0.25); - padding: 6px 16px; - border-radius: 20px; - font-size: 0.8rem; - font-weight: 600; - letter-spacing: 1.5px; - color: var(--lb-accent); - margin-bottom: 1.5rem; -} -.badge-dot { - width: 8px; - height: 8px; - background: var(--lb-accent); - border-radius: 50%; - animation: pulse-dot 2s infinite; -} -@keyframes pulse-dot { - 0%, 100% { opacity: 1; transform: scale(1); } - 50% { opacity: 0.4; transform: scale(0.7); } -} - -/* Hero Title */ -.lagebild-hero h1 { - font-family: 'Bebas Neue', sans-serif; - font-size: 3.5rem; - letter-spacing: 5px; - color: #fff; - margin: 0 0 0.3rem; - line-height: 1; -} -.hero-incident-title { - font-size: 1.5rem; - font-weight: 300; - color: rgba(255, 255, 255, 0.85); - margin: 0 0 0.5rem; -} -.hero-date-info { - font-size: 0.85em; - color: rgba(255, 255, 255, 0.5); - font-weight: 400; -} - -/* Hero Stat Cards */ -.hero-stats { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 14px; - margin-top: 2rem; - max-width: 650px; - margin-left: auto; - margin-right: auto; -} -.stat-card { - display: flex; - align-items: center; - gap: 12px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.08); - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); - padding: 14px 16px; - border-radius: var(--radius-md, 8px); - transition: border-color 0.3s, background 0.3s; -} -.stat-card:hover { - border-color: rgba(200, 168, 81, 0.3); - background: rgba(255, 255, 255, 0.08); -} -.stat-card-icon { - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - background: rgba(200, 168, 81, 0.1); - border-radius: var(--radius-md, 8px); - color: var(--lb-accent); - flex-shrink: 0; -} -.stat-card-icon svg { - width: 18px; - height: 18px; -} -.stat-card-content { - min-width: 0; -} -.stat-card-value { - display: block; - font-size: 1.35rem; - font-weight: 700; - color: #fff; - line-height: 1.1; -} -.stat-card-label { - display: block; - font-size: 0.72rem; - color: rgba(255, 255, 255, 0.55); - text-transform: uppercase; - letter-spacing: 0.5px; - margin-top: 2px; -} - -/* ---------- Control Bar (Sticky) ---------- */ -.control-bar { - background: var(--lb-bg-card); - border-bottom: 1px solid var(--lb-border); - padding: 0 20px; - position: sticky; - top: var(--navbar-height); - z-index: 90; - transition: box-shadow 0.3s; -} -.control-bar.stuck { - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); -} -.control-bar .container { - max-width: 1000px; - margin: 0 auto; -} - -/* Timeline Strip */ -.timeline-wrapper { - padding: 12px 0; - border-bottom: 1px solid var(--lb-border); -} -.timeline-strip { - display: flex; - gap: 4px; - overflow-x: auto; - scroll-behavior: smooth; - padding: 4px 0; - scrollbar-width: thin; - scrollbar-color: var(--lb-border) transparent; -} -.timeline-strip::-webkit-scrollbar { - height: 4px; -} -.timeline-strip::-webkit-scrollbar-track { - background: transparent; -} -.timeline-strip::-webkit-scrollbar-thumb { - background: var(--lb-border); - border-radius: 2px; -} -.timeline-day { - display: flex; - flex-direction: column; - align-items: center; - padding: 8px 14px; - border-radius: var(--radius-sm, 4px); - border: 1px solid var(--lb-border); - background: transparent; - cursor: pointer; - transition: all 0.2s; - flex-shrink: 0; - min-width: 64px; - position: relative; - color: var(--lb-text-sec); - font-family: inherit; -} -.timeline-day:hover { - background: var(--lb-bg-secondary); - border-color: rgba(200, 168, 81, 0.4); -} -.timeline-day.active { - background: rgba(200, 168, 81, 0.1); - border-color: var(--lb-accent); -} -.timeline-dot { - position: absolute; - top: -4px; - right: -4px; - width: 10px; - height: 10px; - background: var(--lb-accent); - border-radius: 50%; - animation: pulse-dot 2s infinite; - border: 2px solid var(--lb-bg-card); -} -.timeline-day-num { - font-size: 1.1rem; - font-weight: 700; - line-height: 1; -} -.timeline-day.active .timeline-day-num { - color: var(--lb-accent); -} -.timeline-day-month { - font-size: 0.62rem; - text-transform: uppercase; - letter-spacing: 0.5px; - opacity: 0.7; - margin-top: 1px; -} -.timeline-day-count { - font-size: 0.68rem; - margin-top: 4px; - padding-top: 4px; - border-top: 1px solid var(--lb-border); - width: 100%; - text-align: center; - opacity: 0.6; -} -.timeline-day.active .timeline-day-count { - opacity: 1; - color: var(--lb-accent); -} -.timeline-day-updates { - font-size: 0.58rem; - opacity: 0.4; -} -.timeline-day-label { - font-size: 0.58rem; - color: var(--lb-accent); - font-weight: 600; - margin-top: 2px; -} - -/* Timeline Dropdown */ -.timeline-dropdown { - display: none; - background: var(--lb-bg-secondary); - border: 1px solid var(--lb-border); - border-top: none; - border-radius: 0 0 var(--radius-sm, 4px) var(--radius-sm, 4px); - padding: 10px 14px; - margin-top: 4px; -} -.timeline-dropdown.open { - display: block; -} -.timeline-dropdown-header { - font-size: 0.78rem; - color: var(--lb-text-sec); - margin-bottom: 8px; - font-weight: 500; -} -.timeline-snap-list { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); - gap: 6px; -} -.timeline-snap-item { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 6px 12px; - border-radius: var(--radius-sm, 4px); - border: 1px solid var(--lb-border); - background: transparent; - color: var(--lb-text-sec); - font-size: 0.78rem; - cursor: pointer; - font-family: inherit; - transition: all 0.2s; -} -.timeline-snap-item:hover { - background: var(--lb-bg-card); - border-color: rgba(200, 168, 81, 0.4); - color: var(--lb-text); -} -.timeline-snap-item.active { - background: rgba(200, 168, 81, 0.1); - border-color: var(--lb-accent); - color: var(--lb-accent); -} -.timeline-snap-time { - font-weight: 600; -} -.timeline-snap-meta { - font-size: 0.7rem; - opacity: 0.7; -} - -/* ---------- Section Navigation (Scroll-Spy) ---------- */ -.section-nav { - display: flex; - gap: 0; -} -.section-nav-link { - display: inline-block; - padding: 12px 20px; - font-size: 0.9rem; - font-weight: 600; - color: var(--lb-text-sec); - text-decoration: none; - border-bottom: 3px solid transparent; - transition: all 0.2s; - white-space: nowrap; -} -.section-nav-link:hover { - color: var(--lb-text); -} -.section-nav-link.active { - color: var(--lb-accent); - border-bottom-color: var(--lb-accent); -} -.section-badge { - display: inline-block; - background: rgba(200, 168, 81, 0.12); - color: var(--lb-accent); - padding: 1px 8px; - border-radius: 10px; - font-size: 0.7rem; - font-weight: 600; - margin-left: 4px; - vertical-align: middle; -} -.section-nav-link.active .section-badge { - background: rgba(200, 168, 81, 0.22); -} - -/* ---------- Main Content ---------- */ -.lagebild-main { - padding: 2rem 0 4rem; -} -.lagebild-main > .container { - max-width: 1000px; - margin: 0 auto; - padding: 0 20px; -} - -/* ---------- Content Sections ---------- */ -.content-section { - margin-bottom: 3rem; - scroll-margin-top: calc(var(--navbar-height) + 120px); -} - -/* ---------- Content Cards ---------- */ -.content-card { - background: var(--lb-bg-card); - border-radius: var(--radius-sm, 4px); - border: 1px solid var(--lb-border); - margin-bottom: 1.5rem; - overflow: hidden; - position: relative; -} -.content-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 3px; - background: var(--lb-accent); -} -.card-header { - padding: 24px 32px 0; - display: flex; - justify-content: space-between; - align-items: baseline; - flex-wrap: wrap; - gap: 8px; -} -.card-header h2 { - font-size: 1.3rem; - font-weight: 700; - color: var(--lb-text); - margin: 0; -} -.card-timestamp { - font-size: 0.85rem; - color: var(--lb-text-sec); - font-weight: 500; -} -.card-description { - font-size: 0.85rem; - color: var(--lb-text-sec); - margin: 4px 0 0; - width: 100%; -} -.card-body { - padding: 20px 32px 28px; -} -.card-footer { - padding: 0 32px 28px; - border-top: 1px solid var(--lb-border); - padding-top: 20px; - margin: 0 32px; -} -.card-footer:empty { - display: none; -} - -/* ---------- Karte Section (Full-Width) ---------- */ -.section-karte { - padding: 0; -} -.section-karte .section-heading { - margin-bottom: 1.5rem; -} -.section-karte .section-heading h2 { - font-size: 1.3rem; - font-weight: 700; - color: var(--lb-text); - margin: 0 0 4px; -} -.section-description { - font-size: 0.85rem; - color: var(--lb-text-sec); - margin: 0; -} -#map-container { - height: 500px; - background: var(--lb-bg-secondary); - border-top: 1px solid var(--lb-border); - border-bottom: 1px solid var(--lb-border); -} - -/* ---------- Lagebild Summary ---------- */ -#summary-content { - line-height: 1.85; - font-size: 1.02rem; - color: var(--lb-text); -} -#summary-content h2 { - font-size: 1.15rem; - font-weight: 700; - color: var(--lb-accent); - margin: 1.8rem 0 0.8rem; - padding-bottom: 0.4rem; - border-bottom: 2px solid var(--lb-border); -} -#summary-content h2:first-child { - margin-top: 0; -} -#summary-content h3 { - font-size: 1.05rem; - font-weight: 600; - color: var(--lb-text); - margin: 1.5rem 0 0.6rem; -} -#summary-content p { - margin: 0 0 1rem; -} -#summary-content ul { - margin: 0 0 1rem; - padding-left: 1.5rem; -} -#summary-content li { - margin-bottom: 0.4rem; - color: var(--lb-text); -} -#summary-content strong { - color: #fff; -} - -/* Citations */ -.citation-ref { - color: var(--lb-accent); - font-weight: 700; - cursor: pointer; - text-decoration: none; - font-size: 0.78em; - vertical-align: super; - line-height: 1; - padding: 0 1px; - transition: color 0.2s; -} -.citation-ref:hover { - color: var(--lb-accent-hover); - text-decoration: underline; -} - -/* Source Highlight (smooth scroll target) */ -.source-highlight { - background: rgba(200, 168, 81, 0.15) !important; - border-radius: 4px; - transition: background 1.5s ease-out; -} - -/* ---------- Article Cards ---------- */ -.article-card { - display: flex; - gap: 16px; - padding: 16px 0; - border-bottom: 1px solid var(--lb-border); -} -.article-card:last-child { border-bottom: none; } -.article-date { - flex-shrink: 0; - width: 60px; - text-align: center; -} -.article-date .day { - display: block; - font-size: 1.3rem; - font-weight: 700; - color: var(--lb-accent); - line-height: 1; -} -.article-date .month { - display: block; - font-size: 0.72rem; - color: var(--lb-text-sec); - text-transform: uppercase; - letter-spacing: 0.5px; -} -.article-info { - flex: 1; - min-width: 0; -} -.article-headline { - font-size: 0.95rem; - font-weight: 600; - color: var(--lb-text); - margin: 0 0 6px; - line-height: 1.4; -} -.article-headline a { - color: inherit; - text-decoration: none; -} -.article-headline a:hover { - color: var(--lb-accent); -} -.article-meta { - display: flex; - align-items: center; - gap: 12px; - font-size: 0.8rem; - color: var(--lb-text-sec); - flex-wrap: wrap; -} -.article-source { - font-weight: 600; - color: var(--lb-text); - display: inline-flex; - align-items: center; - gap: 4px; -} -.article-favicon { - width: 16px; - height: 16px; - border-radius: 2px; - vertical-align: middle; -} -.article-lang { - background: var(--lb-bg-secondary); - border: 1px solid var(--lb-border); - padding: 1px 6px; - border-radius: 3px; - font-size: 0.7rem; - text-transform: uppercase; - color: var(--lb-text-sec); -} -.article-link { - color: var(--lb-accent) !important; - text-decoration: none !important; - font-size: 0.78rem; - display: inline-flex; - align-items: center; - gap: 3px; -} -.article-link:hover { - text-decoration: underline !important; -} - -/* Show All Button */ -.show-all-wrapper { - text-align: center; - padding: 24px 0 8px; -} -.show-all-btn { - display: inline-block; - padding: 10px 28px; - background: transparent; - border: 1px solid var(--lb-accent); - color: var(--lb-accent); - font-size: 0.88rem; - font-weight: 600; - border-radius: var(--radius-sm, 4px); - cursor: pointer; - transition: all 0.2s; - font-family: inherit; -} -.show-all-btn:hover { - background: rgba(200, 168, 81, 0.1); -} - -/* ---------- Map ---------- */ -.lagebild-page .map-legend { - background: var(--lb-bg-card) !important; - color: var(--lb-text) !important; - border: 1px solid var(--lb-border) !important; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important; -} -/* Leaflet controls dark */ -.lagebild-page .leaflet-control-zoom a { - background: var(--lb-bg-card) !important; - color: var(--lb-text) !important; - border-color: var(--lb-border) !important; -} -.lagebild-page .leaflet-control-zoom a:hover { - background: var(--lb-bg-secondary) !important; -} -.lagebild-page .leaflet-control-attribution { - background: rgba(11, 17, 33, 0.8) !important; - color: var(--lb-text-sec) !important; -} -.lagebild-page .leaflet-control-attribution a { - color: var(--lb-accent) !important; -} - -/* ---------- Fact Check Cards ---------- */ -.fc-stats { - display: flex; - gap: 12px; - margin-bottom: 24px; - flex-wrap: wrap; -} -.fc-stat { - background: var(--lb-bg-secondary); - border-radius: var(--radius-sm, 4px); - padding: 14px 20px; - text-align: center; - min-width: 80px; - border: 1px solid var(--lb-border); -} -.fc-stat.confirmed { - background: rgba(16, 185, 129, 0.08); - border-color: rgba(16, 185, 129, 0.2); -} -.fc-stat.unconfirmed { - background: rgba(245, 158, 11, 0.08); - border-color: rgba(245, 158, 11, 0.2); -} -.fc-stat.contradicted { - background: rgba(239, 68, 68, 0.08); - border-color: rgba(239, 68, 68, 0.2); -} -.fc-stat-num { - display: block; - font-size: 1.6rem; - font-weight: 800; - color: var(--lb-text); -} -.fc-stat.confirmed .fc-stat-num { color: var(--lb-success); } -.fc-stat.unconfirmed .fc-stat-num { color: var(--lb-warning); } -.fc-stat.contradicted .fc-stat-num { color: var(--lb-error); } -.fc-stat-label { - font-size: 0.75rem; - color: var(--lb-text-sec); - text-transform: uppercase; - letter-spacing: 0.5px; - font-weight: 600; -} - -.factcheck-card { - background: var(--lb-bg-secondary); - border-radius: var(--radius-sm, 4px); - padding: 20px; - margin-bottom: 12px; - border-left: 4px solid var(--lb-border); - transition: transform 0.2s, box-shadow 0.2s; -} -.factcheck-card:hover { - transform: translateY(-1px); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); -} -.factcheck-card.highlight { - background: rgba(200, 168, 81, 0.06); - border-left-color: var(--lb-accent); - box-shadow: 0 2px 12px rgba(200, 168, 81, 0.1); -} -.factcheck-card[data-status="confirmed"], -.factcheck-card[data-status="established"] { - border-left-color: var(--lb-success); -} -.factcheck-card[data-status="unconfirmed"], -.factcheck-card[data-status="unverified"] { - border-left-color: var(--lb-warning); -} -.factcheck-card[data-status="contradicted"], -.factcheck-card[data-status="disputed"] { - border-left-color: var(--lb-error); -} -.factcheck-card[data-status="developing"] { - border-left-color: #3b82f6; -} -.factcheck-card[data-status="false"] { - border-left-color: #dc2626; -} - -.factcheck-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 8px; -} -.factcheck-sources { - font-size: 0.8rem; - color: var(--lb-text-sec); -} -.factcheck-claim { - font-size: 0.95rem; - color: var(--lb-text); - margin: 0 0 4px; - line-height: 1.5; -} - -/* Status Badges */ -.status-badge { - display: inline-block; - padding: 3px 10px; - border-radius: var(--radius-sm, 4px); - font-size: 0.72rem; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.5px; -} -.status-badge.confirmed, .status-badge.established { - background: rgba(16, 185, 129, 0.15); - color: #34d399; -} -.status-badge.unconfirmed, .status-badge.unverified { - background: rgba(245, 158, 11, 0.15); - color: #fbbf24; -} -.status-badge.contradicted, .status-badge.disputed { - background: rgba(239, 68, 68, 0.15); - color: #f87171; -} -.status-badge.developing { - background: rgba(59, 130, 246, 0.15); - color: #60a5fa; -} -.status-badge.false { - background: rgba(220, 38, 38, 0.15); - color: #f87171; -} - -/* Status Progression */ -.status-progression { - display: flex; - align-items: center; - gap: 6px; - margin-top: 10px; - padding-top: 10px; - border-top: 1px solid var(--lb-border); - font-size: 0.78rem; - flex-wrap: wrap; -} -.progression-label { - color: var(--lb-text-sec); - font-weight: 500; - margin-right: 4px; -} -.progression-arrow { - color: var(--lb-accent); - font-size: 1rem; -} -.progression-step { - display: flex; - align-items: center; - gap: 4px; -} -.progression-time { - color: var(--lb-text-sec); - font-size: 0.7rem; -} - -/* Evidence block */ -.factcheck-evidence { - font-size: 0.82rem; - color: var(--lb-text-sec); - margin: 10px 0 0; - line-height: 1.6; - padding: 10px 14px; - background: rgba(0, 0, 0, 0.2); - border-radius: var(--radius-sm, 4px); - border: 1px solid var(--lb-border); -} -.factcheck-evidence strong { - color: var(--lb-text); -} -.factcheck-evidence a { - color: var(--lb-accent) !important; - word-break: break-all; -} - -/* ---------- Floating CTA Pill ---------- */ -.floating-cta { - position: fixed; - bottom: 24px; - left: 50%; - transform: translateX(-50%) translateY(100px); - display: flex; - align-items: center; - gap: 16px; - background: rgba(21, 29, 46, 0.92); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border: 1px solid rgba(200, 168, 81, 0.25); - border-radius: 50px; - padding: 10px 14px 10px 24px; - z-index: 1000; - opacity: 0; - transition: opacity 0.4s, transform 0.4s; - pointer-events: none; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); -} -.floating-cta.visible { - opacity: 1; - transform: translateX(-50%) translateY(0); - pointer-events: auto; -} -.floating-cta.dismissed { - opacity: 0; - transform: translateX(-50%) translateY(100px); - pointer-events: none; -} -.floating-cta-text { - font-size: 0.88rem; - color: var(--lb-text-sec); - font-weight: 500; - white-space: nowrap; -} -.floating-cta-btn { - display: inline-block; - background: var(--lb-accent); - color: #0a0f1c; - padding: 8px 20px; - border-radius: 50px; - font-weight: 700; - text-decoration: none; - font-size: 0.85rem; - white-space: nowrap; - transition: background 0.2s, transform 0.2s; -} -.floating-cta-btn:hover { - background: var(--lb-accent-hover); - transform: scale(1.03); -} -.floating-cta-close { - background: none; - border: none; - color: var(--lb-text-sec); - font-size: 1.3rem; - cursor: pointer; - padding: 0 4px; - line-height: 1; - transition: color 0.2s; - font-family: inherit; -} -.floating-cta-close:hover { - color: var(--lb-text); -} - -@media (max-width: 768px) { - .floating-cta { - left: 12px; - right: 12px; - transform: translateX(0) translateY(100px); - border-radius: 16px; - gap: 10px; - padding: 10px 12px 10px 16px; - } - .floating-cta.visible { - transform: translateX(0) translateY(0); - } - .floating-cta.dismissed { - transform: translateX(0) translateY(100px); - } - .floating-cta-text { - font-size: 0.8rem; - white-space: normal; - } - .floating-cta-btn { - font-size: 0.8rem; - padding: 7px 14px; - flex-shrink: 0; - } -} - -/* ---------- Loading Skeleton ---------- */ -.loading-skeleton { padding: 20px 0; } -.skeleton-line { - height: 16px; - background: linear-gradient(90deg, var(--lb-bg-secondary) 25%, var(--lb-border) 50%, var(--lb-bg-secondary) 75%); - background-size: 200% 100%; - animation: shimmer 1.5s infinite; - border-radius: var(--radius-sm, 4px); - margin-bottom: 12px; -} -.skeleton-line.short { width: 60%; } -@keyframes shimmer { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } -} - -/* Error */ -.lagebild-error { - text-align: center; - padding: 40px 20px; - color: var(--lb-text-sec); -} - -/* ---------- Scroll Reveal ---------- */ -.reveal { - opacity: 0; - transform: translateY(20px); - transition: opacity 0.4s ease-out, transform 0.4s ease-out; -} -.reveal.revealed { - opacity: 1; - transform: translateY(0); -} - -/* ---------- Responsive ---------- */ - -/* Tablet */ -@media (max-width: 1024px) { - .hero-stats { - max-width: 550px; - } - .stat-card { - padding: 12px 14px; - } - .stat-card-value { - font-size: 1.15rem; - } -} - -/* Mobile */ -@media (max-width: 768px) { - .lagebild-hero { - padding: 120px 16px 50px; - } - .lagebild-hero h1 { - font-size: 2.5rem; - letter-spacing: 3px; - } - .hero-incident-title { - font-size: 1.2rem; - } - .hero-stats { - grid-template-columns: repeat(2, 1fr); - gap: 10px; - margin-top: 1.5rem; - } - .stat-card { - padding: 10px 12px; - gap: 10px; - } - .stat-card-icon { - width: 32px; - height: 32px; - } - .stat-card-value { - font-size: 1.1rem; - } - .stat-card-label { - font-size: 0.65rem; - } - - .control-bar .container { - flex-direction: column; - align-items: stretch; - } - .timeline-strip { - gap: 3px; - } - .timeline-day { - padding: 6px 10px; - min-width: 54px; - } - .timeline-day-num { - font-size: 0.95rem; - } - .timeline-dropdown { - padding: 8px 10px; - } - .timeline-snap-list { - grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); - gap: 4px; - } - .timeline-snap-item { - padding: 5px 10px; - font-size: 0.72rem; - } - .section-nav { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .section-nav-link { - padding: 10px 14px; - font-size: 0.82rem; - } - - .card-header { - padding: 16px 20px 0; - } - .card-body { - padding: 16px 20px 20px; - } - .card-footer { - margin: 0 20px; - padding: 16px 20px 20px; - } - .lagebild-main { - padding: 1rem 0 3rem; - } - .lagebild-main > .container { - padding: 0 12px; - } - .content-section { - margin-bottom: 2rem; - } - .factcheck-header { - flex-direction: column; - align-items: flex-start; - gap: 6px; - } - .article-card { - flex-direction: column; - gap: 8px; - } - .article-date { - width: auto; - text-align: left; - display: flex; - gap: 6px; - align-items: baseline; - } - .article-date .day { - font-size: 1rem; - } - #map-container { - height: 350px !important; - } - .fc-stats { - gap: 8px; - } - .fc-stat { - padding: 10px 14px; - min-width: 70px; - } - .status-progression { - gap: 4px; - } - - .section-karte .section-heading { - margin-bottom: 1rem; - } +/* ========================================================================== + AegisSight Lagebild Page - Dark Theme / Scroll-Narrative + ========================================================================== */ + +/* ---------- Variables ---------- */ +.lagebild-page { + --lb-bg: #0B1121; + --lb-bg-card: #151D2E; + --lb-bg-secondary: #1A2440; + --lb-border: #1E2D45; + --lb-text: #E8ECF4; + --lb-text-sec: #8896AB; + --lb-accent: #C8A851; + --lb-accent-hover: #B5923E; + --lb-success: #10B981; + --lb-warning: #F59E0B; + --lb-error: #EF4444; +} + +/* ---------- Page Base ---------- */ +.lagebild-page { + background: var(--lb-bg); + min-height: 100vh; + color: var(--lb-text); +} + +/* ---------- Navigation Dark Override ---------- */ +.lagebild-page .navbar { + background: rgba(11, 17, 33, 0.95) !important; + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid var(--lb-border) !important; + box-shadow: none !important; +} +.lagebild-page .logo-img { + background: rgba(160, 175, 200, 0.85); + padding: 4px 10px; + border-radius: 6px; +} +.lagebild-page .nav-menu a { + color: var(--lb-text) !important; +} +.lagebild-page .nav-menu a:hover { + color: var(--lb-accent) !important; +} +.lagebild-page .nav-menu a.nav-active { + color: var(--lb-accent) !important; +} +.lagebild-page .lang-toggle { + color: var(--lb-text-sec) !important; + border-color: var(--lb-border) !important; +} +.lagebild-page .lang-toggle:hover { + color: var(--lb-accent) !important; + border-color: var(--lb-accent) !important; +} +.lagebild-page .hamburger span { + background: var(--lb-text) !important; +} + +/* ---------- Footer Dark Override ---------- */ +.lagebild-page .footer { + background: #080D1A !important; + border-top: 1px solid var(--lb-border); +} +.lagebild-page .footer h4 { + color: var(--lb-accent) !important; +} +.lagebild-page .footer p, +.lagebild-page .footer a, +.lagebild-page .footer li, +.lagebild-page .footer ul li a { + color: var(--lb-text-sec) !important; +} +.lagebild-page .footer a:hover { + color: var(--lb-accent) !important; +} +.lagebild-page .copyright { + color: var(--lb-text-sec) !important; + opacity: 0.5; +} + +/* ---------- Hero Section ---------- */ +.lagebild-hero { + background: linear-gradient(135deg, #0a0f1c 0%, #111B30 50%, #0B1121 100%); + padding: 150px 20px 70px; + text-align: center; + color: #fff; + position: relative; + overflow: hidden; +} +.hero-bg-pattern { + position: absolute; + inset: 0; + background: + radial-gradient(circle at 20% 80%, rgba(200, 168, 81, 0.08) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(200, 168, 81, 0.05) 0%, transparent 50%), + radial-gradient(circle at 50% 50%, rgba(15, 114, 181, 0.06) 0%, transparent 60%); + pointer-events: none; +} +.lagebild-hero .container { + position: relative; + z-index: 1; +} + +/* Hero Badge */ +.hero-badge { + display: inline-flex; + align-items: center; + gap: 8px; + background: rgba(200, 168, 81, 0.12); + border: 1px solid rgba(200, 168, 81, 0.25); + padding: 6px 16px; + border-radius: 20px; + font-size: 0.8rem; + font-weight: 600; + letter-spacing: 1.5px; + color: var(--lb-accent); + margin-bottom: 1.5rem; +} +.badge-dot { + width: 8px; + height: 8px; + background: var(--lb-accent); + border-radius: 50%; + animation: pulse-dot 2s infinite; +} +@keyframes pulse-dot { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.4; transform: scale(0.7); } +} + +/* Hero Title */ +.lagebild-hero h1 { + font-family: 'Bebas Neue', sans-serif; + font-size: 3.5rem; + letter-spacing: 5px; + color: #fff; + margin: 0 0 0.3rem; + line-height: 1; +} +.hero-incident-title { + font-size: 1.5rem; + font-weight: 300; + color: rgba(255, 255, 255, 0.85); + margin: 0 0 0.5rem; +} +.hero-date-info { + font-size: 0.85em; + color: rgba(255, 255, 255, 0.5); + font-weight: 400; +} + +/* Hero Stat Cards */ +.hero-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 14px; + margin-top: 2rem; + max-width: 650px; + margin-left: auto; + margin-right: auto; +} +.stat-card { + display: flex; + align-items: center; + gap: 12px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.08); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + padding: 14px 16px; + border-radius: var(--radius-md, 8px); + transition: border-color 0.3s, background 0.3s; +} +.stat-card:hover { + border-color: rgba(200, 168, 81, 0.3); + background: rgba(255, 255, 255, 0.08); +} +.stat-card-icon { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(200, 168, 81, 0.1); + border-radius: var(--radius-md, 8px); + color: var(--lb-accent); + flex-shrink: 0; +} +.stat-card-icon svg { + width: 18px; + height: 18px; +} +.stat-card-content { + min-width: 0; +} +.stat-card-value { + display: block; + font-size: 1.35rem; + font-weight: 700; + color: #fff; + line-height: 1.1; +} +.stat-card-label { + display: block; + font-size: 0.72rem; + color: rgba(255, 255, 255, 0.55); + text-transform: uppercase; + letter-spacing: 0.5px; + margin-top: 2px; +} + +/* ---------- Control Bar (Sticky) ---------- */ +.control-bar { + background: var(--lb-bg-card); + border-bottom: 1px solid var(--lb-border); + padding: 0 20px; +} +.control-bar .container { + max-width: 1000px; + margin: 0 auto; +} + +/* Timeline Strip */ +.timeline-wrapper { + padding: 12px 0; + border-bottom: 1px solid var(--lb-border); +} +.timeline-strip { + display: flex; + gap: 4px; + overflow-x: auto; + scroll-behavior: smooth; + padding: 4px 0; + scrollbar-width: thin; + scrollbar-color: var(--lb-border) transparent; +} +.timeline-strip::-webkit-scrollbar { + height: 4px; +} +.timeline-strip::-webkit-scrollbar-track { + background: transparent; +} +.timeline-strip::-webkit-scrollbar-thumb { + background: var(--lb-border); + border-radius: 2px; +} +.timeline-day { + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 14px; + border-radius: var(--radius-sm, 4px); + border: 1px solid var(--lb-border); + background: transparent; + cursor: pointer; + transition: all 0.2s; + flex-shrink: 0; + min-width: 64px; + position: relative; + color: var(--lb-text-sec); + font-family: inherit; +} +.timeline-day:hover { + background: var(--lb-bg-secondary); + border-color: rgba(200, 168, 81, 0.4); +} +.timeline-day.active { + background: rgba(200, 168, 81, 0.1); + border-color: var(--lb-accent); +} +.timeline-dot { + position: absolute; + top: -4px; + right: -4px; + width: 10px; + height: 10px; + background: var(--lb-accent); + border-radius: 50%; + animation: pulse-dot 2s infinite; + border: 2px solid var(--lb-bg-card); +} +.timeline-day-num { + font-size: 1.1rem; + font-weight: 700; + line-height: 1; +} +.timeline-day.active .timeline-day-num { + color: var(--lb-accent); +} +.timeline-day-month { + font-size: 0.62rem; + text-transform: uppercase; + letter-spacing: 0.5px; + opacity: 0.7; + margin-top: 1px; +} +.timeline-day-count { + font-size: 0.68rem; + margin-top: 4px; + padding-top: 4px; + border-top: 1px solid var(--lb-border); + width: 100%; + text-align: center; + opacity: 0.6; +} +.timeline-day.active .timeline-day-count { + opacity: 1; + color: var(--lb-accent); +} +.timeline-day-updates { + font-size: 0.58rem; + opacity: 0.4; +} +.timeline-day-label { + font-size: 0.58rem; + color: var(--lb-accent); + font-weight: 600; + margin-top: 2px; +} + +/* Timeline Dropdown */ +.timeline-dropdown { + display: none; + background: var(--lb-bg-secondary); + border: 1px solid var(--lb-border); + border-top: none; + border-radius: 0 0 var(--radius-sm, 4px) var(--radius-sm, 4px); + padding: 10px 14px; + margin-top: 4px; +} +.timeline-dropdown.open { + display: block; +} +.timeline-dropdown-header { + font-size: 0.78rem; + color: var(--lb-text-sec); + margin-bottom: 8px; + font-weight: 500; +} +.timeline-snap-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); + gap: 6px; +} +.timeline-snap-item { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + border-radius: var(--radius-sm, 4px); + border: 1px solid var(--lb-border); + background: transparent; + color: var(--lb-text-sec); + font-size: 0.78rem; + cursor: pointer; + font-family: inherit; + transition: all 0.2s; +} +.timeline-snap-item:hover { + background: var(--lb-bg-card); + border-color: rgba(200, 168, 81, 0.4); + color: var(--lb-text); +} +.timeline-snap-item.active { + background: rgba(200, 168, 81, 0.1); + border-color: var(--lb-accent); + color: var(--lb-accent); +} +.timeline-snap-time { + font-weight: 600; +} +.timeline-snap-meta { + font-size: 0.7rem; + opacity: 0.7; +} + +/* ---------- Main Content ---------- */ +.lagebild-main { + padding: 2rem 0 4rem; +} +.lagebild-main > .container { + max-width: 1000px; + margin: 0 auto; + padding: 0 20px; +} + +/* ---------- Content Sections ---------- */ +.content-section { + margin-bottom: 3rem; +} + +/* ---------- Content Cards ---------- */ +.content-card { + background: var(--lb-bg-card); + border-radius: var(--radius-sm, 4px); + border: 1px solid var(--lb-border); + margin-bottom: 1.5rem; + overflow: hidden; + position: relative; +} +.content-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: var(--lb-accent); +} +.card-header { + padding: 24px 32px 0; + display: flex; + justify-content: space-between; + align-items: baseline; + flex-wrap: wrap; + gap: 8px; +} +.card-header h2 { + font-size: 1.3rem; + font-weight: 700; + color: var(--lb-text); + margin: 0; +} +.card-timestamp { + font-size: 0.85rem; + color: var(--lb-text-sec); + font-weight: 500; +} +.card-description { + font-size: 0.85rem; + color: var(--lb-text-sec); + margin: 4px 0 0; + width: 100%; +} +.card-body { + padding: 20px 32px 28px; +} +.card-footer { + padding: 0 32px 28px; + border-top: 1px solid var(--lb-border); + padding-top: 20px; + margin: 0 32px; +} +.card-footer:empty { + display: none; +} + +/* ---------- Karte Section (Full-Width) ---------- */ +.section-karte { + padding: 0; +} +.section-karte .section-heading { + margin-bottom: 1.5rem; +} +.section-karte .section-heading h2 { + font-size: 1.3rem; + font-weight: 700; + color: var(--lb-text); + margin: 0 0 4px; +} +.section-description { + font-size: 0.85rem; + color: var(--lb-text-sec); + margin: 0; +} +#map-container { + height: 500px; + background: var(--lb-bg-secondary); + border-top: 1px solid var(--lb-border); + border-bottom: 1px solid var(--lb-border); +} + +/* ---------- Lagebild Summary ---------- */ +#summary-content { + line-height: 1.85; + font-size: 1.02rem; + color: var(--lb-text); +} +#summary-content h2 { + font-size: 1.15rem; + font-weight: 700; + color: var(--lb-accent); + margin: 1.8rem 0 0.8rem; + padding-bottom: 0.4rem; + border-bottom: 2px solid var(--lb-border); +} +#summary-content h2:first-child { + margin-top: 0; +} +#summary-content h3 { + font-size: 1.05rem; + font-weight: 600; + color: var(--lb-text); + margin: 1.5rem 0 0.6rem; +} +#summary-content p { + margin: 0 0 1rem; +} +#summary-content ul { + margin: 0 0 1rem; + padding-left: 1.5rem; +} +#summary-content li { + margin-bottom: 0.4rem; + color: var(--lb-text); +} +#summary-content strong { + color: #fff; +} + +/* Citations */ +.citation-ref { + color: var(--lb-accent); + font-weight: 700; + cursor: pointer; + text-decoration: none; + font-size: 0.78em; + vertical-align: super; + line-height: 1; + padding: 0 1px; + transition: color 0.2s; +} +.citation-ref:hover { + color: var(--lb-accent-hover); + text-decoration: underline; +} + +/* Source Highlight (smooth scroll target) */ +.source-highlight { + background: rgba(200, 168, 81, 0.15) !important; + border-radius: 4px; + transition: background 1.5s ease-out; +} + +/* ---------- Article Cards ---------- */ +.article-card { + display: flex; + gap: 16px; + padding: 16px 0; + border-bottom: 1px solid var(--lb-border); +} +.article-card:last-child { border-bottom: none; } +.article-date { + flex-shrink: 0; + width: 60px; + text-align: center; +} +.article-date .day { + display: block; + font-size: 1.3rem; + font-weight: 700; + color: var(--lb-accent); + line-height: 1; +} +.article-date .month { + display: block; + font-size: 0.72rem; + color: var(--lb-text-sec); + text-transform: uppercase; + letter-spacing: 0.5px; +} +.article-info { + flex: 1; + min-width: 0; +} +.article-headline { + font-size: 0.95rem; + font-weight: 600; + color: var(--lb-text); + margin: 0 0 6px; + line-height: 1.4; +} +.article-headline a { + color: inherit; + text-decoration: none; +} +.article-headline a:hover { + color: var(--lb-accent); +} +.article-meta { + display: flex; + align-items: center; + gap: 12px; + font-size: 0.8rem; + color: var(--lb-text-sec); + flex-wrap: wrap; +} +.article-source { + font-weight: 600; + color: var(--lb-text); + display: inline-flex; + align-items: center; + gap: 4px; +} +.article-favicon { + width: 16px; + height: 16px; + border-radius: 2px; + vertical-align: middle; +} +.article-lang { + background: var(--lb-bg-secondary); + border: 1px solid var(--lb-border); + padding: 1px 6px; + border-radius: 3px; + font-size: 0.7rem; + text-transform: uppercase; + color: var(--lb-text-sec); +} +.article-link { + color: var(--lb-accent) !important; + text-decoration: none !important; + font-size: 0.78rem; + display: inline-flex; + align-items: center; + gap: 3px; +} +.article-link:hover { + text-decoration: underline !important; +} + +/* Show All Button */ +.show-all-wrapper { + text-align: center; + padding: 24px 0 8px; +} +.show-all-btn { + display: inline-block; + padding: 10px 28px; + background: transparent; + border: 1px solid var(--lb-accent); + color: var(--lb-accent); + font-size: 0.88rem; + font-weight: 600; + border-radius: var(--radius-sm, 4px); + cursor: pointer; + transition: all 0.2s; + font-family: inherit; +} +.show-all-btn:hover { + background: rgba(200, 168, 81, 0.1); +} + +/* ---------- Map ---------- */ +.lagebild-page .map-legend { + background: var(--lb-bg-card) !important; + color: var(--lb-text) !important; + border: 1px solid var(--lb-border) !important; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important; +} +/* Leaflet controls dark */ +.lagebild-page .leaflet-control-zoom a { + background: var(--lb-bg-card) !important; + color: var(--lb-text) !important; + border-color: var(--lb-border) !important; +} +.lagebild-page .leaflet-control-zoom a:hover { + background: var(--lb-bg-secondary) !important; +} +.lagebild-page .leaflet-control-attribution { + background: rgba(11, 17, 33, 0.8) !important; + color: var(--lb-text-sec) !important; +} +.lagebild-page .leaflet-control-attribution a { + color: var(--lb-accent) !important; +} + +/* ---------- Fact Check Cards ---------- */ +.fc-stats { + display: flex; + gap: 12px; + margin-bottom: 24px; + flex-wrap: wrap; +} +.fc-stat { + background: var(--lb-bg-secondary); + border-radius: var(--radius-sm, 4px); + padding: 14px 20px; + text-align: center; + min-width: 80px; + border: 1px solid var(--lb-border); +} +.fc-stat.confirmed { + background: rgba(16, 185, 129, 0.08); + border-color: rgba(16, 185, 129, 0.2); +} +.fc-stat.unconfirmed { + background: rgba(245, 158, 11, 0.08); + border-color: rgba(245, 158, 11, 0.2); +} +.fc-stat.contradicted { + background: rgba(239, 68, 68, 0.08); + border-color: rgba(239, 68, 68, 0.2); +} +.fc-stat-num { + display: block; + font-size: 1.6rem; + font-weight: 800; + color: var(--lb-text); +} +.fc-stat.confirmed .fc-stat-num { color: var(--lb-success); } +.fc-stat.unconfirmed .fc-stat-num { color: var(--lb-warning); } +.fc-stat.contradicted .fc-stat-num { color: var(--lb-error); } +.fc-stat-label { + font-size: 0.75rem; + color: var(--lb-text-sec); + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; +} + +.factcheck-card { + background: var(--lb-bg-secondary); + border-radius: var(--radius-sm, 4px); + padding: 20px; + margin-bottom: 12px; + border-left: 4px solid var(--lb-border); + transition: transform 0.2s, box-shadow 0.2s; +} +.factcheck-card:hover { + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); +} +.factcheck-card.highlight { + background: rgba(200, 168, 81, 0.06); + border-left-color: var(--lb-accent); + box-shadow: 0 2px 12px rgba(200, 168, 81, 0.1); +} +.factcheck-card[data-status="confirmed"], +.factcheck-card[data-status="established"] { + border-left-color: var(--lb-success); +} +.factcheck-card[data-status="unconfirmed"], +.factcheck-card[data-status="unverified"] { + border-left-color: var(--lb-warning); +} +.factcheck-card[data-status="contradicted"], +.factcheck-card[data-status="disputed"] { + border-left-color: var(--lb-error); +} +.factcheck-card[data-status="developing"] { + border-left-color: #3b82f6; +} +.factcheck-card[data-status="false"] { + border-left-color: #dc2626; +} + +.factcheck-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 8px; +} +.factcheck-sources { + font-size: 0.8rem; + color: var(--lb-text-sec); +} +.factcheck-claim { + font-size: 0.95rem; + color: var(--lb-text); + margin: 0 0 4px; + line-height: 1.5; +} + +/* Status Badges */ +.status-badge { + display: inline-block; + padding: 3px 10px; + border-radius: var(--radius-sm, 4px); + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; +} +.status-badge.confirmed, .status-badge.established { + background: rgba(16, 185, 129, 0.15); + color: #34d399; +} +.status-badge.unconfirmed, .status-badge.unverified { + background: rgba(245, 158, 11, 0.15); + color: #fbbf24; +} +.status-badge.contradicted, .status-badge.disputed { + background: rgba(239, 68, 68, 0.15); + color: #f87171; +} +.status-badge.developing { + background: rgba(59, 130, 246, 0.15); + color: #60a5fa; +} +.status-badge.false { + background: rgba(220, 38, 38, 0.15); + color: #f87171; +} + +/* Status Progression */ +.status-progression { + display: flex; + align-items: center; + gap: 6px; + margin-top: 10px; + padding-top: 10px; + border-top: 1px solid var(--lb-border); + font-size: 0.78rem; + flex-wrap: wrap; +} +.progression-label { + color: var(--lb-text-sec); + font-weight: 500; + margin-right: 4px; +} +.progression-arrow { + color: var(--lb-accent); + font-size: 1rem; +} +.progression-step { + display: flex; + align-items: center; + gap: 4px; +} +.progression-time { + color: var(--lb-text-sec); + font-size: 0.7rem; +} + +/* Evidence block */ +.factcheck-evidence { + font-size: 0.82rem; + color: var(--lb-text-sec); + margin: 10px 0 0; + line-height: 1.6; + padding: 10px 14px; + background: rgba(0, 0, 0, 0.2); + border-radius: var(--radius-sm, 4px); + border: 1px solid var(--lb-border); +} +.factcheck-evidence strong { + color: var(--lb-text); +} +.factcheck-evidence a { + color: var(--lb-accent) !important; + word-break: break-all; +} + +/* ---------- Floating CTA Pill ---------- */ +.floating-cta { + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%) translateY(100px); + display: flex; + align-items: center; + gap: 16px; + background: rgba(21, 29, 46, 0.92); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid rgba(200, 168, 81, 0.25); + border-radius: 50px; + padding: 10px 14px 10px 24px; + z-index: 1000; + opacity: 0; + transition: opacity 0.4s, transform 0.4s; + pointer-events: none; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); +} +.floating-cta.visible { + opacity: 1; + transform: translateX(-50%) translateY(0); + pointer-events: auto; +} +.floating-cta.dismissed { + opacity: 0; + transform: translateX(-50%) translateY(100px); + pointer-events: none; +} +.floating-cta-text { + font-size: 0.88rem; + color: var(--lb-text-sec); + font-weight: 500; + white-space: nowrap; +} +.floating-cta-btn { + display: inline-block; + background: var(--lb-accent); + color: #0a0f1c; + padding: 8px 20px; + border-radius: 50px; + font-weight: 700; + text-decoration: none; + font-size: 0.85rem; + white-space: nowrap; + transition: background 0.2s, transform 0.2s; +} +.floating-cta-btn:hover { + background: var(--lb-accent-hover); + transform: scale(1.03); +} +.floating-cta-close { + background: none; + border: none; + color: var(--lb-text-sec); + font-size: 1.3rem; + cursor: pointer; + padding: 0 4px; + line-height: 1; + transition: color 0.2s; + font-family: inherit; +} +.floating-cta-close:hover { + color: var(--lb-text); +} + +@media (max-width: 768px) { + .floating-cta { + left: 12px; + right: 12px; + transform: translateX(0) translateY(100px); + border-radius: 16px; + gap: 10px; + padding: 10px 12px 10px 16px; + } + .floating-cta.visible { + transform: translateX(0) translateY(0); + } + .floating-cta.dismissed { + transform: translateX(0) translateY(100px); + } + .floating-cta-text { + font-size: 0.8rem; + white-space: normal; + } + .floating-cta-btn { + font-size: 0.8rem; + padding: 7px 14px; + flex-shrink: 0; + } +} + +/* ---------- Loading Skeleton ---------- */ +.loading-skeleton { padding: 20px 0; } +.skeleton-line { + height: 16px; + background: linear-gradient(90deg, var(--lb-bg-secondary) 25%, var(--lb-border) 50%, var(--lb-bg-secondary) 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; + border-radius: var(--radius-sm, 4px); + margin-bottom: 12px; +} +.skeleton-line.short { width: 60%; } +@keyframes shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +/* Error */ +.lagebild-error { + text-align: center; + padding: 40px 20px; + color: var(--lb-text-sec); +} + +/* ---------- Scroll Reveal ---------- */ +.reveal { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.4s ease-out, transform 0.4s ease-out; +} +.reveal.revealed { + opacity: 1; + transform: translateY(0); +} + +/* ---------- Responsive ---------- */ + +/* Tablet */ +@media (max-width: 1024px) { + .hero-stats { + max-width: 550px; + } + .stat-card { + padding: 12px 14px; + } + .stat-card-value { + font-size: 1.15rem; + } +} + +/* Mobile */ +@media (max-width: 768px) { + .lagebild-hero { + padding: 120px 16px 50px; + } + .lagebild-hero h1 { + font-size: 2.5rem; + letter-spacing: 3px; + } + .hero-incident-title { + font-size: 1.2rem; + } + .hero-stats { + grid-template-columns: repeat(2, 1fr); + gap: 10px; + margin-top: 1.5rem; + } + .stat-card { + padding: 10px 12px; + gap: 10px; + } + .stat-card-icon { + width: 32px; + height: 32px; + } + .stat-card-value { + font-size: 1.1rem; + } + .stat-card-label { + font-size: 0.65rem; + } + + .control-bar .container { + flex-direction: column; + align-items: stretch; + } + .timeline-strip { + gap: 3px; + } + .timeline-day { + padding: 6px 10px; + min-width: 54px; + } + .timeline-day-num { + font-size: 0.95rem; + } + .timeline-dropdown { + padding: 8px 10px; + } + .timeline-snap-list { + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + gap: 4px; + } + .timeline-snap-item { + padding: 5px 10px; + font-size: 0.72rem; + } + .section-nav { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + .section-nav-link { + padding: 10px 14px; + font-size: 0.82rem; + } + + .card-header { + padding: 16px 20px 0; + } + .card-body { + padding: 16px 20px 20px; + } + .card-footer { + margin: 0 20px; + padding: 16px 20px 20px; + } + .lagebild-main { + padding: 1rem 0 3rem; + } + .lagebild-main > .container { + padding: 0 12px; + } + .content-section { + margin-bottom: 2rem; + } + .factcheck-header { + flex-direction: column; + align-items: flex-start; + gap: 6px; + } + .article-card { + flex-direction: column; + gap: 8px; + } + .article-date { + width: auto; + text-align: left; + display: flex; + gap: 6px; + align-items: baseline; + } + .article-date .day { + font-size: 1rem; + } + #map-container { + height: 350px !important; + } + .fc-stats { + gap: 8px; + } + .fc-stat { + padding: 10px 14px; + min-width: 70px; + } + .status-progression { + gap: 4px; + } + + .section-karte .section-heading { + margin-bottom: 1rem; + } } \ No newline at end of file diff --git a/lagebild/lagebild.js b/lagebild/lagebild.js index cae9afa..a71bb65 100644 --- a/lagebild/lagebild.js +++ b/lagebild/lagebild.js @@ -1,766 +1,703 @@ -/** - * AegisSight Lagebild Page - Dark Theme / Scroll-Narrative - * Count-Up, Timeline, Scroll-Spy, Scroll-Reveal, Favicons - */ - -/** Feste Zeitzone fuer alle Anzeigen - NIEMALS aendern. */ -var TIMEZONE = 'Europe/Berlin'; - -var Lagebild = { - data: null, - allSnapshots: {}, - currentView: null, - map: null, - timelineGroups: null, - articlesShowAll: false, - - /* ===== Inline SVG Icons ===== */ - icons: { - clock: '', - fileText: '', - globe: '', - shieldCheck: '', - externalLink: '' - }, - - async init() { - if (typeof initTranslations === 'function') { - try { initTranslations(); } catch(e) {} - } - try { - var resp = await fetch('data/current.json?t=' + Date.now()); - if (!resp.ok) throw new Error('HTTP ' + resp.status); - this.data = await resp.json(); - this.currentView = { - summary: this.data.current_lagebild.summary_markdown, - sources_json: this.data.current_lagebild.sources_json, - updated_at: this.data.current_lagebild.updated_at || this.data.generated_at, - articles: this.data.articles, - fact_checks: this.data.fact_checks - }; - this.render(); - this.initScrollSpy(); - this.initLangToggle(); - this.initScrollReveal(); - this.initFloatingCta(); - this.initStickyDetect(); - } catch (e) { - console.error('Lagebild laden fehlgeschlagen:', e); - this.showError(); - } - }, - - render: function() { - this.renderHero(); - this.renderTimeline(); - this.renderSectionBadges(); - this.renderCurrentView(); - }, - - /* ===== HERO ===== */ - renderHero: function() { - var d = this.data; - document.getElementById('incident-title').innerHTML = - this.esc(this.fixUmlauts(d.incident.title)) + - ' \u2013 Stand: ' + this.fmtDateOnly(d.generated_at) + ', ' + this.fmtTimeOnly(d.generated_at) + ' Uhr'; - - // Stat Cards (3: Artikel, Quellen, Faktenchecks) - var statsHtml = ''; - statsHtml += this.statCard(this.icons.fileText, '0', 'Artikel'); - statsHtml += this.statCard(this.icons.globe, '0', 'Quellen'); - statsHtml += this.statCard(this.icons.shieldCheck, '0', 'Faktenchecks'); - document.getElementById('hero-stats').innerHTML = statsHtml; - - // Start count-up animations - var self = this; - requestAnimationFrame(function() { - var els = document.querySelectorAll('.count-up'); - for (var i = 0; i < els.length; i++) { - self.animateCount(els[i], parseInt(els[i].getAttribute('data-target')), 800); - } - }); - }, - - statCard: function(icon, value, label) { - return '
' + - '
' + icon + '
' + - '
' + - '' + value + '' + - '' + label + '' + - '
'; - }, - - /* ===== COUNT-UP ANIMATION ===== */ - animateCount: function(element, target, duration) { - var start = performance.now(); - function update(now) { - var elapsed = now - start; - var progress = Math.min(elapsed / duration, 1); - var eased = 1 - Math.pow(1 - progress, 3); // easeOutCubic - var current = Math.round(target * eased); - element.textContent = current.toLocaleString('de-DE'); - if (progress < 1) { - requestAnimationFrame(update); - } - } - requestAnimationFrame(update); - }, - - /* ===== TIMELINE STRIP ===== */ - renderTimeline: function() { - var snaps = this.data.available_snapshots || []; - var current = { - id: 'current', - article_count: this.data.incident.article_count, - fact_check_count: this.data.incident.factcheck_count, - created_at: this.data.generated_at - }; - var all = [current].concat(snaps); - - // Group by date - var groups = {}; - for (var i = 0; i < all.length; i++) { - var s = all[i]; - var dateKey = this.toDateKey(s.created_at); - if (!groups[dateKey]) groups[dateKey] = []; - groups[dateKey].push(s); - } - - // Sort each group descending (newest first) - for (var dk in groups) { - groups[dk].sort(function(a, b) { - return new Date(Lagebild.toUTC(b.created_at)) - new Date(Lagebild.toUTC(a.created_at)); - }); - } - - this.timelineGroups = groups; - var dates = Object.keys(groups).sort(); - var strip = document.getElementById('timeline-strip'); - var h = ''; - - for (var j = 0; j < dates.length; j++) { - var date = dates[j]; - var daySnaps = groups[date]; - var latest = daySnaps[0]; - var isActive = (j === dates.length - 1); - var d = new Date(date + 'T12:00:00Z'); - - h += ''; - } - - strip.innerHTML = h; - - // Scroll to active day - var active = strip.querySelector('.timeline-day.active'); - if (active) { - setTimeout(function() { - active.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' }); - }, 150); - } - - // Click handler for day buttons - var self = this; - strip.addEventListener('click', function(e) { - var btn = e.target.closest('.timeline-day'); - if (!btn) return; - - var allDays = strip.querySelectorAll('.timeline-day'); - for (var k = 0; k < allDays.length; k++) allDays[k].classList.remove('active'); - btn.classList.add('active'); - - var dateKey = btn.getAttribute('data-date'); - var snapId = btn.getAttribute('data-snapshot-id'); - - // Show dropdown for this day - self.showTimelineDropdown(dateKey, snapId); - - // Load latest snapshot - if (snapId === 'current') { - self.currentView = { - summary: self.data.current_lagebild.summary_markdown, - sources_json: self.data.current_lagebild.sources_json, - updated_at: self.data.current_lagebild.updated_at || self.data.generated_at, - articles: self.data.articles, - fact_checks: self.data.fact_checks - }; - self.renderCurrentView(); - } else { - self.loadSnapshot(parseInt(snapId)); - } - }); - - // Click handler for dropdown snapshot items (delegated) - var dropdown = document.getElementById('timeline-dropdown'); - dropdown.addEventListener('click', function(e) { - var item = e.target.closest('.timeline-snap-item'); - if (!item) return; - - var items = dropdown.querySelectorAll('.timeline-snap-item'); - for (var k = 0; k < items.length; k++) items[k].classList.remove('active'); - item.classList.add('active'); - - var snapId = item.getAttribute('data-snapshot-id'); - if (snapId === 'current') { - self.currentView = { - summary: self.data.current_lagebild.summary_markdown, - sources_json: self.data.current_lagebild.sources_json, - updated_at: self.data.current_lagebild.updated_at || self.data.generated_at, - articles: self.data.articles, - fact_checks: self.data.fact_checks - }; - self.renderCurrentView(); - } else { - self.loadSnapshot(parseInt(snapId)); - } - }); - - // Show dropdown for newest day by default - var newestDate = dates[dates.length - 1]; - if (newestDate && groups[newestDate].length > 1) { - this.showTimelineDropdown(newestDate, groups[newestDate][0].id); - } - }, - - showTimelineDropdown: function(dateKey, activeSnapId) { - var dropdown = document.getElementById('timeline-dropdown'); - var snaps = this.timelineGroups[dateKey]; - - if (!snaps || snaps.length <= 1) { - dropdown.classList.remove('open'); - dropdown.innerHTML = ''; - return; - } - - var d = new Date(dateKey + 'T12:00:00Z'); - var dateLabel = d.toLocaleDateString('de-DE', { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' }); - - var h = '
' + dateLabel + ' \u2013 ' + snaps.length + ' Updates
'; - h += '
'; - for (var i = 0; i < snaps.length; i++) { - var snap = snaps[i]; - var isActive = (String(snap.id) === String(activeSnapId)); - h += ''; - } - h += '
'; - - dropdown.innerHTML = h; - dropdown.classList.add('open'); - }, - - toDateKey: function(iso) { - if (!iso) return ''; - var d = new Date(this.toUTC(iso)); - return d.toLocaleDateString('en-CA', { timeZone: TIMEZONE }); - }, - - /* ===== SECTION BADGES ===== */ - renderSectionBadges: function() { - var artikelBadge = document.getElementById('badge-artikel'); - var fcBadge = document.getElementById('badge-faktenchecks'); - if (artikelBadge) artikelBadge.textContent = this.data.incident.article_count; - if (fcBadge) fcBadge.textContent = this.data.incident.factcheck_count; - }, - - /* ===== SNAPSHOT LOADING ===== */ - loadSnapshot: async function(id) { - if (this.allSnapshots[id]) { - this.currentView = this.allSnapshots[id]; - this.renderCurrentView(); - return; - } - try { - var resp = await fetch('data/snapshot-' + id + '.json'); - if (!resp.ok) throw new Error('HTTP ' + resp.status); - var sd = await resp.json(); - var sj = sd.sources_json; - if (typeof sj === 'string') { try { sj = JSON.parse(sj); } catch(e) { sj = []; } } - this.currentView = { - summary: sd.summary, - sources_json: sj || [], - updated_at: sd.created_at, - articles: this.data.articles, - fact_checks: this.data.fact_checks - }; - this.allSnapshots[id] = this.currentView; - this.renderCurrentView(); - } catch (e) { console.error('Snapshot Fehler:', e); } - }, - - renderCurrentView: function() { - this.renderSummary(); - this.renderInlineSources(); - this.renderArtikelSection(); - this.renderFactChecksTab(); - if (!this.map) this.renderMap(); - }, - - /* ===== SECTION: LAGEBILD ===== */ - renderSummary: function() { - var v = this.currentView; - document.getElementById('lagebild-timestamp').textContent = this.fmtDT(v.updated_at); - var md = this.fixUmlauts(v.summary || ''); - var html = this.mdToHtml(md); - - // Build source lookup for citation links - var srcMap = {}; - var sources = v.sources_json || []; - for (var i = 0; i < sources.length; i++) { - srcMap[sources[i].nr] = sources[i]; - } - var self = this; - html = html.replace(/\[(\d+)\]/g, function(match, nr) { - var src = srcMap[nr]; - if (src && src.url) { - return '[' + nr + ']'; - } - return '[' + nr + ']'; - }); - - document.getElementById('summary-content').innerHTML = html; - }, - - renderInlineSources: function() { - document.getElementById('inline-sources').innerHTML = ''; - }, - - /* ===== SECTION: ARTIKEL ===== */ - renderArtikelSection: function() { - var articles = this.currentView.articles || []; - var limit = 20; - var showAll = this.articlesShowAll || articles.length <= limit; - var displayArticles = showAll ? articles : articles.slice(0, limit); - - document.getElementById('articles-heading').textContent = 'Artikel (' + articles.length + ')'; - - var ah = ''; - for (var i = 0; i < displayArticles.length; i++) { - var a = displayArticles[i]; - var dt = a.published_at || a.collected_at || ''; - var dObj = dt ? new Date(this.toUTC(dt)) : null; - var hl = this.fixUmlauts(a.headline_de || a.headline || ''); - var domain = this.extractDomain(a.source_url); - - ah += '
'; - ah += '
'; - } - - if (!showAll) { - ah += '
'; - ah += ''; - ah += '
'; - } - - document.getElementById('articles-content').innerHTML = ah; - - if (!showAll) { - var self = this; - document.getElementById('show-all-articles').addEventListener('click', function() { - self.articlesShowAll = true; - self.renderArtikelSection(); - }); - } - }, - - /* ===== SECTION: KARTE ===== */ - renderMap: function() { - if (this.map) { this.map.remove(); this.map = null; } - this.map = L.map('map-container').setView([33.0, 48.0], 5); - - // Dark map tiles (CartoDB Dark Matter) - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { - attribution: '© OpenStreetMap © CARTO', - maxZoom: 19, - subdomains: 'abcd' - }).addTo(this.map); - - var redIcon = L.icon({ - iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', - shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', - iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] - }); - var blueIcon = L.icon({ - iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png', - shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', - iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] - }); - var orangeIcon = L.icon({ - iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-orange.png', - shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', - iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] - }); - - var locs = [ - {n:'Teheran, Iran',lat:35.6892,lng:51.3890,d:'Hauptziel der US-israelischen Luftschl\u00e4ge. \u00dcber 1.000 Tote nach f\u00fcnf Tagen Krieg.',ic:redIcon}, - {n:'Beirut, Libanon',lat:33.8938,lng:35.5018,d:'Gleichzeitige US-israelische Luftschl\u00e4ge auf Beirut und Teheran [6].',ic:redIcon}, - {n:'Juffair, Bahrain',lat:26.2235,lng:50.6001,d:'US-Marinebasis \u2013 Ziel iranischer Vergeltungsraketen [3].',ic:orangeIcon}, - {n:'Al Udeid, Katar',lat:25.1173,lng:51.3150,d:'US-Luftwaffenst\u00fctzpunkt \u2013 Ziel iranischer Gegenangriffe.',ic:orangeIcon}, - {n:'Tel Aviv, Israel',lat:32.0853,lng:34.7818,d:'Operationsbasis f\u00fcr israelische Angriffe auf den Iran.',ic:blueIcon}, - {n:'Ankara, T\u00fcrkei',lat:39.9334,lng:32.8597,d:'NATO vermutet iranischen Raketenbeschuss auf T\u00fcrkei [10]. Keine NATO-Beteiligung geplant.',ic:orangeIcon}, - {n:'Bagdad, Irak',lat:33.3152,lng:44.3661,d:'Lage im Irak als Faktor im Kriegsverlauf [2].',ic:blueIcon}, - {n:'Persischer Golf',lat:27.0,lng:51.5,d:'Iran greift Energieinfrastruktur und diplomatische Einrichtungen in der Golfregion an.',ic:orangeIcon}, - {n:'Dubai, VAE',lat:25.2048,lng:55.2708,d:'US-Botschaft in Dubai durch iranischen Angriff getroffen.',ic:redIcon}, - {n:'Washington D.C., USA',lat:38.9072,lng:-77.0369,d:'War-Powers-Abstimmung im Senat gescheitert (47:53). Trump verteidigt Iran-Krieg vor Kongress.',ic:blueIcon} - ]; - - for (var i = 0; i < locs.length; i++) { - var l = locs[i]; - L.marker([l.lat, l.lng], { icon: l.ic }) - .addTo(this.map) - .bindPopup('' + l.n + '
' + l.d + ''); - } - - // Dark legend - var legend = L.control({ position: 'bottomright' }); - legend.onAdd = function() { - var div = L.DomUtil.create('div', 'map-legend'); - div.style.cssText = 'background:#151D2E;padding:10px 14px;border-radius:4px;border:1px solid #1E2D45;box-shadow:0 2px 8px rgba(0,0,0,0.3);font-size:0.8rem;line-height:1.8;color:#E8ECF4;'; - div.innerHTML = 'Legende
' - + ' Angegriffene Ziele
' - + ' Vergeltung / Eskalation
' - + ' Strategische Akteure'; - return div; - }; - legend.addTo(this.map); - - // Dark popup styling - if (!document.getElementById('leaflet-dark-style')) { - var style = document.createElement('style'); - style.id = 'leaflet-dark-style'; - style.textContent = '.lagebild-page .leaflet-popup-content-wrapper{background:#151D2E;color:#E8ECF4;border:1px solid #1E2D45;border-radius:4px;box-shadow:0 4px 16px rgba(0,0,0,0.4);}.lagebild-page .leaflet-popup-tip{background:#151D2E;}'; - document.head.appendChild(style); - } - - setTimeout(function() { if (Lagebild.map) Lagebild.map.invalidateSize(); }, 300); - }, - - /* ===== SECTION: FAKTENCHECKS ===== */ - renderFactChecksTab: function() { - var checks = this.currentView.fact_checks || []; - if (!checks.length) { - document.getElementById('factchecks-content').innerHTML = '

Keine Faktenchecks verf\u00fcgbar.

'; - return; - } - - var stats = { confirmed: 0, unconfirmed: 0, contradicted: 0, developing: 0, established: 0, disputed: 0 }; - for (var k = 0; k < checks.length; k++) { - var st = checks[k].status || 'developing'; - if (stats[st] !== undefined) stats[st]++; - } - - var h = '
'; - h += '
' + checks.length + 'Gesamt
'; - h += '
' + (stats.confirmed + stats.established) + 'Best\u00e4tigt
'; - h += '
' + (stats.unconfirmed + stats.developing) + 'Offen
'; - if (stats.contradicted + stats.disputed > 0) - h += '
' + (stats.contradicted + stats.disputed) + 'Widerlegt
'; - h += '
'; - - checks = checks.slice().sort(function(a, b) { - var aH = (a.status_history || []).length; - var bH = (b.status_history || []).length; - if (bH !== aH) return bH - aH; - return (b.sources_count || 0) - (a.sources_count || 0); - }); - - for (var i = 0; i < checks.length; i++) { - var fc = checks[i]; - var status = fc.status || 'developing'; - var hasProg = fc.status_history && fc.status_history.length > 1; - - h += '
'; - h += '
'; - h += '' + this.stLabel(status) + ''; - h += '' + (fc.sources_count || 0) + ' unabh\u00e4ngige Quellen'; - h += '
'; - h += '

' + this.esc(this.fixUmlauts(fc.claim || '')) + '

'; - - if (fc.evidence) { - var ev = this.fixUmlauts(fc.evidence); - ev = this.esc(ev).replace(/(https?:\/\/[^\s,)]+)/g, '$1'); - h += '
Evidenz: ' + ev + '
'; - } - - if (hasProg) { - h += '
'; - h += 'Verlauf:'; - for (var j = 0; j < fc.status_history.length; j++) { - var step = fc.status_history[j]; - if (j > 0) h += ''; - h += ''; - h += '' + this.stLabel(step.status) + ''; - if (step.at) h += '' + this.fmtShort(step.at) + ''; - h += ''; - } - h += '
'; - } - h += '
'; - } - document.getElementById('factchecks-content').innerHTML = h; - }, - - /* ===== SCROLL-SPY (Section Navigation) ===== */ - initScrollSpy: function() { - var navLinks = document.querySelectorAll('.section-nav-link'); - var sections = document.querySelectorAll('.content-section'); - var controlBar = document.getElementById('control-bar'); - - // Smooth scroll on click - for (var i = 0; i < navLinks.length; i++) { - navLinks[i].addEventListener('click', function(e) { - e.preventDefault(); - var targetId = this.getAttribute('href').substring(1); - var target = document.getElementById(targetId); - if (target) { - var offset = controlBar.offsetHeight + 20; - var navbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--navbar-height')) || 72; - var top = target.getBoundingClientRect().top + window.scrollY - offset - navbarH; - window.scrollTo({ top: top, behavior: 'smooth' }); - } - }); - } - - // IntersectionObserver for scroll-spy - if (!('IntersectionObserver' in window)) return; - - var observer = new IntersectionObserver(function(entries) { - entries.forEach(function(entry) { - if (entry.isIntersecting) { - var id = entry.target.id; - for (var j = 0; j < navLinks.length; j++) { - navLinks[j].classList.remove('active'); - if (navLinks[j].getAttribute('href') === '#' + id) { - navLinks[j].classList.add('active'); - } - } - } - }); - }, { rootMargin: '-20% 0px -70% 0px' }); - - for (var i = 0; i < sections.length; i++) { - observer.observe(sections[i]); - } - }, - - /* ===== STICKY DETECTION ===== */ - initStickyDetect: function() { - var controlBar = document.getElementById('control-bar'); - if (!('IntersectionObserver' in window)) return; - - // Sentinel element before control-bar - var sentinel = document.createElement('div'); - sentinel.style.height = '1px'; - sentinel.style.visibility = 'hidden'; - controlBar.parentNode.insertBefore(sentinel, controlBar); - - var observer = new IntersectionObserver(function(entries) { - entries.forEach(function(entry) { - controlBar.classList.toggle('stuck', !entry.isIntersecting); - }); - }, { threshold: 0 }); - - observer.observe(sentinel); - }, - - initLangToggle: function() { - var btn = document.querySelector('.lang-toggle'); - if (!btn) return; - btn.addEventListener('click', function(e) { - e.preventDefault(); - if (typeof switchLanguage === 'function') { - var cur = (typeof getCurrentLanguage === 'function') ? getCurrentLanguage() : 'de'; - switchLanguage(cur === 'de' ? 'en' : 'de'); - } - }); - }, - - /* ===== FLOATING CTA ===== */ - initFloatingCta: function() { - var cta = document.createElement('div'); - cta.className = 'floating-cta'; - cta.innerHTML = 'AegisSight Monitor f\u00fcr Ihre Organisation' - + 'Kontakt aufnehmen \u2192' - + ''; - document.body.appendChild(cta); - - // Show after scrolling past hero - var shown = false; - window.addEventListener('scroll', function() { - if (shown) return; - if (window.scrollY > 400) { - cta.classList.add('visible'); - shown = true; - } - }); - - // Close button - cta.querySelector('.floating-cta-close').addEventListener('click', function(e) { - e.preventDefault(); - cta.classList.add('dismissed'); - setTimeout(function() { cta.classList.remove('dismissed'); }, 60000); - }); - }, - - /* ===== SCROLL REVEAL ===== */ - initScrollReveal: function() { - var cards = document.querySelectorAll('.content-card, .section-karte'); - if (!('IntersectionObserver' in window)) { - for (var i = 0; i < cards.length; i++) cards[i].classList.add('revealed'); - return; - } - var observer = new IntersectionObserver(function(entries) { - entries.forEach(function(entry) { - if (entry.isIntersecting) { - entry.target.classList.add('revealed'); - observer.unobserve(entry.target); - } - }); - }, { threshold: 0.1 }); - - for (var i = 0; i < cards.length; i++) { - cards[i].classList.add('reveal'); - observer.observe(cards[i]); - } - }, - - /* ===== HILFSFUNKTIONEN ===== */ - extractDomain: function(url) { - if (!url) return null; - try { return new URL(url).hostname; } catch(e) { return null; } - }, - - fixUmlauts: function(text) { - if (!text) return text; - var skip = ['Israel','Israelis','Jazeera','Euronews','Reuters','Februar', - 'Juffair','abgefeuert','Feindseligkeiten','Gegenschlag','neuesten', - 'auszuweiten','befeuert','feuerte','Feuer','feuer','neue','neuen', - 'neuer','neues','Neue','Aero','aero','Manoeuvre','Dauerfeuer']; - var ph = []; var c = 0; - for (var i = 0; i < skip.length; i++) { - var re = new RegExp('\\b' + skip[i] + '\\b', 'g'); - text = text.replace(re, function(m) { ph.push(m); return '##S' + (c++) + '##'; }); - } - text = text.replace(/ae/g, '\u00e4').replace(/Ae/g, '\u00c4'); - text = text.replace(/oe/g, '\u00f6').replace(/Oe/g, '\u00d6'); - text = text.replace(/ue/g, '\u00fc').replace(/Ue/g, '\u00dc'); - text = text.replace(/##S(\d+)##/g, function(m, idx) { return ph[parseInt(idx)]; }); - return text; - }, - - stLabel: function(s) { - return { confirmed: 'Best\u00e4tigt', unconfirmed: 'Unbest\u00e4tigt', established: 'Gesichert', - unverified: 'Nicht verifiziert', contradicted: 'Widerlegt', disputed: 'Umstritten', - developing: 'In Entwicklung', 'false': 'Falsch' }[s] || s; - }, - - mdToHtml: function(md) { - if (!md) return ''; - var lines = md.split('\n'), html = '', inList = false; - for (var i = 0; i < lines.length; i++) { - var l = lines[i]; - if (/^### (.+)$/.test(l)) { if (inList) { html += ''; inList = false; } html += '

' + l.replace(/^### /, '') + '

'; continue; } - if (/^## (.+)$/.test(l)) { if (inList) { html += ''; inList = false; } html += '

' + l.replace(/^## /, '') + '

'; continue; } - if (/^[-*] (.+)$/.test(l)) { if (!inList) { html += ''; inList = false; } - if (l.trim() === '') continue; - html += '

' + l + '

'; - } - if (inList) html += ''; - html = html.replace(/\*\*(.+?)\*\*/g, '$1'); - html = html.replace(/\*(.+?)\*/g, '$1'); - return html; - }, - - esc: function(s) { if (!s) return ''; var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }, - - toUTC: function(s) { - if (!s) return s; - s = String(s).trim(); - if (/[Zz]$/.test(s) || /[+-]\d{2}:?\d{2}$/.test(s)) return s; - return s.replace(' ', 'T') + 'Z'; - }, - - fmtDT: function(iso) { - if (!iso) return ''; - try { - var d = new Date(this.toUTC(iso)); - if (isNaN(d.getTime())) return iso; - var opts = { timeZone: TIMEZONE, weekday: 'long', day: 'numeric', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }; - var parts = new Intl.DateTimeFormat('de-DE', opts).formatToParts(d); - var p = {}; - parts.forEach(function(x) { p[x.type] = x.value; }); - return p.weekday + ', ' + p.day + '. ' + p.month + ' ' + p.year - + ' um ' + p.hour + ':' + p.minute + ' Uhr'; - } catch(e) { return iso; } - }, - - fmtDateOnly: function(iso) { - if (!iso) return ''; - try { - var d = new Date(this.toUTC(iso)); - if (isNaN(d.getTime())) return iso; - return d.toLocaleDateString('de-DE', { day: 'numeric', month: 'short', year: 'numeric', timeZone: TIMEZONE }); - } catch(e) { return iso; } - }, - - fmtTimeOnly: function(iso) { - if (!iso) return ''; - try { - var d = new Date(this.toUTC(iso)); - if (isNaN(d.getTime())) return iso; - return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', timeZone: TIMEZONE }); - } catch(e) { return iso; } - }, - - fmtShort: function(iso) { - if (!iso) return ''; - try { return new Date(this.toUTC(iso)).toLocaleDateString('de-DE', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit', timeZone: TIMEZONE }); } - catch(e) { return iso; } - }, - - showError: function() { - document.getElementById('summary-content').innerHTML = - '

Das Lagebild konnte nicht geladen werden. Bitte versuchen Sie es sp\u00e4ter erneut.

'; - } -}; - -document.addEventListener('DOMContentLoaded', function() { Lagebild.init(); }); +/** + * AegisSight Lagebild Page - Dark Theme / Scroll-Narrative + * Count-Up, Timeline, Scroll-Spy, Scroll-Reveal, Favicons + */ + +/** Feste Zeitzone fuer alle Anzeigen - NIEMALS aendern. */ +var TIMEZONE = 'Europe/Berlin'; + +var Lagebild = { + data: null, + allSnapshots: {}, + currentView: null, + map: null, + timelineGroups: null, + articlesShowAll: false, + + /* ===== Inline SVG Icons ===== */ + icons: { + clock: '', + fileText: '', + globe: '', + shieldCheck: '', + externalLink: '' + }, + + async init() { + if (typeof initTranslations === 'function') { + try { initTranslations(); } catch(e) {} + } + try { + var resp = await fetch('data/current.json?t=' + Date.now()); + if (!resp.ok) throw new Error('HTTP ' + resp.status); + this.data = await resp.json(); + this.currentView = { + summary: this.data.current_lagebild.summary_markdown, + sources_json: this.data.current_lagebild.sources_json, + updated_at: this.data.current_lagebild.updated_at || this.data.generated_at, + articles: this.data.articles, + fact_checks: this.data.fact_checks + }; + this.render(); + this.initLangToggle(); + this.initScrollReveal(); + this.initFloatingCta(); + } catch (e) { + console.error('Lagebild laden fehlgeschlagen:', e); + this.showError(); + } + }, + + render: function() { + this.renderHero(); + this.renderTimeline(); + this.renderSectionBadges(); + this.renderCurrentView(); + }, + + /* ===== HERO ===== */ + renderHero: function() { + var d = this.data; + document.getElementById('incident-title').innerHTML = + this.esc(this.fixUmlauts(d.incident.title)) + + ' \u2013 Stand: ' + this.fmtDateOnly(d.generated_at) + ', ' + this.fmtTimeOnly(d.generated_at) + ' Uhr'; + + // Stat Cards (3: Artikel, Quellen, Faktenchecks) + var statsHtml = ''; + statsHtml += this.statCard(this.icons.fileText, '0', 'Artikel'); + statsHtml += this.statCard(this.icons.globe, '0', 'Quellen'); + statsHtml += this.statCard(this.icons.shieldCheck, '0', 'Faktenchecks'); + document.getElementById('hero-stats').innerHTML = statsHtml; + + // Start count-up animations + var self = this; + requestAnimationFrame(function() { + var els = document.querySelectorAll('.count-up'); + for (var i = 0; i < els.length; i++) { + self.animateCount(els[i], parseInt(els[i].getAttribute('data-target')), 800); + } + }); + }, + + statCard: function(icon, value, label) { + return '
' + + '
' + icon + '
' + + '
' + + '' + value + '' + + '' + label + '' + + '
'; + }, + + /* ===== COUNT-UP ANIMATION ===== */ + animateCount: function(element, target, duration) { + var start = performance.now(); + function update(now) { + var elapsed = now - start; + var progress = Math.min(elapsed / duration, 1); + var eased = 1 - Math.pow(1 - progress, 3); // easeOutCubic + var current = Math.round(target * eased); + element.textContent = current.toLocaleString('de-DE'); + if (progress < 1) { + requestAnimationFrame(update); + } + } + requestAnimationFrame(update); + }, + + /* ===== TIMELINE STRIP ===== */ + renderTimeline: function() { + var snaps = this.data.available_snapshots || []; + var current = { + id: 'current', + article_count: this.data.incident.article_count, + fact_check_count: this.data.incident.factcheck_count, + created_at: this.data.generated_at + }; + var all = [current].concat(snaps); + + // Group by date + var groups = {}; + for (var i = 0; i < all.length; i++) { + var s = all[i]; + var dateKey = this.toDateKey(s.created_at); + if (!groups[dateKey]) groups[dateKey] = []; + groups[dateKey].push(s); + } + + // Sort each group descending (newest first) + for (var dk in groups) { + groups[dk].sort(function(a, b) { + return new Date(Lagebild.toUTC(b.created_at)) - new Date(Lagebild.toUTC(a.created_at)); + }); + } + + this.timelineGroups = groups; + var dates = Object.keys(groups).sort(); + var strip = document.getElementById('timeline-strip'); + var h = ''; + + for (var j = 0; j < dates.length; j++) { + var date = dates[j]; + var daySnaps = groups[date]; + var latest = daySnaps[0]; + var isActive = (j === dates.length - 1); + var d = new Date(date + 'T12:00:00Z'); + + h += ''; + } + + strip.innerHTML = h; + + // Scroll to active day + var active = strip.querySelector('.timeline-day.active'); + if (active) { + setTimeout(function() { + active.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' }); + }, 150); + } + + // Click handler for day buttons + var self = this; + strip.addEventListener('click', function(e) { + var btn = e.target.closest('.timeline-day'); + if (!btn) return; + + var allDays = strip.querySelectorAll('.timeline-day'); + for (var k = 0; k < allDays.length; k++) allDays[k].classList.remove('active'); + btn.classList.add('active'); + + var dateKey = btn.getAttribute('data-date'); + var snapId = btn.getAttribute('data-snapshot-id'); + + // Show dropdown for this day + self.showTimelineDropdown(dateKey, snapId); + + // Load latest snapshot + if (snapId === 'current') { + self.currentView = { + summary: self.data.current_lagebild.summary_markdown, + sources_json: self.data.current_lagebild.sources_json, + updated_at: self.data.current_lagebild.updated_at || self.data.generated_at, + articles: self.data.articles, + fact_checks: self.data.fact_checks + }; + self.renderCurrentView(); + } else { + self.loadSnapshot(parseInt(snapId)); + } + }); + + // Click handler for dropdown snapshot items (delegated) + var dropdown = document.getElementById('timeline-dropdown'); + dropdown.addEventListener('click', function(e) { + var item = e.target.closest('.timeline-snap-item'); + if (!item) return; + + var items = dropdown.querySelectorAll('.timeline-snap-item'); + for (var k = 0; k < items.length; k++) items[k].classList.remove('active'); + item.classList.add('active'); + + var snapId = item.getAttribute('data-snapshot-id'); + if (snapId === 'current') { + self.currentView = { + summary: self.data.current_lagebild.summary_markdown, + sources_json: self.data.current_lagebild.sources_json, + updated_at: self.data.current_lagebild.updated_at || self.data.generated_at, + articles: self.data.articles, + fact_checks: self.data.fact_checks + }; + self.renderCurrentView(); + } else { + self.loadSnapshot(parseInt(snapId)); + } + }); + + // Show dropdown for newest day by default + var newestDate = dates[dates.length - 1]; + if (newestDate && groups[newestDate].length > 1) { + this.showTimelineDropdown(newestDate, groups[newestDate][0].id); + } + }, + + showTimelineDropdown: function(dateKey, activeSnapId) { + var dropdown = document.getElementById('timeline-dropdown'); + var snaps = this.timelineGroups[dateKey]; + + if (!snaps || snaps.length <= 1) { + dropdown.classList.remove('open'); + dropdown.innerHTML = ''; + return; + } + + var d = new Date(dateKey + 'T12:00:00Z'); + var dateLabel = d.toLocaleDateString('de-DE', { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' }); + + var h = '
' + dateLabel + ' \u2013 ' + snaps.length + ' Updates
'; + h += '
'; + for (var i = 0; i < snaps.length; i++) { + var snap = snaps[i]; + var isActive = (String(snap.id) === String(activeSnapId)); + h += ''; + } + h += '
'; + + dropdown.innerHTML = h; + dropdown.classList.add('open'); + }, + + toDateKey: function(iso) { + if (!iso) return ''; + var d = new Date(this.toUTC(iso)); + return d.toLocaleDateString('en-CA', { timeZone: TIMEZONE }); + }, + + /* ===== SECTION BADGES ===== */ + renderSectionBadges: function() { + var artikelBadge = document.getElementById('badge-artikel'); + var fcBadge = document.getElementById('badge-faktenchecks'); + if (artikelBadge) artikelBadge.textContent = this.data.incident.article_count; + if (fcBadge) fcBadge.textContent = this.data.incident.factcheck_count; + }, + + /* ===== SNAPSHOT LOADING ===== */ + loadSnapshot: async function(id) { + if (this.allSnapshots[id]) { + this.currentView = this.allSnapshots[id]; + this.renderCurrentView(); + return; + } + try { + var resp = await fetch('data/snapshot-' + id + '.json'); + if (!resp.ok) throw new Error('HTTP ' + resp.status); + var sd = await resp.json(); + var sj = sd.sources_json; + if (typeof sj === 'string') { try { sj = JSON.parse(sj); } catch(e) { sj = []; } } + this.currentView = { + summary: sd.summary, + sources_json: sj || [], + updated_at: sd.created_at, + articles: this.data.articles, + fact_checks: this.data.fact_checks + }; + this.allSnapshots[id] = this.currentView; + this.renderCurrentView(); + } catch (e) { console.error('Snapshot Fehler:', e); } + }, + + renderCurrentView: function() { + this.renderSummary(); + this.renderInlineSources(); + this.renderArtikelSection(); + this.renderFactChecksTab(); + if (!this.map) this.renderMap(); + }, + + /* ===== SECTION: LAGEBILD ===== */ + renderSummary: function() { + var v = this.currentView; + document.getElementById('lagebild-timestamp').textContent = this.fmtDT(v.updated_at); + var md = this.fixUmlauts(v.summary || ''); + var html = this.mdToHtml(md); + + // Build source lookup for citation links + var srcMap = {}; + var sources = v.sources_json || []; + for (var i = 0; i < sources.length; i++) { + srcMap[sources[i].nr] = sources[i]; + } + var self = this; + html = html.replace(/\[(\d+)\]/g, function(match, nr) { + var src = srcMap[nr]; + if (src && src.url) { + return '[' + nr + ']'; + } + return '[' + nr + ']'; + }); + + document.getElementById('summary-content').innerHTML = html; + }, + + renderInlineSources: function() { + document.getElementById('inline-sources').innerHTML = ''; + }, + + /* ===== SECTION: ARTIKEL ===== */ + renderArtikelSection: function() { + var articles = this.currentView.articles || []; + var limit = 20; + var showAll = this.articlesShowAll || articles.length <= limit; + var displayArticles = showAll ? articles : articles.slice(0, limit); + + document.getElementById('articles-heading').textContent = 'Artikel (' + articles.length + ')'; + + var ah = ''; + for (var i = 0; i < displayArticles.length; i++) { + var a = displayArticles[i]; + var dt = a.published_at || a.collected_at || ''; + var dObj = dt ? new Date(this.toUTC(dt)) : null; + var hl = this.fixUmlauts(a.headline_de || a.headline || ''); + var domain = this.extractDomain(a.source_url); + + ah += '
'; + ah += '
'; + } + + if (!showAll) { + ah += '
'; + ah += ''; + ah += '
'; + } + + document.getElementById('articles-content').innerHTML = ah; + + if (!showAll) { + var self = this; + document.getElementById('show-all-articles').addEventListener('click', function() { + self.articlesShowAll = true; + self.renderArtikelSection(); + }); + } + }, + + /* ===== SECTION: KARTE ===== */ + renderMap: function() { + if (this.map) { this.map.remove(); this.map = null; } + this.map = L.map('map-container').setView([33.0, 48.0], 5); + + // Dark map tiles (CartoDB Dark Matter) + L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { + attribution: '© OpenStreetMap © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(this.map); + + var redIcon = L.icon({ + iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', + iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] + }); + var blueIcon = L.icon({ + iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', + iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] + }); + var orangeIcon = L.icon({ + iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-orange.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', + iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] + }); + + var locs = [ + {n:'Teheran, Iran',lat:35.6892,lng:51.3890,d:'Hauptziel der US-israelischen Luftschl\u00e4ge. \u00dcber 1.000 Tote nach f\u00fcnf Tagen Krieg.',ic:redIcon}, + {n:'Beirut, Libanon',lat:33.8938,lng:35.5018,d:'Gleichzeitige US-israelische Luftschl\u00e4ge auf Beirut und Teheran [6].',ic:redIcon}, + {n:'Juffair, Bahrain',lat:26.2235,lng:50.6001,d:'US-Marinebasis \u2013 Ziel iranischer Vergeltungsraketen [3].',ic:orangeIcon}, + {n:'Al Udeid, Katar',lat:25.1173,lng:51.3150,d:'US-Luftwaffenst\u00fctzpunkt \u2013 Ziel iranischer Gegenangriffe.',ic:orangeIcon}, + {n:'Tel Aviv, Israel',lat:32.0853,lng:34.7818,d:'Operationsbasis f\u00fcr israelische Angriffe auf den Iran.',ic:blueIcon}, + {n:'Ankara, T\u00fcrkei',lat:39.9334,lng:32.8597,d:'NATO vermutet iranischen Raketenbeschuss auf T\u00fcrkei [10]. Keine NATO-Beteiligung geplant.',ic:orangeIcon}, + {n:'Bagdad, Irak',lat:33.3152,lng:44.3661,d:'Lage im Irak als Faktor im Kriegsverlauf [2].',ic:blueIcon}, + {n:'Persischer Golf',lat:27.0,lng:51.5,d:'Iran greift Energieinfrastruktur und diplomatische Einrichtungen in der Golfregion an.',ic:orangeIcon}, + {n:'Dubai, VAE',lat:25.2048,lng:55.2708,d:'US-Botschaft in Dubai durch iranischen Angriff getroffen.',ic:redIcon}, + {n:'Washington D.C., USA',lat:38.9072,lng:-77.0369,d:'War-Powers-Abstimmung im Senat gescheitert (47:53). Trump verteidigt Iran-Krieg vor Kongress.',ic:blueIcon} + ]; + + for (var i = 0; i < locs.length; i++) { + var l = locs[i]; + L.marker([l.lat, l.lng], { icon: l.ic }) + .addTo(this.map) + .bindPopup('' + l.n + '
' + l.d + ''); + } + + // Dark legend + var legend = L.control({ position: 'bottomright' }); + legend.onAdd = function() { + var div = L.DomUtil.create('div', 'map-legend'); + div.style.cssText = 'background:#151D2E;padding:10px 14px;border-radius:4px;border:1px solid #1E2D45;box-shadow:0 2px 8px rgba(0,0,0,0.3);font-size:0.8rem;line-height:1.8;color:#E8ECF4;'; + div.innerHTML = 'Legende
' + + ' Angegriffene Ziele
' + + ' Vergeltung / Eskalation
' + + ' Strategische Akteure'; + return div; + }; + legend.addTo(this.map); + + // Dark popup styling + if (!document.getElementById('leaflet-dark-style')) { + var style = document.createElement('style'); + style.id = 'leaflet-dark-style'; + style.textContent = '.lagebild-page .leaflet-popup-content-wrapper{background:#151D2E;color:#E8ECF4;border:1px solid #1E2D45;border-radius:4px;box-shadow:0 4px 16px rgba(0,0,0,0.4);}.lagebild-page .leaflet-popup-tip{background:#151D2E;}'; + document.head.appendChild(style); + } + + setTimeout(function() { if (Lagebild.map) Lagebild.map.invalidateSize(); }, 300); + }, + + /* ===== SECTION: FAKTENCHECKS ===== */ + renderFactChecksTab: function() { + var checks = this.currentView.fact_checks || []; + if (!checks.length) { + document.getElementById('factchecks-content').innerHTML = '

Keine Faktenchecks verf\u00fcgbar.

'; + return; + } + + var stats = { confirmed: 0, unconfirmed: 0, contradicted: 0, developing: 0, established: 0, disputed: 0 }; + for (var k = 0; k < checks.length; k++) { + var st = checks[k].status || 'developing'; + if (stats[st] !== undefined) stats[st]++; + } + + var h = '
'; + h += '
' + checks.length + 'Gesamt
'; + h += '
' + (stats.confirmed + stats.established) + 'Best\u00e4tigt
'; + h += '
' + (stats.unconfirmed + stats.developing) + 'Offen
'; + if (stats.contradicted + stats.disputed > 0) + h += '
' + (stats.contradicted + stats.disputed) + 'Widerlegt
'; + h += '
'; + + checks = checks.slice().sort(function(a, b) { + var aH = (a.status_history || []).length; + var bH = (b.status_history || []).length; + if (bH !== aH) return bH - aH; + return (b.sources_count || 0) - (a.sources_count || 0); + }); + + for (var i = 0; i < checks.length; i++) { + var fc = checks[i]; + var status = fc.status || 'developing'; + var hasProg = fc.status_history && fc.status_history.length > 1; + + h += '
'; + h += '
'; + h += '' + this.stLabel(status) + ''; + h += '' + (fc.sources_count || 0) + ' unabh\u00e4ngige Quellen'; + h += '
'; + h += '

' + this.esc(this.fixUmlauts(fc.claim || '')) + '

'; + + if (fc.evidence) { + var ev = this.fixUmlauts(fc.evidence); + ev = this.esc(ev).replace(/(https?:\/\/[^\s,)]+)/g, '$1'); + h += '
Evidenz: ' + ev + '
'; + } + + if (hasProg) { + h += '
'; + h += 'Verlauf:'; + for (var j = 0; j < fc.status_history.length; j++) { + var step = fc.status_history[j]; + if (j > 0) h += ''; + h += ''; + h += '' + this.stLabel(step.status) + ''; + if (step.at) h += '' + this.fmtShort(step.at) + ''; + h += ''; + } + h += '
'; + } + h += '
'; + } + document.getElementById('factchecks-content').innerHTML = h; + }, + + + + initLangToggle: function() { + var btn = document.querySelector('.lang-toggle'); + if (!btn) return; + btn.addEventListener('click', function(e) { + e.preventDefault(); + if (typeof switchLanguage === 'function') { + var cur = (typeof getCurrentLanguage === 'function') ? getCurrentLanguage() : 'de'; + switchLanguage(cur === 'de' ? 'en' : 'de'); + } + }); + }, + + /* ===== FLOATING CTA ===== */ + initFloatingCta: function() { + var cta = document.createElement('div'); + cta.className = 'floating-cta'; + cta.innerHTML = 'AegisSight Monitor f\u00fcr Ihre Organisation' + + 'Kontakt aufnehmen \u2192' + + ''; + document.body.appendChild(cta); + + // Show after scrolling past hero + var shown = false; + window.addEventListener('scroll', function() { + if (shown) return; + if (window.scrollY > 400) { + cta.classList.add('visible'); + shown = true; + } + }); + + // Close button + cta.querySelector('.floating-cta-close').addEventListener('click', function(e) { + e.preventDefault(); + cta.classList.add('dismissed'); + setTimeout(function() { cta.classList.remove('dismissed'); }, 60000); + }); + }, + + /* ===== SCROLL REVEAL ===== */ + initScrollReveal: function() { + var cards = document.querySelectorAll('.content-card, .section-karte'); + if (!('IntersectionObserver' in window)) { + for (var i = 0; i < cards.length; i++) cards[i].classList.add('revealed'); + return; + } + var observer = new IntersectionObserver(function(entries) { + entries.forEach(function(entry) { + if (entry.isIntersecting) { + entry.target.classList.add('revealed'); + observer.unobserve(entry.target); + } + }); + }, { threshold: 0.1 }); + + for (var i = 0; i < cards.length; i++) { + cards[i].classList.add('reveal'); + observer.observe(cards[i]); + } + }, + + /* ===== HILFSFUNKTIONEN ===== */ + extractDomain: function(url) { + if (!url) return null; + try { return new URL(url).hostname; } catch(e) { return null; } + }, + + fixUmlauts: function(text) { + if (!text) return text; + var skip = ['Israel','Israelis','Jazeera','Euronews','Reuters','Februar', + 'Juffair','abgefeuert','Feindseligkeiten','Gegenschlag','neuesten', + 'auszuweiten','befeuert','feuerte','Feuer','feuer','neue','neuen', + 'neuer','neues','Neue','Aero','aero','Manoeuvre','Dauerfeuer']; + var ph = []; var c = 0; + for (var i = 0; i < skip.length; i++) { + var re = new RegExp('\\b' + skip[i] + '\\b', 'g'); + text = text.replace(re, function(m) { ph.push(m); return '##S' + (c++) + '##'; }); + } + text = text.replace(/ae/g, '\u00e4').replace(/Ae/g, '\u00c4'); + text = text.replace(/oe/g, '\u00f6').replace(/Oe/g, '\u00d6'); + text = text.replace(/ue/g, '\u00fc').replace(/Ue/g, '\u00dc'); + text = text.replace(/##S(\d+)##/g, function(m, idx) { return ph[parseInt(idx)]; }); + return text; + }, + + stLabel: function(s) { + return { confirmed: 'Best\u00e4tigt', unconfirmed: 'Unbest\u00e4tigt', established: 'Gesichert', + unverified: 'Nicht verifiziert', contradicted: 'Widerlegt', disputed: 'Umstritten', + developing: 'In Entwicklung', 'false': 'Falsch' }[s] || s; + }, + + mdToHtml: function(md) { + if (!md) return ''; + var lines = md.split('\n'), html = '', inList = false; + for (var i = 0; i < lines.length; i++) { + var l = lines[i]; + if (/^### (.+)$/.test(l)) { if (inList) { html += ''; inList = false; } html += '

' + l.replace(/^### /, '') + '

'; continue; } + if (/^## (.+)$/.test(l)) { if (inList) { html += ''; inList = false; } html += '

' + l.replace(/^## /, '') + '

'; continue; } + if (/^[-*] (.+)$/.test(l)) { if (!inList) { html += ''; inList = false; } + if (l.trim() === '') continue; + html += '

' + l + '

'; + } + if (inList) html += ''; + html = html.replace(/\*\*(.+?)\*\*/g, '$1'); + html = html.replace(/\*(.+?)\*/g, '$1'); + return html; + }, + + esc: function(s) { if (!s) return ''; var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }, + + toUTC: function(s) { + if (!s) return s; + s = String(s).trim(); + if (/[Zz]$/.test(s) || /[+-]\d{2}:?\d{2}$/.test(s)) return s; + return s.replace(' ', 'T') + 'Z'; + }, + + fmtDT: function(iso) { + if (!iso) return ''; + try { + var d = new Date(this.toUTC(iso)); + if (isNaN(d.getTime())) return iso; + var opts = { timeZone: TIMEZONE, weekday: 'long', day: 'numeric', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }; + var parts = new Intl.DateTimeFormat('de-DE', opts).formatToParts(d); + var p = {}; + parts.forEach(function(x) { p[x.type] = x.value; }); + return p.weekday + ', ' + p.day + '. ' + p.month + ' ' + p.year + + ' um ' + p.hour + ':' + p.minute + ' Uhr'; + } catch(e) { return iso; } + }, + + fmtDateOnly: function(iso) { + if (!iso) return ''; + try { + var d = new Date(this.toUTC(iso)); + if (isNaN(d.getTime())) return iso; + return d.toLocaleDateString('de-DE', { day: 'numeric', month: 'short', year: 'numeric', timeZone: TIMEZONE }); + } catch(e) { return iso; } + }, + + fmtTimeOnly: function(iso) { + if (!iso) return ''; + try { + var d = new Date(this.toUTC(iso)); + if (isNaN(d.getTime())) return iso; + return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', timeZone: TIMEZONE }); + } catch(e) { return iso; } + }, + + fmtShort: function(iso) { + if (!iso) return ''; + try { return new Date(this.toUTC(iso)).toLocaleDateString('de-DE', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit', timeZone: TIMEZONE }); } + catch(e) { return iso; } + }, + + showError: function() { + document.getElementById('summary-content').innerHTML = + '

Das Lagebild konnte nicht geladen werden. Bitte versuchen Sie es sp\u00e4ter erneut.

'; + } +}; + +document.addEventListener('DOMContentLoaded', function() { Lagebild.init(); });