From 8189cf9add6f14f8fdf2282f9b18455d81b6d3a7 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 7 Mar 2026 17:24:49 +0100 Subject: [PATCH] Lagebild: Faktenchecks als Filter + Akkordeon mit Monitor-Icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Stat-Cards klickbar als Filter (Gesamt/Bestätigt/Offen/Widerlegt), zentriert - Kompakte Akkordeon-Zeilen statt großer Karten - Icons vom echten Monitor (✓ ✗ ? ↻ ⚠) als farbige Quadrate - Klick auf Zeile klappt Detail auf (Evidenz + Statusverlauf) - Nur eine Zeile gleichzeitig offen - Gold-Punkt bei Einträgen mit Statusverlauf Co-Authored-By: Claude Opus 4.6 --- lagebild/lagebild.css | 273 ++++++++++++++++++++++++++---------------- lagebild/lagebild.js | 122 ++++++++++++++++--- 2 files changed, 277 insertions(+), 118 deletions(-) diff --git a/lagebild/lagebild.css b/lagebild/lagebild.css index e086559..d86ba49 100644 --- a/lagebild/lagebild.css +++ b/lagebild/lagebild.css @@ -938,36 +938,61 @@ a.source-detail-article-title:hover { 100% { transform: scale(3.5); opacity: 0; } } -/* ---------- Fact Check Cards ---------- */ +/* ---------- Fact Checks (Filter + Accordion) ---------- */ .fc-stats { + justify-content: center; display: flex; - gap: 12px; - margin-bottom: 24px; + gap: 10px; + margin-bottom: 20px; flex-wrap: wrap; } .fc-stat { background: var(--lb-bg-secondary); border-radius: var(--radius-sm, 4px); - padding: 14px 20px; + padding: 12px 18px; text-align: center; - min-width: 80px; + min-width: 75px; border: 1px solid var(--lb-border); + cursor: pointer; + transition: all 0.2s; + font-family: inherit; +} +.fc-stat:hover { + border-color: rgba(200, 168, 81, 0.4); + box-shadow: 0 0 16px var(--lb-glow-soft); +} +.fc-stat.active { + border-color: var(--lb-accent); + box-shadow: 0 0 20px var(--lb-glow-soft); + background: rgba(200, 168, 81, 0.06); } .fc-stat.confirmed { background: rgba(16, 185, 129, 0.08); border-color: rgba(16, 185, 129, 0.2); } +.fc-stat.confirmed.active { + border-color: var(--lb-success); + box-shadow: 0 0 16px 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.unconfirmed.active { + border-color: var(--lb-warning); + box-shadow: 0 0 16px 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.contradicted.active { + border-color: var(--lb-error); + box-shadow: 0 0 16px rgba(239, 68, 68, 0.2); +} .fc-stat-num { display: block; - font-size: 1.6rem; + font-size: 1.5rem; font-weight: 800; color: var(--lb-text); } @@ -975,109 +1000,166 @@ a.source-detail-article-title:hover { .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; + font-size: 0.72rem; 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 { +/* Factcheck Icon (from real Monitor) */ +.fc-icon { + flex-shrink: 0; + width: 22px; + height: 22px; + border-radius: 4px; 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; + justify-content: center; + font-size: 11px; font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.5px; } -.status-badge.confirmed, .status-badge.established { +.fc-icon.small { + width: 18px; + height: 18px; + font-size: 10px; +} +.fc-icon.confirmed, .fc-icon.established { background: rgba(16, 185, 129, 0.15); color: #34d399; } -.status-badge.unconfirmed, .status-badge.unverified { +.fc-icon.unconfirmed, .fc-icon.unverified { background: rgba(245, 158, 11, 0.15); color: #fbbf24; } -.status-badge.contradicted, .status-badge.disputed { +.fc-icon.contradicted, .fc-icon.disputed, .fc-icon.false { background: rgba(239, 68, 68, 0.15); color: #f87171; } -.status-badge.developing { +.fc-icon.developing { background: rgba(59, 130, 246, 0.15); color: #60a5fa; } -.status-badge.false { - background: rgba(220, 38, 38, 0.15); - color: #f87171; + +/* Accordion List */ +.fc-list { + border: 1px solid var(--lb-border); + border-radius: 4px; + overflow: hidden; +} +.fc-row { + border-bottom: 1px solid var(--lb-border); +} +.fc-row:last-child { + border-bottom: none; +} +.fc-row-header { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + cursor: pointer; + transition: background 0.15s; +} +.fc-row-header:hover { + background: var(--lb-bg-secondary); +} +.fc-row.open .fc-row-header { + background: var(--lb-bg-secondary); + border-bottom: 1px solid var(--lb-border); +} +.fc-row-claim { + flex: 1; + font-size: 0.88rem; + color: var(--lb-text); + line-height: 1.4; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.fc-row.open .fc-row-claim { + white-space: normal; + text-overflow: unset; +} +.fc-row-sources { + flex-shrink: 0; + font-size: 0.72rem; + color: var(--lb-text-sec); + background: var(--lb-bg-card); + border: 1px solid var(--lb-border); + padding: 2px 7px; + border-radius: 3px; + font-weight: 600; +} +.fc-row-history-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--lb-accent); + flex-shrink: 0; + box-shadow: 0 0 6px var(--lb-glow); +} +.fc-row-chevron { + flex-shrink: 0; + color: var(--lb-text-sec); + font-size: 0.8rem; + transition: transform 0.2s; + width: 16px; + text-align: center; +} +.fc-row.open .fc-row-chevron { + transform: rotate(90deg); + color: var(--lb-accent); } -/* Status Progression */ -.status-progression { +/* Expandable Detail */ +.fc-row-detail { + display: none; + background: rgba(0, 0, 0, 0.15); +} +.fc-row.open .fc-row-detail { + display: block; + animation: sourceDetailSlideIn 0.25s ease-out; +} +.fc-row-detail-inner { + padding: 14px 14px 14px 46px; +} +.fc-detail-status { + font-size: 0.85rem; + color: var(--lb-text); + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 6px; +} +.fc-detail-evidence { + font-size: 0.82rem; + color: var(--lb-text-sec); + line-height: 1.6; + padding: 10px 14px; + background: rgba(0, 0, 0, 0.2); + border-radius: 4px; + border: 1px solid var(--lb-border); + margin-bottom: 8px; +} +.fc-detail-evidence strong { + color: var(--lb-text); +} +.fc-detail-evidence a { + color: var(--lb-accent) !important; + word-break: break-all; +} +.fc-detail-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; + padding-top: 8px; + border-top: 1px solid var(--lb-border); } -.progression-label { +.fc-detail-prog-label { color: var(--lb-text-sec); font-weight: 500; margin-right: 4px; @@ -1096,25 +1178,6 @@ a.source-detail-article-title:hover { 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; @@ -1343,10 +1406,15 @@ a.source-detail-article-title:hover { .lagebild-main { padding: 1rem 12px 3rem; } - .factcheck-header { - flex-direction: column; - align-items: flex-start; - gap: 6px; + .fc-row-claim { + font-size: 0.82rem; + } + .fc-row-detail-inner { + padding: 12px 12px 12px 12px; + } + .fc-stat { + padding: 10px 14px; + min-width: 65px; } .sources-grid { grid-template-columns: repeat(2, 1fr); @@ -1375,6 +1443,7 @@ a.source-detail-article-title:hover { height: 350px !important; } .fc-stats { + justify-content: center; gap: 8px; } .fc-stat { diff --git a/lagebild/lagebild.js b/lagebild/lagebild.js index 8c04d38..bd7f66a 100644 --- a/lagebild/lagebild.js +++ b/lagebild/lagebild.js @@ -695,27 +695,57 @@ var Lagebild = { }, /* ===== TAB: FAKTENCHECKS ===== */ + /* ===== Factcheck Icons (from real Monitor) ===== */ + fcIcons: { + confirmed: '✓', + unconfirmed: '?', + contradicted: '✗', + developing: '↻', + established: '✓', + disputed: '⚠', + 'false': '✗', + unverified: '?' + }, + + fcLabels: { + confirmed: 'Bestätigt', + unconfirmed: 'Unbestätigt', + contradicted: 'Widerlegt', + developing: 'Unklar', + established: 'Gesichert', + disputed: 'Umstritten', + 'false': 'Falsch', + unverified: 'Nicht verifiziert' + }, + 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; } + // Count stats 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 confirmedTotal = stats.confirmed + stats.established; + var openTotal = stats.unconfirmed + stats.developing; + var contradictedTotal = stats.contradicted + stats.disputed; + + // Stat cards (clickable filters) 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 += ''; + h += ''; + h += ''; + if (contradictedTotal > 0) + h += ''; h += '
'; + // Sort: status_history first, then by sources_count checks = checks.slice().sort(function(a, b) { var aH = (a.status_history || []).length; var bH = (b.status_history || []).length; @@ -723,40 +753,100 @@ var Lagebild = { return (b.sources_count || 0) - (a.sources_count || 0); }); + // Compact accordion list + h += '
'; 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; + var filterGroup = 'all'; + if (status === 'confirmed' || status === 'established') filterGroup = 'confirmed'; + else if (status === 'unconfirmed' || status === 'developing') filterGroup = 'unconfirmed'; + else if (status === 'contradicted' || status === 'disputed') filterGroup = 'contradicted'; - h += '
'; - h += '
'; - h += '' + this.stLabel(status) + ''; - h += '' + (fc.sources_count || 0) + ' unabh\u00e4ngige Quellen'; + var hasProg = fc.status_history && fc.status_history.length > 1; + var icon = this.fcIcons[status] || '?'; + var label = this.fcLabels[status] || status; + + h += '
'; + h += '
'; + h += '' + icon + ''; + h += '' + this.esc(this.fixUmlauts(fc.claim || '')) + ''; + h += '' + (fc.sources_count || 0) + ''; + if (hasProg) h += ''; + h += ''; h += '
'; - h += '

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

'; + + // Expandable detail + h += '
'; + h += '
'; + h += '
' + icon + ' ' + label + ' – ' + (fc.sources_count || 0) + ' unabhängige Quellen
'; if (fc.evidence) { var ev = this.fixUmlauts(fc.evidence); ev = this.esc(ev).replace(/(https?:\/\/[^\s,)]+)/g, '$1'); - h += '
Evidenz: ' + ev + '
'; + h += '
Evidenz: ' + ev + '
'; } if (hasProg) { - h += '
'; - h += 'Verlauf:'; + 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) + ''; + h += '' + (this.fcIcons[step.status] || '?') + ''; if (step.at) h += '' + this.fmtShort(step.at) + ''; h += ''; } h += '
'; } + h += '
'; h += '
'; } + h += '
'; + document.getElementById('factchecks-content').innerHTML = h; + + // Filter click handler + var statBtns = document.querySelectorAll('.fc-stat'); + statBtns.forEach(function(btn) { + btn.addEventListener('click', function() { + for (var k = 0; k < statBtns.length; k++) statBtns[k].classList.remove('active'); + btn.classList.add('active'); + var filter = btn.getAttribute('data-filter'); + var rows = document.querySelectorAll('.fc-row'); + for (var k = 0; k < rows.length; k++) { + if (filter === 'all' || rows[k].getAttribute('data-status-group') === filter) { + rows[k].style.display = ''; + } else { + rows[k].style.display = 'none'; + } + } + }); + }); + + // Accordion click handler + document.getElementById('fc-list').addEventListener('click', function(e) { + var header = e.target.closest('.fc-row-header'); + if (!header) return; + var row = header.closest('.fc-row'); + var wasOpen = row.classList.contains('open'); + + // Close all open rows + var allRows = document.querySelectorAll('.fc-row.open'); + for (var k = 0; k < allRows.length; k++) allRows[k].classList.remove('open'); + + // Toggle clicked row + if (!wasOpen) { + row.classList.add('open'); + var detail = row.querySelector('.fc-row-detail'); + if (detail) { + setTimeout(function() { + detail.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + }, 50); + } + } + }); }, /* ===== TABS ===== */