diff --git a/lagebild/index.html b/lagebild/index.html index a54c7f8..9b931f4 100644 --- a/lagebild/index.html +++ b/lagebild/index.html @@ -66,22 +66,28 @@ - -
+ +
-
+
+ + + + +
+
- +
-
-
-
+ +
+

Lagebild

@@ -94,43 +100,49 @@
-
-
-
- - -
-
-
-

Karte

-

Geografische Einordnung der Meldungen

-
+
-
- - -
-
-
+ +
+
+
+

Quellen & Quellenberichte

+

Alle vom AegisSight Monitor aggregierten Quellen und Artikel

+
+
+
+

Alle Artikel

+
+
+
+
+ + +
+
+
+

Karte

+

Geografische Einordnung der Meldungen

+
+
+
+
+
+
+ + +
+

Faktenchecks

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

-
-
+ +
- -
-
-
-

Artikel

-

Alle vom AegisSight Monitor aggregierten Artikel

-
-
-
-
+
@@ -174,4 +186,4 @@ - \ No newline at end of file + diff --git a/lagebild/lagebild.css b/lagebild/lagebild.css index 5d066cc..67148a3 100644 --- a/lagebild/lagebild.css +++ b/lagebild/lagebild.css @@ -1,5 +1,5 @@ /* ========================================================================== - AegisSight Lagebild Page - Dark Theme / Scroll-Narrative + AegisSight Lagebild Page - Dark Theme Design Refresh ========================================================================== */ /* ---------- Variables ---------- */ @@ -211,7 +211,7 @@ margin-top: 2px; } -/* ---------- Control Bar (Sticky) ---------- */ +/* ---------- Control Bar ---------- */ .control-bar { background: var(--lb-bg-card); border-bottom: 1px solid var(--lb-border); @@ -376,19 +376,56 @@ opacity: 0.7; } -/* ---------- Main Content ---------- */ -.lagebild-main { - padding: 2rem 0 4rem; +/* Tab Navigation */ +.tab-nav { + display: flex; + gap: 0; } -.lagebild-main > .container { - max-width: 1000px; - margin: 0 auto; - padding: 0 20px; +.tab-btn { + padding: 12px 20px; + border: none; + background: transparent; + cursor: pointer; + font-size: 0.9rem; + font-weight: 600; + color: var(--lb-text-sec); + border-bottom: 3px solid transparent; + transition: all 0.2s; + font-family: inherit; +} +.tab-btn:hover { + color: var(--lb-text); +} +.tab-btn.active { + color: var(--lb-accent); + border-bottom-color: var(--lb-accent); +} +.tab-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; +} +.tab-btn.active .tab-badge { + background: rgba(200, 168, 81, 0.22); } -/* ---------- Content Sections ---------- */ -.content-section { - margin-bottom: 3rem; +/* Tab Panels */ +.tab-panel { display: none; } +.tab-panel.active { display: block; } + +/* ---------- Main Content ---------- */ +.lagebild-main { + padding: 2rem 20px 4rem; +} +.lagebild-main .container { + max-width: 1000px; + margin: 0 auto; } /* ---------- Content Cards ---------- */ @@ -443,34 +480,6 @@ 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 { @@ -534,6 +543,113 @@ transition: background 1.5s ease-out; } +/* Sources List */ +.sources-section h3 { + font-size: 1.1rem; + font-weight: 700; + color: var(--lb-text); + margin: 0 0 12px; +} +.section-subtitle { + font-size: 1.1rem; + font-weight: 700; + color: var(--lb-text); + margin: 2rem 0 12px; + padding-top: 1.5rem; + border-top: 1px solid var(--lb-border); +} +.sources-list { + list-style: none; + padding: 0; + margin: 0; + counter-reset: src; + columns: 2; + column-gap: 24px; +} +.sources-list li { + counter-increment: src; + padding: 4px 0; + font-size: 0.88rem; + color: var(--lb-text); + break-inside: avoid; +} +.sources-list li::before { + content: "[" counter(src) "]"; + color: var(--lb-accent); + font-weight: 700; + font-size: 0.82rem; + margin-right: 6px; +} +.sources-list a { + color: var(--lb-accent); + text-decoration: none; +} +.sources-list a:hover { text-decoration: underline; } +.source-name { + font-weight: 600; + color: var(--lb-text); +} + +/* Inline sources (Lagebild tab footer) - Collapsible */ +.inline-sources-toggle { + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 0.9rem; + font-weight: 600; + color: var(--lb-text-sec); + cursor: pointer; + padding: 10px 16px; + user-select: none; + transition: all 0.2s; + background: var(--lb-bg-secondary); + border: 1px solid var(--lb-border); + border-radius: var(--radius-sm, 4px); +} +.inline-sources-toggle:hover { + color: var(--lb-accent); + border-color: rgba(200, 168, 81, 0.4); + background: rgba(200, 168, 81, 0.06); +} +.inline-sources-arrow { + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + font-size: 1.1rem; + transition: transform 0.2s; + color: var(--lb-accent); +} +#inline-sources.open .inline-sources-arrow { + transform: rotate(90deg); +} +.inline-sources-body { + display: none; + padding: 8px 0 0; + font-size: 0.82rem; + line-height: 1.8; + color: var(--lb-text-sec); +} +#inline-sources.open .inline-sources-body { + display: block; +} +.src-inline .src-nr { + color: var(--lb-accent); + font-weight: 700; +} +.src-sep { + color: var(--lb-border); + margin: 0 2px; +} +.inline-sources-body a { + color: var(--lb-accent); + text-decoration: none; +} +.inline-sources-body a:hover { + text-decoration: underline; +} + /* ---------- Article Cards ---------- */ .article-card { display: flex; @@ -621,29 +737,10 @@ 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 ---------- */ +#map-container { + background: var(--lb-bg-secondary); +} .lagebild-page .map-legend { background: var(--lb-bg-card) !important; color: var(--lb-text) !important; @@ -1044,13 +1141,14 @@ padding: 5px 10px; font-size: 0.72rem; } - .section-nav { + .tab-nav { overflow-x: auto; -webkit-overflow-scrolling: touch; } - .section-nav-link { + .tab-btn { padding: 10px 14px; font-size: 0.82rem; + white-space: nowrap; } .card-header { @@ -1064,13 +1162,7 @@ padding: 16px 20px 20px; } .lagebild-main { - padding: 1rem 0 3rem; - } - .lagebild-main > .container { - padding: 0 12px; - } - .content-section { - margin-bottom: 2rem; + padding: 1rem 12px 3rem; } .factcheck-header { flex-direction: column; @@ -1105,7 +1197,7 @@ gap: 4px; } - .section-karte .section-heading { - margin-bottom: 1rem; + .sources-list { + columns: 1; } -} \ No newline at end of file +} diff --git a/lagebild/lagebild.js b/lagebild/lagebild.js index a71bb65..c7b5ed8 100644 --- a/lagebild/lagebild.js +++ b/lagebild/lagebild.js @@ -1,6 +1,6 @@ /** - * AegisSight Lagebild Page - Dark Theme / Scroll-Narrative - * Count-Up, Timeline, Scroll-Spy, Scroll-Reveal, Favicons + * AegisSight Lagebild Page - Dark Theme Design Refresh + * Count-Up, Timeline mit Dropdown, Scroll-Reveal, Smooth-Scroll, Favicons */ /** Feste Zeitzone fuer alle Anzeigen - NIEMALS aendern. */ @@ -12,7 +12,6 @@ var Lagebild = { currentView: null, map: null, timelineGroups: null, - articlesShowAll: false, /* ===== Inline SVG Icons ===== */ icons: { @@ -39,6 +38,7 @@ var Lagebild = { fact_checks: this.data.fact_checks }; this.render(); + this.initTabs(); this.initLangToggle(); this.initScrollReveal(); this.initFloatingCta(); @@ -51,7 +51,7 @@ var Lagebild = { render: function() { this.renderHero(); this.renderTimeline(); - this.renderSectionBadges(); + this.renderTabBadges(); this.renderCurrentView(); }, @@ -60,7 +60,7 @@ var Lagebild = { 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'; + ' - Stand: ' + this.fmtDateOnly(d.generated_at) + ', ' + this.fmtTimeOnly(d.generated_at) + ' Uhr'; // Stat Cards (3: Artikel, Quellen, Faktenchecks) var statsHtml = ''; @@ -204,7 +204,7 @@ var Lagebild = { } }); - // Click handler for dropdown snapshot items (delegated) + // Click handler for dropdown snapshot items (delegated, set up once) var dropdown = document.getElementById('timeline-dropdown'); dropdown.addEventListener('click', function(e) { var item = e.target.closest('.timeline-snap-item'); @@ -249,7 +249,7 @@ var Lagebild = { 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
'; + var h = '
' + dateLabel + ' - ' + snaps.length + ' Updates
'; h += '
'; for (var i = 0; i < snaps.length; i++) { var snap = snaps[i]; @@ -272,11 +272,11 @@ var Lagebild = { 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; + /* ===== TAB BADGES ===== */ + renderTabBadges: function() { + var quellenBadge = document.getElementById('tab-badge-quellen'); + var fcBadge = document.getElementById('tab-badge-faktenchecks'); + if (quellenBadge) quellenBadge.textContent = this.data.incident.source_count; if (fcBadge) fcBadge.textContent = this.data.incident.factcheck_count; }, @@ -308,12 +308,15 @@ var Lagebild = { renderCurrentView: function() { this.renderSummary(); this.renderInlineSources(); - this.renderArtikelSection(); + this.renderSourcesTab(); + this.renderArticlesTab(); this.renderFactChecksTab(); - if (!this.map) this.renderMap(); + if (document.getElementById('panel-karte').classList.contains('active')) { + this.renderMap(); + } }, - /* ===== SECTION: LAGEBILD ===== */ + /* ===== TAB: LAGEBILD ===== */ renderSummary: function() { var v = this.currentView; document.getElementById('lagebild-timestamp').textContent = this.fmtDT(v.updated_at); @@ -342,18 +345,32 @@ var Lagebild = { document.getElementById('inline-sources').innerHTML = ''; }, - /* ===== SECTION: ARTIKEL ===== */ - renderArtikelSection: function() { + /* ===== TAB: QUELLEN ===== */ + renderSourcesTab: function() { + var sources = this.currentView.sources_json || []; var articles = this.currentView.articles || []; - var limit = 20; - var showAll = this.articlesShowAll || articles.length <= limit; - var displayArticles = showAll ? articles : articles.slice(0, limit); + var h = ''; - document.getElementById('articles-heading').textContent = 'Artikel (' + articles.length + ')'; + h += '

Im Lagebild zitierte Quellen (' + sources.length + ')

'; + if (sources.length) { + h += '
    '; + for (var i = 0; i < sources.length; i++) { + var s = sources[i]; + if (s.url) { + h += '
  1. ' + this.esc(s.name || '') + '
  2. '; + } else { + h += '
  3. ' + this.esc(s.name || '') + '
  4. '; + } + } + h += '
'; + } + h += '
'; + document.getElementById('sources-cited').innerHTML = h; + document.getElementById('articles-heading').textContent = 'Alle gesammelten Artikel (' + articles.length + ')'; var ah = ''; - for (var i = 0; i < displayArticles.length; i++) { - var a = displayArticles[i]; + for (var i = 0; i < articles.length; i++) { + var a = articles[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 || ''); @@ -381,25 +398,12 @@ var Lagebild = { if (a.source_url) ah += 'Artikel lesen ' + this.icons.externalLink + ''; 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 ===== */ + renderArticlesTab: function() {}, + + /* ===== TAB: KARTE ===== */ renderMap: function() { if (this.map) { this.map.remove(); this.map = null; } this.map = L.map('map-container').setView([33.0, 48.0], 5); @@ -428,12 +432,12 @@ var Lagebild = { }); 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:'Teheran, Iran',lat:35.6892,lng:51.3890,d:'Hauptziel der US-israelischen Luftschläge. Über 1.000 Tote nach fünf Tagen Krieg.',ic:redIcon}, + {n:'Beirut, Libanon',lat:33.8938,lng:35.5018,d:'Gleichzeitige US-israelische Luftschläge auf Beirut und Teheran [6].',ic:redIcon}, + {n:'Juffair, Bahrain',lat:26.2235,lng:50.6001,d:'US-Marinebasis - Ziel iranischer Vergeltungsraketen [3].',ic:orangeIcon}, + {n:'Al Udeid, Katar',lat:25.1173,lng:51.3150,d:'US-Luftwaffenstützpunkt - Ziel iranischer Gegenangriffe.',ic:orangeIcon}, + {n:'Tel Aviv, Israel',lat:32.0853,lng:34.7818,d:'Operationsbasis für israelische Angriffe auf den Iran.',ic:blueIcon}, + {n:'Ankara, Türkei',lat:39.9334,lng:32.8597,d:'NATO vermutet iranischen Raketenbeschuss auf Türkei [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}, @@ -471,11 +475,11 @@ var Lagebild = { setTimeout(function() { if (Lagebild.map) Lagebild.map.invalidateSize(); }, 300); }, - /* ===== SECTION: FAKTENCHECKS ===== */ + /* ===== TAB: FAKTENCHECKS ===== */ renderFactChecksTab: function() { var checks = this.currentView.fact_checks || []; if (!checks.length) { - document.getElementById('factchecks-content').innerHTML = '

Keine Faktenchecks verf\u00fcgbar.

'; + document.getElementById('factchecks-content').innerHTML = '

Keine Faktenchecks verfügbar.

'; return; } @@ -487,7 +491,7 @@ var Lagebild = { var h = '
'; h += '
' + checks.length + 'Gesamt
'; - h += '
' + (stats.confirmed + stats.established) + 'Best\u00e4tigt
'; + h += '
' + (stats.confirmed + stats.established) + 'Bestätigt
'; h += '
' + (stats.unconfirmed + stats.developing) + 'Offen
'; if (stats.contradicted + stats.disputed > 0) h += '
' + (stats.contradicted + stats.disputed) + 'Widerlegt
'; @@ -508,7 +512,7 @@ var Lagebild = { h += '
'; h += '
'; h += '' + this.stLabel(status) + ''; - h += '' + (fc.sources_count || 0) + ' unabh\u00e4ngige Quellen'; + h += '' + (fc.sources_count || 0) + ' unabhängige Quellen'; h += '
'; h += '

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

'; @@ -536,7 +540,30 @@ var Lagebild = { document.getElementById('factchecks-content').innerHTML = h; }, + /* ===== TABS ===== */ + initTabs: function() { + var btns = document.querySelectorAll('.tab-btn'); + var self = this; + for (var i = 0; i < btns.length; i++) { + btns[i].addEventListener('click', function() { + var tab = this.getAttribute('data-tab'); + for (var j = 0; j < btns.length; j++) btns[j].classList.remove('active'); + this.classList.add('active'); + var panels = document.querySelectorAll('.tab-panel'); + for (var j = 0; j < panels.length; j++) panels[j].classList.remove('active'); + var activePanel = document.getElementById('panel-' + tab); + activePanel.classList.add('active'); + // Trigger reveal for cards in newly active panel + var revealCards = activePanel.querySelectorAll('.reveal:not(.revealed)'); + for (var k = 0; k < revealCards.length; k++) { + revealCards[k].classList.add('revealed'); + } + + if (tab === 'karte') self.renderMap(); + }); + } + }, initLangToggle: function() { var btn = document.querySelector('.lang-toggle'); @@ -579,7 +606,7 @@ var Lagebild = { /* ===== SCROLL REVEAL ===== */ initScrollReveal: function() { - var cards = document.querySelectorAll('.content-card, .section-karte'); + var cards = document.querySelectorAll('.content-card, .lagebild-cta'); if (!('IntersectionObserver' in window)) { for (var i = 0; i < cards.length; i++) cards[i].classList.add('revealed'); return; @@ -595,7 +622,13 @@ var Lagebild = { for (var i = 0; i < cards.length; i++) { cards[i].classList.add('reveal'); - observer.observe(cards[i]); + // Immediately reveal cards in the active (visible) tab panel + var panel = cards[i].closest('.tab-panel'); + if (!panel || panel.classList.contains('active')) { + cards[i].classList.add('revealed'); + } else { + observer.observe(cards[i]); + } } }, @@ -624,7 +657,7 @@ var Lagebild = { }, stLabel: function(s) { - return { confirmed: 'Best\u00e4tigt', unconfirmed: 'Unbest\u00e4tigt', established: 'Gesichert', + return { confirmed: 'Bestätigt', unconfirmed: 'Unbestätigt', established: 'Gesichert', unverified: 'Nicht verifiziert', contradicted: 'Widerlegt', disputed: 'Umstritten', developing: 'In Entwicklung', 'false': 'Falsch' }[s] || s; }, @@ -696,7 +729,7 @@ var Lagebild = { showError: function() { document.getElementById('summary-content').innerHTML = - '

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

'; + '

Das Lagebild konnte nicht geladen werden. Bitte versuchen Sie es später erneut.

'; } };