Files
2026-04-29 19:04:25 +02:00

5161 lines
319 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Prawicowy Dashboard — Wielka Polska wróci, pogonimy Rudego</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/>
<style>
:root {
--bg: #0f1117;
--surface: #1a1d27;
--card: #22263a;
--border: #2e334d;
--accent: #3b82f6;
--text: #e2e8f0;
--muted: #94a3b8;
--republika: #c0392b;
--wpolsce: #2980b9;
--trwam: #27ae60;
--twitter: #1da1f2;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
padding-top: 58px;
}
/* ── HEADER ── */
header {
background: linear-gradient(135deg, #0f1117 0%, #1a1d27 100%);
border-bottom: 1px solid var(--border);
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: 58px;
z-index: 100;
backdrop-filter: blur(8px);
margin-right: 340px;
}
.logo {
display: flex;
align-items: center;
gap: 12px;
}
.logo-icon {
width: 40px; height: 40px;
background: var(--accent);
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 20px;
}
.logo h1 { font-size: 1.3rem; font-weight: 700; }
.logo span { font-size: 0.8rem; color: var(--muted); }
.header-right {
display: flex;
align-items: center;
gap: 12px;
}
#last-updated {
font-size: 0.75rem;
color: var(--muted);
}
#refresh-btn {
background: var(--accent);
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 16px;
cursor: pointer;
font-size: 0.85rem;
display: flex; align-items: center; gap: 6px;
transition: opacity 0.2s;
}
#refresh-btn:hover { opacity: 0.85; }
#refresh-btn.loading { opacity: 0.6; pointer-events: none; }
/* ── FILTERS / SOURCE TABS ── */
.filters {
padding: 12px 24px;
display: flex;
gap: 8px;
flex-wrap: wrap;
border-bottom: 1px solid var(--border);
background: var(--surface);
margin-right: 340px;
}
.filter-btn {
border: none;
border-radius: 20px;
padding: 6px 14px;
font-size: 0.82rem;
cursor: pointer;
font-weight: 500;
transition: all 0.2s;
color: #fff;
}
.filter-btn[data-src="all"] { background: #475569; }
.filter-btn[data-src="republika"] { background: var(--republika); }
.filter-btn[data-src="wpolsce"] { background: var(--wpolsce); }
.filter-btn[data-src="trwam"] { background: var(--trwam); }
.filter-btn[data-src="social"] { background: #7c3aed; }
.filter-btn[data-src="memy"] { background: #b45309; }
.filter-btn.active { outline: 2px solid #fff; outline-offset: 2px; }
.filter-btn:hover { transform: translateY(-1px); }
/* ── LAYOUT ── */
.layout {
display: grid;
grid-template-columns: 1fr;
gap: 0;
min-height: calc(100vh - 110px);
margin-right: 340px;
}
/* ── MAIN FEED ── */
.feed {
padding: 20px 24px;
overflow-y: auto;
}
.section-label {
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 1.2px;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.section-label::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.articles-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 16px;
margin-bottom: 32px;
}
/* ── CARD ── */
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
display: flex;
flex-direction: column;
transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer;
text-decoration: none;
color: inherit;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.card-img {
width: 100%;
height: 160px;
object-fit: cover;
background: var(--border);
}
.card-img-placeholder {
width: 100%;
height: 160px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
background: linear-gradient(135deg, var(--surface), var(--border));
}
.card-body { padding: 14px; flex: 1; display: flex; flex-direction: column; gap: 8px; }
.card-source {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.5px;
text-transform: uppercase;
padding: 3px 8px;
border-radius: 4px;
width: fit-content;
}
.card-title {
font-size: 0.92rem;
font-weight: 600;
line-height: 1.4;
color: var(--text);
}
.card-summary {
font-size: 0.8rem;
color: var(--muted);
line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.card-footer {
margin-top: auto;
padding-top: 8px;
border-top: 1px solid var(--border);
font-size: 0.72rem;
color: var(--muted);
display: flex;
justify-content: space-between;
}
/* Source color tags */
.src-republika { background: rgba(192,57,43,0.2); color: #e74c3c; }
.src-wpolsce { background: rgba(41,128,185,0.2); color: #3498db; }
.src-trwam { background: rgba(39,174,96,0.2); color: #2ecc71; }
.src-social { background: rgba(124,58,237,0.2); color: #a78bfa; }
/* ── SIDEBAR ── */
/* ── FIXED MEDIA PANEL ── */
.sidebar {
position: fixed;
top: 74px;
right: 0;
width: 340px;
height: calc(100vh - 74px);
border-left: 1px solid var(--border);
background: var(--surface);
overflow: hidden;
z-index: 85;
display: flex;
flex-direction: column;
padding: 0;
}
.mp-section {
border-bottom: 2px solid var(--border);
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.mp-header {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 12px;
font-size: 0.8rem;
font-weight: 800;
color: #fff;
letter-spacing: 0.5px;
flex-shrink: 0;
}
.mp-header-republika { background: linear-gradient(135deg, #7f1d1d 0%, #b91c1c 100%); }
.mp-header-wpolsce { background: linear-gradient(135deg, #1e3a8a 0%, #1d4ed8 100%); }
.mp-live-dot {
width: 7px; height: 7px; border-radius: 50%; background: #fff;
animation: pulse 1.5s infinite; flex-shrink: 0; opacity: 0.9;
}
.mp-logo { font-size: 1rem; line-height: 1; }
.mp-name { flex: 1; }
.mp-live-badge {
background: rgba(255,255,255,0.2);
color: #fff; font-size: 0.58rem; font-weight: 900;
padding: 2px 6px; border-radius: 3px; letter-spacing: 1.5px;
}
.mp-channel-logo {
height: 22px; width: auto; border-radius: 3px; object-fit: contain;
flex-shrink: 0;
}
.mp-video-link {
display: block; flex: 1; position: relative; min-height: 0;
overflow: hidden; text-decoration: none;
}
.mp-video-link img {
width: 100%; height: 100%; object-fit: cover; display: block;
transition: opacity 0.2s;
}
.mp-video-link:hover img { opacity: 0.85; }
.mp-play-overlay {
position: absolute; inset: 0;
display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 8px;
}
.mp-play-btn {
width: 52px; height: 52px; border-radius: 50%;
background: rgba(0,0,0,0.72); border: 2px solid rgba(255,255,255,0.7);
display: flex; align-items: center; justify-content: center;
font-size: 1.5rem; color: #fff;
transition: background 0.2s, transform 0.15s;
}
.mp-video-link:hover .mp-play-btn {
background: rgba(220,38,38,0.85); transform: scale(1.1);
}
.mp-play-label {
font-size: 0.68rem; font-weight: 800; color: #fff; letter-spacing: 1px;
text-shadow: 0 1px 4px rgba(0,0,0,0.9);
background: rgba(0,0,0,0.5); padding: 3px 8px; border-radius: 4px;
}
/* ── Radio bar under header ── */
.radio-bar {
background: var(--surface);
border-bottom: 2px solid var(--border);
display: flex;
gap: 0;
margin-right: 340px;
}
.radio-player {
flex: 1;
display: flex;
align-items: center;
gap: 10px;
padding: 7px 12px;
border-right: 1px solid var(--border);
}
.radio-player:last-child { border-right: none; }
.radio-logo-img {
height: 28px; width: auto; border-radius: 4px; object-fit: contain; flex-shrink: 0;
}
.radio-player audio {
flex: 1; height: 32px; min-width: 0; accent-color: var(--accent);
}
.radio-status-badge {
background: rgba(255,255,255,0.15);
color: #fff; font-size: 0.55rem; font-weight: 900;
padding: 2px 5px; border-radius: 3px; letter-spacing: 1.5px; flex-shrink: 0;
}
/* ── POLITICIANS ── */
.politicians { margin-bottom: 28px; }
.politician-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s;
}
.politician-card:hover {
border-color: var(--accent);
box-shadow: 0 0 12px rgba(59,130,246,0.25);
}
.pol-avatar {
width: 44px; height: 44px;
border-radius: 50%;
object-fit: cover;
background: var(--border);
flex-shrink: 0;
}
.pol-info { flex: 1; min-width: 0; }
.pol-name { font-size: 0.85rem; font-weight: 600; }
.pol-role { font-size: 0.72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pol-hint { font-size: 0.68rem; color: var(--accent); margin-top: 2px; }
/* ── POLITICIAN POPUP ── */
#pol-popup {
position: fixed;
z-index: 9999;
width: 320px;
background: #1a1d27;
border: 1px solid var(--accent);
border-radius: 16px;
box-shadow: 0 12px 48px rgba(0,0,0,0.7), 0 0 24px rgba(59,130,246,0.2);
pointer-events: none;
opacity: 0;
transform: scale(0.92) translateY(8px);
transition: opacity 0.18s ease, transform 0.18s ease;
overflow: hidden;
}
#pol-popup.visible {
opacity: 1;
transform: scale(1) translateY(0);
}
#pol-popup .pp-photo {
width: 100%;
height: 220px;
object-fit: cover;
object-position: top center;
display: block;
}
#pol-popup .pp-body {
padding: 14px 16px 16px;
}
#pol-popup .pp-name {
font-size: 1.05rem;
font-weight: 800;
color: #fff;
margin-bottom: 2px;
}
#pol-popup .pp-role {
font-size: 0.72rem;
color: var(--accent);
font-weight: 600;
letter-spacing: 0.5px;
text-transform: uppercase;
margin-bottom: 10px;
}
#pol-popup .pp-desc {
font-size: 0.82rem;
color: var(--text);
line-height: 1.6;
}
#pol-popup .pp-tag {
display: inline-block;
margin-top: 10px;
background: rgba(59,130,246,0.15);
color: var(--accent);
border-radius: 20px;
padding: 3px 10px;
font-size: 0.72rem;
font-weight: 600;
}
/* ── MEMY ── */
.memes-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 16px;
margin-bottom: 32px;
}
.meme-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
display: flex;
flex-direction: column;
transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer;
text-decoration: none;
color: inherit;
}
.meme-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.meme-photo-wrap {
position: relative;
width: 100%;
aspect-ratio: 4/3;
overflow: hidden;
background: var(--border);
}
.meme-photo-wrap img {
width: 100%; height: 100%;
object-fit: cover;
object-position: top center;
}
.meme-platform-badge {
position: absolute;
top: 8px; right: 8px;
background: rgba(0,0,0,0.7);
border-radius: 6px;
padding: 3px 8px;
font-size: 0.7rem;
font-weight: 600;
color: #fff;
backdrop-filter: blur(4px);
}
.meme-likes {
position: absolute;
bottom: 8px; right: 8px;
background: rgba(0,0,0,0.7);
border-radius: 6px;
padding: 3px 8px;
font-size: 0.72rem;
color: #f87171;
backdrop-filter: blur(4px);
}
.meme-body {
padding: 12px;
display: flex;
flex-direction: column;
gap: 6px;
}
.meme-author {
display: flex;
align-items: center;
gap: 8px;
}
.meme-author-avatar {
width: 28px; height: 28px;
border-radius: 50%;
object-fit: cover;
background: var(--border);
}
.meme-author-name {
font-size: 0.8rem;
font-weight: 600;
}
.meme-author-handle {
font-size: 0.7rem;
color: var(--muted);
}
.meme-caption {
font-size: 0.82rem;
color: var(--text);
line-height: 1.45;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.meme-date {
font-size: 0.7rem;
color: var(--muted);
}
.src-memy { background: rgba(245,158,11,0.2); color: #fbbf24; }
.src-opozycja { background: rgba(100,100,100,0.25); color: #cbd5e1; }
/* ── OPOZYCJA — rainbow tło ── */
.rainbow-bg {
background: linear-gradient(135deg,
rgba(255,0,0,0.12) 0%,
rgba(255,165,0,0.12) 16%,
rgba(255,255,0,0.10) 33%,
rgba(0,200,0,0.12) 50%,
rgba(0,100,255,0.12) 66%,
rgba(130,0,255,0.12) 83%,
rgba(255,0,150,0.12) 100%
);
border-image: linear-gradient(135deg,#f00,#ff8c00,#ff0,#0c0,#00f,#8b00ff,#ff69b4) 1;
}
.rainbow-bg .card-title { color: #e2e8f0; }
/* ── TWITTER EMBED WRAPPER ── */
.twitter-section {
margin-bottom: 32px;
}
.twitter-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
gap: 16px;
}
.twitter-embed-box {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
min-height: 480px;
}
.twitter-embed-box .embed-label {
padding: 10px 14px;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.5px;
text-transform: uppercase;
color: var(--muted);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 8px;
}
/* ── TRENDING TOPICS ── */
.trending { margin-bottom: 28px; }
.topic-pill {
display: inline-flex;
align-items: center;
background: var(--card);
border: 1px solid var(--border);
border-radius: 20px;
padding: 5px 12px;
font-size: 0.78rem;
margin: 4px 4px 0 0;
cursor: pointer;
transition: background 0.2s;
}
.topic-pill:hover { background: var(--border); }
.topic-pill::before { content: '#'; color: var(--accent); margin-right: 3px; }
/* ── STATS ── */
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
margin-bottom: 28px;
}
.stat-box {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px;
text-align: center;
}
.stat-box .num { font-size: 1.5rem; font-weight: 700; color: var(--accent); }
.stat-box .lbl { font-size: 0.7rem; color: var(--muted); margin-top: 2px; }
/* ── SOURCE BADGES in sidebar ── */
.source-status {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 10px 12px;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 10px;
font-size: 0.8rem;
}
a.source-link {
text-decoration: none;
color: inherit;
transition: border-color 0.15s, background 0.15s;
cursor: pointer;
}
a.source-link:hover {
border-color: var(--accent);
background: rgba(239,68,68,0.07);
}
.status-dot {
width: 8px; height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.dot-ok { background: #22c55e; box-shadow: 0 0 6px #22c55e; }
.dot-err { background: #ef4444; box-shadow: 0 0 6px #ef4444; }
.dot-loading { background: #f59e0b; box-shadow: 0 0 6px #f59e0b; animation: pulse 1s infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }
/* ── LOADER ── */
.spinner {
display: flex;
align-items: center;
justify-content: center;
padding: 60px;
flex-direction: column;
gap: 16px;
color: var(--muted);
}
.spin {
width: 36px; height: 36px;
border: 3px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* ── EMPTY / ERROR ── */
.empty {
text-align: center;
padding: 48px 24px;
color: var(--muted);
font-size: 0.9rem;
}
/* ── PARTY TREE ── */
.party-tree { padding: 8px 0 32px; }
.tree-root { display: flex; flex-direction: column; align-items: center; }
.tree-node {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.tree-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 14px 18px;
display: flex;
align-items: center;
gap: 14px;
width: 280px;
cursor: default;
transition: box-shadow 0.2s;
}
.tree-card:hover { box-shadow: 0 4px 20px rgba(0,0,0,0.4); }
.tree-card.root-card {
width: 320px;
border-color: var(--accent);
box-shadow: 0 0 16px rgba(59,130,246,0.3);
}
.tree-card.pis-card { border-color: #1e40af; }
.tree-card.ko-card { border-color: #f59e0b; }
.tree-card.kkp-card { border-color: #dc2626; }
.tree-card.konf-card { border-color: #f97316; }
.tree-avatar {
width: 52px; height: 52px;
border-radius: 50%;
object-fit: cover;
object-position: top;
background: var(--border);
flex-shrink: 0;
}
.tree-avatar.initials {
display: flex; align-items: center; justify-content: center;
font-size: 1.1rem; font-weight: 700; color: #fff;
}
.tree-info { flex: 1; min-width: 0; }
.tree-name { font-size: 0.9rem; font-weight: 700; }
.tree-role { font-size: 0.72rem; color: var(--muted); margin-top: 2px; line-height: 1.3; }
.tree-merit { font-size: 0.7rem; color: #86efac; margin-top: 4px; line-height: 1.3; }
.tree-fail { font-size: 0.7rem; color: #fca5a5; margin-top: 4px; line-height: 1.3; }
.tree-bio { font-size: 0.72rem; color: #64748b; margin-top: 5px; display: flex; gap: 4px; flex-wrap: wrap; }
.tree-bio span { background: rgba(255,255,255,0.06); border-radius: 4px; padding: 1px 6px; }
/* Connector lines */
.tree-line-down {
width: 2px; height: 24px;
background: var(--border);
}
.tree-children {
display: flex;
gap: 16px;
flex-wrap: wrap;
justify-content: center;
position: relative;
}
.tree-children::before {
content: '';
position: absolute;
top: 0; left: 16px; right: 16px;
height: 2px;
background: var(--border);
}
.tree-child-wrap {
display: flex;
flex-direction: column;
align-items: center;
}
.tree-child-wrap::before {
content: '';
width: 2px; height: 24px;
background: var(--border);
}
.tree-section {
width: 100%;
max-width: 1100px;
margin-top: 8px;
}
.tree-section-title {
font-size: 0.85rem;
font-weight: 700;
color: var(--accent);
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 8px 12px;
background: rgba(59,130,246,0.08);
border-left: 3px solid var(--accent);
border-radius: 0 6px 6px 0;
margin-bottom: 10px;
}
.tree-section-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
gap: 10px;
margin-bottom: 8px;
}
.tree-section-grid .tree-card {
width: 100%;
}
/* ── SCROLL BAR ── */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
/* ── POLITICIAN TICKER (top banner) ── */
.pol-ticker-wrap {
background: linear-gradient(90deg, #7f0000 0%, #b00000 50%, #7f0000 100%);
border-bottom: 3px solid #fff;
display: flex;
align-items: stretch;
height: 58px;
overflow: hidden;
position: fixed;
top: 0; left: 0; right: 0;
z-index: 110;
}
.pol-ticker-scroll {
flex: 1;
overflow: hidden;
position: relative;
}
.pol-ticker-scroll::after {
content: '';
position: absolute;
right: 0; top: 0; bottom: 0;
width: 70px;
background: linear-gradient(270deg, #7f0000, transparent);
pointer-events: none;
z-index: 1;
}
.pol-ticker-inner {
display: flex;
align-items: center;
white-space: nowrap;
height: 100%;
will-change: transform;
}
.pol-ticker-item {
display: inline-flex;
align-items: center;
gap: 11px;
padding: 0 30px;
flex-shrink: 0;
}
.pol-ticker-item img {
width: 34px;
height: 44px;
object-fit: cover;
object-position: top;
border-radius: 5px;
border: 2px solid rgba(255,255,255,0.65);
flex-shrink: 0;
}
.pol-ticker-text {
display: flex;
flex-direction: column;
gap: 2px;
}
.pol-ticker-name {
font-size: 0.88rem;
font-weight: 900;
color: #fff;
letter-spacing: 0.4px;
text-shadow: 1px 1px 4px rgba(0,0,0,0.9);
}
.pol-ticker-quote {
font-size: 0.78rem;
color: rgba(255,255,220,0.92);
font-style: italic;
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
text-shadow: 1px 1px 3px rgba(0,0,0,0.8);
}
.pol-ticker-sep {
color: rgba(255,220,100,0.6);
font-size: 1.3rem;
padding: 0 4px;
flex-shrink: 0;
}
/* ── TUSK NEWS TICKER (bottom fixed bar) ── */
body { padding-bottom: 56px; }
.tusk-ticker-bar {
position: fixed;
bottom: 0; left: 0; right: 0;
height: 54px;
background: #080808;
border-top: 2px solid #dc2626;
z-index: 1100;
display: flex;
align-items: center;
overflow: hidden;
box-shadow: 0 -4px 20px rgba(220,38,38,0.2);
}
.tusk-ticker-channel {
flex-shrink: 0;
background: #0f1117;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border-right: 2px solid #dc2626;
padding: 0 10px;
}
.tusk-ticker-channel img {
height: 38px;
width: auto;
object-fit: contain;
display: block;
}
.tusk-ticker-scroll {
flex: 1;
overflow: hidden;
height: 100%;
position: relative;
}
.tusk-ticker-inner {
display: flex;
align-items: center;
white-space: nowrap;
height: 100%;
will-change: transform;
}
.tusk-ticker-news {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 0 18px;
flex-shrink: 0;
}
.tusk-tt-sep { color: #22c55e; padding: 0 6px; font-size: 1rem; font-weight: 700; }
.tusk-tt-title {
color: #ffffff;
font-size: 1.4rem;
font-weight: 700;
max-width: none;
}
@keyframes glow {
from { text-shadow: 2px 2px 8px rgba(0,0,0,0.6), 0 0 10px rgba(255,220,50,0.2); }
to { text-shadow: 2px 2px 8px rgba(0,0,0,0.6), 0 0 28px rgba(255,220,50,0.6), 0 0 50px rgba(255,150,0,0.3); }
}
/* ── GRA EMBED ── */
.game-wrap {
max-width: 1000px;
margin: 0 auto 24px;
background: #000;
border: 2px solid #065f46;
border-radius: 14px;
overflow: hidden;
box-shadow: 0 0 40px rgba(0,200,100,0.12);
}
.game-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
background: linear-gradient(90deg, #022c22, #064e3b);
border-bottom: 1px solid #065f46;
}
.game-title { font-size: 1.1rem; font-weight: 800; color: #6ee7b7; letter-spacing: 1px; }
.game-sub { font-size: 0.72rem; color: #34d399; margin-top: 2px; }
.game-fs-btn {
background: #065f46; color: #6ee7b7; border: 1px solid #34d399;
border-radius: 7px; padding: 6px 14px; cursor: pointer;
font-size: 0.8rem; font-weight: 600;
transition: background 0.15s;
}
.game-fs-btn:hover { background: #047857; }
.game-frame-wrap {
position: relative;
width: 100%;
/* 16:9 aspect ratio for 1280×720 canvas */
aspect-ratio: 16 / 9;
background: #000;
}
.game-frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border: none;
display: block;
}
.game-footer {
padding: 8px 16px;
font-size: 0.72rem;
color: var(--muted);
background: #011711;
border-top: 1px solid #065f46;
}
/* ── SMOLEŃSK CANDLES ── */
.sm-candles {
font-size: 1.6rem;
letter-spacing: 4px;
margin: 8px 0;
animation: candleFlicker 2.5s ease-in-out infinite alternate;
filter: drop-shadow(0 0 8px rgba(255,200,50,0.7));
}
@keyframes candleFlicker {
0% { filter: drop-shadow(0 0 6px rgba(255,180,30,0.6)) brightness(1); }
25% { filter: drop-shadow(0 0 12px rgba(255,220,80,0.9)) brightness(1.15); }
50% { filter: drop-shadow(0 0 5px rgba(255,160,20,0.5)) brightness(0.92); }
75% { filter: drop-shadow(0 0 14px rgba(255,230,100,1)) brightness(1.2); }
100% { filter: drop-shadow(0 0 8px rgba(255,200,50,0.7)) brightness(1); }
}
/* ── COUNTDOWN ── */
.sm-countdown-wrap {
margin: 16px auto 4px;
max-width: 780px;
}
.sm-countdown-label {
font-size: 0.72rem;
color: #f87171;
letter-spacing: 1px;
text-transform: uppercase;
margin-bottom: 8px;
font-weight: 700;
}
.sm-countdown {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
gap: 4px;
font-variant-numeric: tabular-nums;
}
.cd-unit {
display: flex;
flex-direction: column;
align-items: center;
background: rgba(0,0,0,0.35);
border: 1px solid rgba(239,68,68,0.3);
border-radius: 8px;
padding: 4px 10px 5px;
min-width: 56px;
}
.cd-ms { min-width: 64px; }
.cd-n {
font-size: 1.4rem;
font-weight: 800;
color: #fca5a5;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.cd-l {
font-size: 0.6rem;
color: #ef4444;
letter-spacing: 0.5px;
text-transform: uppercase;
margin-top: 2px;
}
.cd-sep { color: #7f1d1d; font-size: 1.1rem; margin-bottom: 6px; }
/* ── TUPOLEW DIAGRAM ── */
.tu154-wrap {
background: #070c18;
border: 1px solid #1e3a8a;
border-radius: 12px;
overflow: hidden;
}
.tu154-svg { width: 100%; display: block; max-height: 340px; }
.tu-fuselage { fill: url(#fus-grad); stroke: #6b7280; stroke-width: 1.5; }
.tu-fuselage:hover { fill: #4b5563; }
.tu-wing { fill: url(#wing-grad); stroke: #4b5563; stroke-width: 1.5; }
.tu-wing:hover { fill: #374151; }
.tu-vstab { fill: #334155; stroke: #4b5563; stroke-width: 1.5; }
.tu-vstab:hover { fill: #475569; }
.tu-hstab { fill: #334155; stroke: #4b5563; stroke-width: 1.5; }
.tu-hstab:hover { fill: #475569; }
.tu-engine { fill: #1e2d3d; stroke: #374151; stroke-width: 1.5; }
.tu-engine:hover { fill: #2d3f52; }
.tu-nose { fill: #4b5563; stroke: #6b7280; stroke-width: 1.5; }
.tu-nose:hover { fill: #6b7280; }
.tu154-legend {
display: flex; flex-wrap: wrap; gap: 8px;
padding: 8px 14px 10px;
border-top: 1px solid #1e3a8a;
background: rgba(0,0,0,0.3);
}
.tu154-leg-item {
font-size: 0.7rem; padding: 3px 8px; border-radius: 5px; font-weight: 600;
}
.tu154-leg-item.red { background: rgba(239,68,68,0.2); color: #fca5a5; border: 1px solid #ef4444; }
.tu154-leg-item.orange { background: rgba(245,158,11,0.2); color: #fcd34d; border: 1px solid #f59e0b; }
.tu154-leg-item.blue { background: rgba(147,197,253,0.15); color: #93c5fd; border: 1px solid #3b82f6; }
/* ── SMOLEŃSK MAP ── */
.sm-map-wrap {
background: #070c18;
border: 1px solid #1e3a8a;
border-radius: 14px;
overflow: hidden;
margin-bottom: 28px;
position: relative;
}
.sm-map-title {
padding: 10px 16px;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: #93c5fd;
border-bottom: 1px solid #1e3a8a;
display: flex;
align-items: center;
gap: 8px;
}
.sm-map-svg { width: 100%; display: block; }
.sm-map-svg .country-poland { fill: #1e3a8a; fill-opacity: 0.35; stroke: #3b82f6; stroke-width: 1.5; }
.sm-map-svg .country-belarus { fill: #374151; fill-opacity: 0.4; stroke: #4b5563; stroke-width: 1; }
.sm-map-svg .country-russia { fill: #1f2937; fill-opacity: 0.5; stroke: #374151; stroke-width: 1; }
.sm-map-svg .country-other { fill: #111827; fill-opacity: 0.6; stroke: #1f2937; stroke-width: 0.8; }
.sm-map-svg .sea { fill: #0c2340; fill-opacity: 0.9; }
.sm-map-svg text { font-family: 'Segoe UI', sans-serif; }
.map-marker {
cursor: pointer;
transition: all 0.2s;
}
.map-marker:hover circle { filter: brightness(1.4); }
.map-marker.crash-site circle { animation: crashPulse 2s infinite; }
@keyframes crashPulse {
0%,100% { r:10; opacity:1; }
50% { r:14; opacity:0.6; }
}
/* ── SMOLEŃSK TOOLTIP ── */
#sm-tooltip {
position: fixed;
z-index: 9998;
width: 340px;
background: #1a1d27;
border: 1px solid #3b82f6;
border-radius: 14px;
box-shadow: 0 16px 48px rgba(0,0,0,0.8), 0 0 20px rgba(59,130,246,0.15);
pointer-events: none;
opacity: 0;
transform: scale(0.93) translateY(8px);
transition: opacity 0.16s, transform 0.16s;
overflow: hidden;
}
#sm-tooltip.vis {
opacity: 1;
transform: scale(1) translateY(0);
}
#sm-tooltip .st-photo {
width: 100%; height: 180px;
object-fit: cover; object-position: top;
display: block;
background: var(--border);
}
#sm-tooltip .st-photo-placeholder {
width: 100%; height: 180px;
display: flex; align-items: center; justify-content: center;
font-size: 4rem;
background: linear-gradient(135deg, #0f172a, #1e2d4a);
}
#sm-tooltip .st-body { padding: 14px 16px 16px; }
#sm-tooltip .st-name { font-size: 1rem; font-weight: 800; color: #fff; margin-bottom: 3px; }
#sm-tooltip .st-role { font-size: 0.72rem; color: #93c5fd; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
#sm-tooltip .st-desc { font-size: 0.8rem; color: var(--text); line-height: 1.6; }
#sm-tooltip .st-tag { display: inline-block; margin-top: 10px; padding: 3px 9px; border-radius: 5px; font-size: 0.7rem; font-weight: 700; }
/* ── SMOLEŃSK PAGE ── */
.smolensk-page { max-width: 1100px; margin: 0 auto; padding-bottom: 48px; }
.sm-hero {
background: linear-gradient(135deg, #1a0000 0%, #3b0000 50%, #1a0000 100%);
border: 1px solid #7f1d1d;
border-radius: 16px;
padding: 32px 28px;
margin-bottom: 28px;
text-align: center;
position: relative;
overflow: hidden;
}
.sm-hero::before {
content: '✝';
position: absolute;
font-size: 14rem;
color: rgba(255,255,255,0.03);
top: -30px; right: -20px;
pointer-events: none;
}
.sm-hero-date { font-size: 0.8rem; letter-spacing: 3px; color: #fca5a5; text-transform: uppercase; margin-bottom: 8px; }
.sm-hero-title { font-size: 2rem; font-weight: 900; color: #fff; margin-bottom: 6px; text-shadow: 0 0 30px rgba(220,38,38,0.5); }
.sm-hero-sub { font-size: 0.9rem; color: #fca5a5; max-width: 700px; margin: 0 auto; line-height: 1.7; }
.sm-hero-stats { display: flex; justify-content: center; gap: 32px; margin-top: 24px; flex-wrap: wrap; }
.sm-stat { text-align: center; }
.sm-stat .n { font-size: 2.2rem; font-weight: 900; color: #ef4444; }
.sm-stat .l { font-size: 0.72rem; color: #fca5a5; letter-spacing: 1px; text-transform: uppercase; }
.sm-section { margin-bottom: 32px; }
.sm-section-title {
font-size: 1rem; font-weight: 800; color: #fff;
border-left: 4px solid #ef4444;
padding: 8px 14px;
background: rgba(239,68,68,0.08);
border-radius: 0 8px 8px 0;
margin-bottom: 16px;
letter-spacing: 0.5px;
}
/* Macierewicz report table */
.sm-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.sm-table th { background: #1e3a8a; color: #fff; padding: 10px 12px; text-align: left; font-size: 0.75rem; letter-spacing: 0.5px; }
.sm-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); color: var(--text); vertical-align: top; }
.sm-table tr:nth-child(even) td { background: rgba(255,255,255,0.02); }
.sm-table tr:hover td { background: rgba(239,68,68,0.06); }
.sm-table .teza { font-weight: 600; color: #fca5a5; }
.sm-table .dowod { color: #94a3b8; font-size: 0.78rem; }
.sm-table .status-c { color: #f59e0b; font-weight: 600; }
/* Victims grid */
.victims-featured { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; margin-bottom: 20px; }
.victim-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
text-align: center;
transition: transform 0.2s, box-shadow 0.2s;
}
.victim-card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.4); }
.victim-card.pis { border-color: #1e3a8a; box-shadow: 0 0 10px rgba(30,58,138,0.3); }
.victim-card.president { border-color: #dc2626; box-shadow: 0 0 14px rgba(220,38,38,0.4); }
.victim-card img { width: 100%; height: 140px; object-fit: cover; object-position: top; background: var(--border); display: block; }
.victim-card .vc-body { padding: 10px; }
.victim-card .vc-name { font-size: 0.82rem; font-weight: 700; color: #fff; margin-bottom: 3px; }
.victim-card .vc-role { font-size: 0.7rem; color: var(--muted); line-height: 1.3; }
.victim-card .vc-party { font-size: 0.65rem; font-weight: 700; border-radius: 3px; padding: 2px 6px; margin-top: 5px; display: inline-block; }
.vc-pis { background: rgba(30,58,138,0.3); color: #93c5fd; }
.vc-pres { background: rgba(220,38,38,0.3); color: #fca5a5; }
.vc-other { background: rgba(100,100,100,0.2); color: #cbd5e1; }
.vc-mil { background: rgba(21,128,61,0.25); color: #86efac; }
.vc-sld { background: rgba(220,38,38,0.2); color: #fda4af; }
.victims-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.victims-table th { background: #374151; color: #e5e7eb; padding: 8px 10px; text-align: left; font-size: 0.72rem; }
.victims-table td { padding: 7px 10px; border-bottom: 1px solid rgba(255,255,255,0.05); color: var(--text); }
.victims-table tr.pis-row td { background: rgba(30,58,138,0.08); }
.victims-table tr.pres-row td { background: rgba(220,38,38,0.1); font-weight: 600; }
.victims-table .lp { color: var(--muted); font-size: 0.7rem; }
/* Timeline */
.sm-timeline { position: relative; padding-left: 28px; }
.sm-timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0; width: 2px; background: var(--border); }
.sm-tl-item { position: relative; margin-bottom: 18px; }
.sm-tl-item::before { content: ''; position: absolute; left: -24px; top: 4px; width: 10px; height: 10px; border-radius: 50%; background: #ef4444; box-shadow: 0 0 8px rgba(239,68,68,0.5); }
.sm-tl-time { font-size: 0.7rem; color: #ef4444; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 2px; }
.sm-tl-text { font-size: 0.82rem; color: var(--text); line-height: 1.5; }
.sm-tl-bad { color: #fca5a5; }
/* Tusk-Putin section */
.tp-box {
background: linear-gradient(135deg, rgba(0,0,0,0.4), rgba(30,0,0,0.4));
border: 1px solid #7f1d1d;
border-radius: 14px;
padding: 20px;
display: grid;
grid-template-columns: 280px 1fr;
gap: 20px;
align-items: center;
}
.tp-photo-wrap { position: relative; border-radius: 10px; overflow: hidden; aspect-ratio: 4/3; background: #1a1d27; display: flex; align-items: center; justify-content: center; }
.tp-photo-wrap img { width: 100%; height: 100%; object-fit: cover; }
.tp-photo-placeholder { font-size: 3rem; }
.tp-text h3 { font-size: 1.1rem; font-weight: 800; color: #fca5a5; margin-bottom: 10px; }
.tp-text p { font-size: 0.83rem; color: var(--text); line-height: 1.65; margin-bottom: 10px; }
.tp-tag { display: inline-block; background: rgba(239,68,68,0.15); color: #fca5a5; border: 1px solid rgba(239,68,68,0.3); border-radius: 6px; padding: 4px 12px; font-size: 0.75rem; font-weight: 700; }
/* Versions comparison */
.versions-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.version-box { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 16px; }
.version-box.official { border-color: #374151; }
.version-box.macierewicz { border-color: #1e3a8a; }
.version-box h4 { font-size: 0.85rem; font-weight: 700; margin-bottom: 10px; }
.version-box.official h4 { color: #94a3b8; }
.version-box.macierewicz h4 { color: #93c5fd; }
.version-box ul { list-style: none; font-size: 0.78rem; color: var(--text); line-height: 1.6; }
.version-box ul li::before { content: '▸ '; }
.version-box.macierewicz ul li::before { content: '🔴 '; }
@media (max-width: 768px) {
.tp-box { grid-template-columns: 1fr; }
.versions-grid { grid-template-columns: 1fr; }
.victims-featured { grid-template-columns: repeat(2, 1fr); }
}
/* ── RESPONSIVE ── */
@media (max-width: 900px) {
.layout { margin-right: 0; }
.sidebar { display: none; }
.articles-grid { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
header { padding: 12px 16px; }
.feed { padding: 14px 16px; }
.logo h1 { font-size: 1rem; }
.pol-ticker-wrap { height: 52px; }
.pol-ticker-quote { max-width: 180px; }
}
/* ── WIELCY POLACY ── */
.wielcy-page { max-width: 1200px; margin: 0 auto; padding-bottom: 60px; }
.wielcy-hero {
background: linear-gradient(135deg, #1a1200 0%, #2d2000 50%, #1a1200 100%);
border: 1px solid #d97706; border-radius: 16px; padding: 32px 28px;
margin-bottom: 24px; text-align: center; position: relative; overflow: hidden;
}
.wielcy-hero::before { content:'🏆'; position:absolute; font-size:13rem; opacity:0.05; top:-20px; right:-10px; pointer-events:none; }
.wielcy-hero-title { font-size: 2rem; font-weight: 900; color: #fbbf24; text-shadow: 0 0 30px rgba(251,191,36,0.5); margin-bottom: 6px; }
.wielcy-hero-sub { font-size: 0.9rem; color: #fcd34d; max-width: 700px; margin: 0 auto; line-height: 1.7; }
.wielcy-stats { display:flex; justify-content:center; gap:32px; margin-top:20px; flex-wrap:wrap; }
.wielcy-stat .n { font-size:2.2rem; font-weight:900; color:#fbbf24; }
.wielcy-stat .l { font-size:0.72rem; color:#fcd34d; letter-spacing:1px; text-transform:uppercase; }
.wielcy-filters { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:20px; }
.wielcy-filter-btn {
border:1px solid rgba(255,255,255,0.15); border-radius:20px; padding:5px 14px;
cursor:pointer; font-size:0.8rem; font-weight:600; background:rgba(0,0,0,0.3);
color:var(--muted); transition:all 0.2s;
}
.wielcy-filter-btn.active, .wielcy-filter-btn:hover { color:#fff; border-color:rgba(255,255,255,0.5); background:rgba(255,255,255,0.1); }
.wielcy-filter-btn[data-kat="Nobel"].active { background:#d97706; border-color:#d97706; color:#fff; }
.wielcy-filter-btn[data-kat="Sport"].active { background:#16a34a; border-color:#16a34a; color:#fff; }
.wielcy-filter-btn[data-kat="Nauka"].active { background:#1d4ed8; border-color:#1d4ed8; color:#fff; }
.wielcy-filter-btn[data-kat="Kultura"].active { background:#7c3aed; border-color:#7c3aed; color:#fff; }
.wielcy-filter-btn[data-kat="Historia"].active { background:#7f1d1d; border-color:#7f1d1d; color:#fff; }
.wielcy-timeline { display:flex; flex-direction:column; gap:0; }
.wielcy-decade { font-size:0.7rem; font-weight:900; letter-spacing:3px; color:#fbbf24;
text-transform:uppercase; padding:16px 0 8px; border-bottom:1px solid rgba(217,119,6,0.25); margin-bottom:12px; }
.wielcy-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:12px; margin-bottom:8px; }
.wielcy-card {
background:var(--card); border-radius:12px; overflow:hidden;
display:flex; gap:0; border:1px solid var(--border); transition:border-color 0.2s, transform 0.15s;
}
.wielcy-card:hover { transform:translateY(-2px); }
.wielcy-card.sport { border-left:4px solid #16a34a; }
.wielcy-card.sport:hover { border-color:#16a34a; }
.wielcy-card.Nobel { border-left:4px solid #d97706; }
.wielcy-card.Nobel:hover { border-color:#d97706; }
.wielcy-card.Nauka { border-left:4px solid #1d4ed8; }
.wielcy-card.Nauka:hover { border-color:#1d4ed8; }
.wielcy-card.Kultura { border-left:4px solid #7c3aed; }
.wielcy-card.Kultura:hover { border-color:#7c3aed; }
.wielcy-card.Historia{ border-left:4px solid #ef4444; }
.wielcy-card.Historia:hover{ border-color:#ef4444; }
.wielcy-card-icon {
width:70px; min-width:70px; display:flex; flex-direction:column;
align-items:center; justify-content:center; gap:4px; padding:12px 6px;
font-size:1.8rem; background:rgba(0,0,0,0.2);
}
.wielcy-card-year { font-size:0.62rem; font-weight:700; color:var(--muted); letter-spacing:1px; }
.wielcy-card-body { padding:12px 14px; flex:1; min-width:0; }
.wielcy-card-name { font-size:0.95rem; font-weight:800; color:#fff; margin-bottom:3px; }
.wielcy-card-achievement { font-size:0.8rem; font-weight:700; margin-bottom:5px; }
.wielcy-card-desc { font-size:0.75rem; color:var(--muted); line-height:1.55; }
.wielcy-card-badge {
display:inline-block; font-size:0.62rem; font-weight:700; padding:2px 7px;
border-radius:4px; margin-top:5px; color:#fff;
}
.badge-sport { background:#166534; }
.badge-Nobel { background:#92400e; }
.badge-Nauka { background:#1e3a8a; }
.badge-Kultura { background:#581c87; }
.badge-Historia{ background:#7f1d1d; }
/* ── ŚW. JAN PAWEŁ II PAGE ── */
.jp2-page { max-width: 1200px; margin: 0 auto; padding-bottom: 60px; }
.jp2-hero {
background: linear-gradient(135deg, #0a0f2e 0%, #1a1560 40%, #7c1d1d 100%);
border-radius: 16px; padding: 40px 32px 32px; text-align: center; margin-bottom: 32px;
position: relative; overflow: hidden; border: 2px solid #fbbf24;
}
.jp2-hero::before { content:'✝'; position:absolute; font-size:20rem; opacity:0.04; top:-60px; right:-40px; pointer-events:none; color:#fbbf24; }
.jp2-hero-title { font-size:2.2rem; font-weight:900; color:#fbbf24; text-shadow:0 0 40px rgba(251,191,36,0.7); margin-bottom:8px; }
.jp2-hero-sub { font-size:1rem; color:#fcd34d; line-height:1.7; max-width:800px; margin:0 auto 20px; }
.jp2-stats { display:flex; justify-content:center; gap:28px; flex-wrap:wrap; margin-top:16px; }
.jp2-stat .n { font-size:2rem; font-weight:900; color:#fbbf24; }
.jp2-stat .l { font-size:0.7rem; color:#fcd34d; letter-spacing:1.2px; text-transform:uppercase; }
.jp2-section { margin-bottom:36px; }
.jp2-section-title {
font-size:1.1rem; font-weight:900; color:#fbbf24; letter-spacing:1px;
border-left:4px solid #fbbf24; padding-left:12px; margin-bottom:20px;
display:flex; align-items:center; gap:10px;
}
/* Timeline */
.jp2-timeline { position:relative; padding-left:32px; }
.jp2-timeline::before { content:''; position:absolute; left:10px; top:0; bottom:0; width:2px; background:linear-gradient(180deg,#fbbf24,#1e3a8a,#dc2626); }
.jp2-tl-item { position:relative; margin-bottom:20px; }
.jp2-tl-dot { position:absolute; left:-27px; top:8px; width:14px; height:14px; border-radius:50%; background:#fbbf24; border:3px solid #0f1117; box-shadow:0 0 8px rgba(251,191,36,0.6); }
.jp2-tl-dot.blue { background:#3b82f6; box-shadow:0 0 8px rgba(59,130,246,0.6); }
.jp2-tl-dot.red { background:#dc2626; box-shadow:0 0 8px rgba(220,38,38,0.6); }
.jp2-tl-card {
background: var(--card); border:1px solid var(--border); border-radius:10px;
padding:12px 16px; transition:border-color 0.2s;
}
.jp2-tl-card:hover { border-color:#fbbf24; }
.jp2-tl-year { font-size:0.65rem; font-weight:900; color:#fbbf24; letter-spacing:2px; margin-bottom:3px; }
.jp2-tl-title { font-size:0.92rem; font-weight:800; color:#fff; margin-bottom:4px; }
.jp2-tl-desc { font-size:0.78rem; color:var(--muted); line-height:1.55; }
/* Map */
.jp2-map-wrap { border-radius:12px; overflow:hidden; border:2px solid #fbbf24; height:500px; }
.jp2-map-legend { display:flex; gap:16px; flex-wrap:wrap; margin-top:10px; }
.jp2-map-legend-item { display:flex; align-items:center; gap:6px; font-size:0.75rem; color:var(--muted); }
.jp2-map-legend-dot { width:12px; height:12px; border-radius:50%; flex-shrink:0; }
/* Leaflet popup override */
.jp2-popup { max-width:240px; font-family:'Segoe UI',sans-serif; }
.jp2-popup-img { width:100%; border-radius:6px; margin-bottom:8px; max-height:130px; object-fit:cover; display:block; }
.jp2-popup-title { font-weight:800; color:#1e3a8a; font-size:0.85rem; margin-bottom:4px; }
.jp2-popup-desc { font-size:0.75rem; color:#374151; line-height:1.5; }
/* Polish pilgrimages list */
.jp2-pilgr-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:12px; }
.jp2-pilgr-card {
background:var(--card); border:1px solid var(--border); border-radius:10px;
padding:14px; border-left:4px solid #fbbf24; transition:border-color 0.2s;
}
.jp2-pilgr-card:hover { border-color:#3b82f6; }
.jp2-pilgr-n { font-size:0.6rem; font-weight:900; color:#fbbf24; letter-spacing:2px; }
.jp2-pilgr-title { font-size:0.9rem; font-weight:800; color:#fff; margin:4px 0; }
.jp2-pilgr-desc { font-size:0.78rem; color:var(--muted); line-height:1.5; }
.jp2-pilgr-quote { font-size:0.78rem; font-style:italic; color:#fcd34d; margin-top:6px; border-left:2px solid #fbbf24; padding-left:8px; }
/* Gallery */
.jp2-gallery-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:14px; }
.jp2-gal-card {
background:var(--card); border:1px solid var(--border); border-radius:10px;
overflow:hidden; text-align:center; transition:transform 0.2s,border-color 0.2s;
}
.jp2-gal-card:hover { transform:translateY(-2px); border-color:#fbbf24; }
.jp2-gal-img { width:100%; height:150px; object-fit:cover; object-position:top; display:block; }
.jp2-gal-placeholder { width:100%; height:150px; display:flex; align-items:center; justify-content:center; font-size:3rem; background:linear-gradient(135deg,#1e3a8a,#1a1d27); }
.jp2-gal-name { padding:8px 10px 4px; font-size:0.82rem; font-weight:700; color:#fff; }
.jp2-gal-desc { padding:0 10px 10px; font-size:0.72rem; color:var(--muted); line-height:1.4; }
/* Miracles */
.jp2-miracle-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:14px; }
.jp2-miracle-card {
background:linear-gradient(135deg,#1a1560,#0a0f2e); border:1px solid #fbbf24;
border-radius:12px; padding:16px; position:relative; overflow:hidden;
}
.jp2-miracle-card::before { content:attr(data-icon); position:absolute; font-size:5rem; opacity:0.08; right:-10px; top:-10px; pointer-events:none; }
.jp2-miracle-icon { font-size:1.6rem; margin-bottom:8px; }
.jp2-miracle-title { font-size:0.92rem; font-weight:900; color:#fbbf24; margin-bottom:6px; }
.jp2-miracle-desc { font-size:0.78rem; color:#e2e8f0; line-height:1.6; }
/* Counter */
.jp2-counter {
background:linear-gradient(135deg,#0f1117,#1a1d27); border:2px solid #dc2626;
border-radius:14px; padding:24px 28px;
}
.jp2-counter-title { font-size:1rem; font-weight:900; color:#fca5a5; margin-bottom:14px; display:flex; align-items:center; gap:8px; }
.jp2-counter-item { display:flex; gap:10px; margin-bottom:14px; }
.jp2-counter-bullet { font-size:1.2rem; flex-shrink:0; margin-top:2px; }
.jp2-counter-text { font-size:0.82rem; color:#e2e8f0; line-height:1.6; }
.jp2-counter-text b { color:#fca5a5; }
/* ── VIDEO PAGE ── */
.video-page { max-width: 1200px; margin: 0 auto; padding-bottom: 60px; }
.video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); gap: 18px; }
.video-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; transition: border-color 0.2s; }
.video-card:hover { border-color: #f97316; }
.video-card video { width: 100%; display: block; background: #000; max-height: 260px; }
.video-card-title { padding: 12px 14px; font-size: 0.88rem; font-weight: 600; color: var(--text); line-height: 1.4; }
/* ── TUSK DAILY PORTRAIT ── */
.tusk-portrait { max-width: 1200px; margin: 0 auto; padding-bottom: 48px; }
.tusk-portrait-header {
display: flex; align-items: center; gap: 24px;
background: linear-gradient(135deg, #1a0000 0%, #3b0000 60%, #1a0000 100%);
border: 1px solid #7f1d1d; border-radius: 16px;
padding: 28px 28px; margin-bottom: 24px; position: relative; overflow: hidden;
}
.tusk-portrait-header::before { content:'☭'; position:absolute; font-size:16rem; color:rgba(255,255,255,0.02); right:-30px; top:-40px; pointer-events:none; }
.tusk-portrait-photo { width: 100px; height: 130px; object-fit: cover; border-radius: 10px; flex-shrink: 0; border: 2px solid #ef4444; filter: grayscale(20%); }
.tusk-portrait-intro { flex: 1; }
.tusk-portrait-intro .tp-date { font-size: 0.73rem; color: #fca5a5; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 4px; }
.tusk-portrait-intro h2 { font-size: 1.6rem; font-weight: 900; color: #fff; margin-bottom: 6px; text-shadow: 0 0 30px rgba(239,68,68,0.4); }
.tusk-portrait-intro .sub { font-size: 0.85rem; color: #fca5a5; line-height: 1.65; max-width: 700px; }
.tusk-portrait-stats { display: flex; gap: 28px; margin-top: 16px; flex-wrap: wrap; }
.tp-stat .n { font-size: 2rem; font-weight: 900; color: #ef4444; }
.tp-stat .l { font-size: 0.68rem; color: #fca5a5; letter-spacing: 1px; text-transform: uppercase; }
.tusk-section-head {
font-size: 1rem; font-weight: 800; color: #fff;
border-left: 4px solid #ef4444; padding: 8px 14px;
background: rgba(239,68,68,0.08); border-radius: 0 8px 8px 0;
margin: 24px 0 14px 0; letter-spacing: 0.5px;
}
.tusk-section-head.yellow { border-left-color: #f59e0b; background: rgba(245,158,11,0.08); }
.tusk-section-head.blue { border-left-color: #3b82f6; background: rgba(59,130,246,0.08); }
.tusk-fail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 12px; margin-bottom: 20px; }
.tusk-conn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; margin-bottom: 20px; }
.tusk-fail-card { background: rgba(0,0,0,0.3); border: 1px solid rgba(239,68,68,0.18); border-radius: 10px; padding: 14px; }
.tusk-conn-card { background: rgba(0,0,0,0.3); border-radius: 10px; padding: 14px; }
.tusk-conn-card.red { border: 1px solid rgba(239,68,68,0.3); }
.tusk-conn-card.yellow { border: 1px solid rgba(245,158,11,0.3); }
.tfc-cat { font-size: 0.64rem; letter-spacing: 2px; color: #fca5a5; text-transform: uppercase; margin-bottom: 3px; }
.tfc-cat.y { color: #fcd34d; }
.tfc-title { font-size: 0.88rem; font-weight: 700; color: #fff; margin-bottom: 8px; line-height: 1.35; }
.tusk-col-label { font-size: 0.63rem; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 3px; }
.tusk-col-label.red { color: #ef4444; }
.tusk-col-label.green { color: #22c55e; }
.tusk-fail-col { font-size: 0.78rem; line-height: 1.6; }
.tusk-col-tusk { color: #fca5a5; }
.tusk-col-pis { color: #86efac; }
.tusk-conn-desc { font-size: 0.78rem; color: #fca5a5; line-height: 1.6; }
.tusk-conn-desc.y { color: #fcd34d; }
.tusk-fail-divider { border: none; border-top: 1px solid rgba(239,68,68,0.18); margin: 9px 0; }
.tusk-timeline { border-left: 2px solid #7f1d1d; padding-left: 20px; margin-bottom: 20px; }
.tusk-tl-item { position: relative; padding-bottom: 18px; }
.tusk-tl-item::before { content:''; position:absolute; left:-26px; top:5px; width:10px; height:10px; border-radius:50%; background:#ef4444; border:2px solid #1a0000; }
.tusk-tl-year { font-size: 0.65rem; font-weight: 700; color: #f87171; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 2px; }
.tusk-tl-title { font-size: 0.88rem; font-weight: 700; color: #fff; margin-bottom: 4px; }
.tusk-tl-desc { font-size: 0.78rem; color: #fca5a5; line-height: 1.6; }
/* ── MAP ── */
#tusk-map { height: 500px; border-radius: 14px; border: 1px solid #7f1d1d; margin-bottom: 20px; z-index: 1; }
.leaflet-popup-content-wrapper { background: #1a1d27 !important; border: 1px solid #ef4444 !important; border-radius: 12px !important; color: #e2e8f0 !important; box-shadow: 0 8px 32px rgba(0,0,0,0.7) !important; }
.leaflet-popup-tip { background: #1a1d27 !important; }
.leaflet-popup-content { margin: 12px 14px !important; }
.map-pop { max-width: 240px; }
.map-pop-img { width: 100%; height: 130px; object-fit: cover; border-radius: 8px; margin-bottom: 8px; background: #2e334d; display: block; }
.map-pop-year { font-size: 0.65rem; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 3px; }
.map-pop-title { font-size: 0.9rem; font-weight: 700; color: #fff; margin-bottom: 6px; }
.map-pop-desc { font-size: 0.75rem; color: #fca5a5; line-height: 1.6; }
.map-pop-desc.y { color: #fcd34d; }
.map-pop-desc.g { color: #86efac; }
.map-legend { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; padding: 10px 0 6px; font-size: 0.78rem; color: var(--muted); }
.map-legend-item { display: flex; align-items: center; gap: 6px; }
.map-legend-dot { width: 13px; height: 13px; border-radius: 50%; flex-shrink: 0; border: 2px solid rgba(255,255,255,0.3); }
/* ── RESET z Rosją ── */
.reset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; margin-bottom: 20px; }
.reset-card { background: rgba(0,0,0,0.3); border: 1px solid rgba(239,68,68,0.25); border-radius: 10px; padding: 14px; }
.reset-card:hover { border-color: rgba(239,68,68,0.6); }
.reset-year { font-size: 0.64rem; font-weight: 700; letter-spacing: 2px; color: #f87171; text-transform: uppercase; margin-bottom: 3px; }
.reset-title { font-size: 0.88rem; font-weight: 700; color: #fff; margin-bottom: 7px; }
.reset-desc { font-size: 0.78rem; color: #fca5a5; line-height: 1.6; }
.tusk-news-strip { background: rgba(0,0,0,0.25); border: 1px solid rgba(127,29,29,0.3); border-radius: 10px; padding: 14px; margin-top: 8px; }
.tusk-news-strip h4 { font-size: 0.7rem; color: #fca5a5; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 10px; }
.tusk-news-item { font-size: 0.82rem; color: var(--text); padding: 5px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
.tusk-news-item:last-child { border-bottom: none; }
.tusk-news-item a { color: var(--text); text-decoration: none; }
.tusk-news-item a:hover { color: #ef4444; }
/* ── SEJM RP PAGE ── */
.sejm-page { max-width: 1200px; margin: 0 auto; padding-bottom: 60px; }
.sejm-hero {
background: linear-gradient(135deg, #071a0c 0%, #0d3320 50%, #071a0c 100%);
border: 1px solid #166534; border-radius: 16px;
padding: 32px 28px; margin-bottom: 28px; text-align: center;
position: relative; overflow: hidden;
}
.sejm-hero::before {
content: '⚖'; position: absolute; font-size: 14rem;
color: rgba(255,255,255,0.03); top: -30px; right: -20px; pointer-events: none;
}
.sejm-hero-title { font-size: 2rem; font-weight: 900; color: #fff; margin-bottom: 6px; text-shadow: 0 0 30px rgba(34,197,94,0.4); }
.sejm-hero-date { font-size: 0.8rem; letter-spacing: 3px; color: #86efac; text-transform: uppercase; margin-bottom: 8px; }
.sejm-hero-sub { font-size: 0.9rem; color: #86efac; max-width: 700px; margin: 0 auto; line-height: 1.7; }
.sejm-stats { display: flex; justify-content: center; gap: 32px; margin-top: 20px; flex-wrap: wrap; }
.sejm-stat { text-align: center; }
.sejm-stat .n { font-size: 2.2rem; font-weight: 900; color: #4ade80; }
.sejm-stat .l { font-size: 0.72rem; color: #86efac; letter-spacing: 1px; text-transform: uppercase; }
.sejm-section-title {
font-size: 1rem; font-weight: 800; color: #fff;
border-left: 4px solid #22c55e; padding: 8px 14px;
background: rgba(34,197,94,0.08); border-radius: 0 8px 8px 0;
margin: 24px 0 16px 0; letter-spacing: 0.5px;
}
.sejm-hemicycle-wrap {
background: var(--card); border: 1px solid var(--border);
border-radius: 16px; padding: 20px; margin-bottom: 24px;
overflow-x: auto; text-align: center;
}
.sejm-hemicycle-wrap .sejm-loading { padding: 60px 0; color: var(--muted); font-size: 0.9rem; }
.sejm-legend { display: flex; flex-wrap: wrap; gap: 10px 18px; justify-content: center; padding: 12px 0 4px; }
.sejm-legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; color: var(--text); }
.sejm-legend-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
.sejm-legend-count { color: var(--muted); font-size: 0.72rem; }
#sejm-tooltip {
position: fixed; pointer-events: none; z-index: 9999;
background: #1a1d27; border: 1px solid #3b82f6; border-radius: 14px;
padding: 14px; width: 190px; display: none;
box-shadow: 0 8px 32px rgba(0,0,0,0.6);
}
#sejm-tooltip img { width: 80px; height: 100px; object-fit: cover; border-radius: 8px; display: block; margin: 0 auto 10px; background: var(--border); }
#sejm-tooltip .stt-name { font-size: 0.85rem; font-weight: 700; color: #fff; text-align: center; line-height: 1.3; }
#sejm-tooltip .stt-club { font-size: 0.73rem; font-weight: 600; text-align: center; margin-top: 4px; padding: 2px 8px; border-radius: 4px; display: inline-block; }
#sejm-tooltip .stt-dist { font-size: 0.7rem; color: var(--muted); text-align: center; margin-top: 5px; }
#sejm-tooltip .stt-wrap { text-align: center; }
.minister-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.minister-card {
background: var(--card); border: 1px solid var(--border);
border-radius: 12px; padding: 16px;
display: flex; gap: 14px; align-items: flex-start;
transition: border-color 0.2s;
}
.minister-card:hover { border-color: #22c55e; }
.minister-photo { width: 72px; height: 90px; border-radius: 10px; object-fit: cover; flex-shrink: 0; background: var(--border); }
.minister-info { flex: 1; min-width: 0; }
.minister-name { font-size: 0.92rem; font-weight: 700; color: #fff; line-height: 1.3; }
.minister-role { font-size: 0.73rem; color: #4ade80; margin-top: 2px; font-weight: 600; }
.minister-ministry { font-size: 0.7rem; color: var(--muted); margin-top: 3px; }
.minister-desc { font-size: 0.72rem; color: var(--muted); margin-top: 7px; line-height: 1.55; }
.minister-party-badge { display: inline-block; margin-top: 6px; padding: 2px 8px; border-radius: 4px; font-size: 0.66rem; font-weight: 700; color: #fff; }
</style>
</head>
<body>
<!-- ══ POLITICIAN TICKER ══ -->
<div class="pol-ticker-wrap">
<div class="pol-ticker-scroll">
<div class="pol-ticker-inner" id="pol-ticker-inner"></div>
</div>
</div>
<!-- ══ HEADER ══ -->
<header>
<div class="logo">
<div class="logo-icon">📡</div>
<div>
<h1>Prawicowy Dashboard — Wielka Polska wróci, pogonimy Rudego</h1>
<span id="last-updated">Ładowanie...</span>
</div>
</div>
<div class="header-right">
<button id="refresh-btn" onclick="loadAll()">↻ Odśwież</button>
</div>
</header>
<!-- ══ RADIO BAR ══ -->
<div class="radio-bar">
<div class="radio-player">
<img src="img/radiomaryja.png" alt="Radio Maryja" class="radio-logo-img" onerror="this.style.opacity='0.4'">
<audio id="audio-maryja" preload="none" controls>
<source src="https://stream4.nadaje.com:9550/maryja" type="audio/mpeg">
<source src="https://stream1.nadaje.com:9550/maryja" type="audio/mpeg">
<source src="/api/radio/maryja" type="audio/aac">
</audio>
<span id="rm-status" class="radio-status-badge">NA ŻYWO</span>
</div>
<div class="radio-player">
<img src="img/republika.jpg" alt="Radio Republika" class="radio-logo-img" onerror="this.style.opacity='0.4'">
<audio id="audio-republika" preload="none" controls>
<source src="https://stream.radiotvrepublika.pl:8100/mp3" type="audio/mpeg">
<source src="https://stream.radiotvrepublika.pl:8100/stream" type="audio/mpeg">
</audio>
<span id="rr-status" class="radio-status-badge">NA ŻYWO</span>
</div>
</div>
<!-- ══ FILTERS ══ -->
<div class="filters">
<button class="filter-btn active" data-src="all" onclick="filterBy('all')">📰 Przekaz Dnia</button>
<button class="filter-btn" data-src="republika" onclick="filterBy('republika')">📺 Republika</button>
<button class="filter-btn" data-src="wpolsce" onclick="filterBy('wpolsce')">🎙 wPolsce24</button>
<button class="filter-btn" data-src="trwam" onclick="filterBy('trwam')">⛪ Trwam</button>
<button class="filter-btn" data-src="social" onclick="filterBy('social')">📣 Social Media</button>
<button class="filter-btn" data-src="smolensk" onclick="filterBy('smolensk')" style="background:#7f1d1d">✈ Smoleńsk</button>
<button class="filter-btn" data-src="gra" onclick="filterBy('gra')" style="background:#064e3b">🎮 Sejm Kombat</button>
<button class="filter-btn" data-src="opozycja" onclick="filterBy('opozycja')" style="background:#dc2626;font-weight:900">💀 TVN24 💀</button>
<button class="filter-btn" data-src="pis" onclick="filterBy('pis')" style="background:#1e3a8a">🦅 PiS</button>
<button class="filter-btn" data-src="ko" onclick="filterBy('ko')" style="background:#92400e">🟡 Koalicja</button>
<button class="filter-btn" data-src="kkp" onclick="filterBy('kkp')" style="background:#7c0000">⚡ KKP</button>
<button class="filter-btn" data-src="konf" onclick="filterBy('konf')" style="background:#b45309">🗽 Konfederacja</button>
<button class="filter-btn" data-src="sejm" onclick="filterBy('sejm')" style="background:#166534">⚖️ Sejm RP</button>
<button class="filter-btn" data-src="video" onclick="filterBy('video')" style="background:#c2410c">🎬 Wideo</button>
<button class="filter-btn" data-src="wielcy" onclick="filterBy('wielcy')" style="background:#92400e">🏆 Wielcy Polacy</button>
<button class="filter-btn" data-src="jp2" onclick="filterBy('jp2')" style="background:linear-gradient(135deg,#1e3a8a,#fbbf24);color:#fff;font-weight:900">✝ Św. Jan Paweł II</button>
</div>
<!-- ══ SEJM TOOLTIP ══ -->
<div id="sejm-tooltip">
<img id="sejm-tip-img" src="" alt="">
<div class="stt-wrap">
<div class="stt-name" id="sejm-tip-name"></div>
<div><span class="stt-club" id="sejm-tip-club"></span></div>
<div class="stt-dist" id="sejm-tip-dist"></div>
</div>
</div>
<!-- ══ LAYOUT ══ -->
<div class="layout">
<!-- ══ MAIN FEED ══ -->
<main class="feed">
<div id="feed-container">
<div class="spinner"><div class="spin"></div>Pobieranie artykułów...</div>
</div>
</main>
</div>
<!-- ══ FIXED MEDIA PANEL ══ -->
<aside class="sidebar">
<!-- ── Telewizja Republika ── -->
<div class="mp-section">
<div class="mp-header mp-header-republika">
<span class="mp-live-dot"></span>
<img src="img/republika.jpg" alt="Republika" class="mp-channel-logo" onerror="this.style.opacity='0.4'">
<span class="mp-name">Telewizja Republika</span>
<span class="mp-live-badge">NA ŻYWO</span>
</div>
<div class="mp-video-wrap">
<iframe
src="https://www.youtube.com/embed/dzntyCTgJMQ?autoplay=0&mute=1&rel=0&modestbranding=1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen title="Telewizja Republika na żywo">
</iframe>
</div>
</div>
<!-- ── W Polsce 24 ── -->
<div class="mp-section">
<div class="mp-header mp-header-wpolsce">
<span class="mp-live-dot"></span>
<img src="img/wpolsce24.png" alt="wPolsce24" class="mp-channel-logo" onerror="this.style.opacity='0.4'">
<span class="mp-name">W Polsce 24</span>
<span class="mp-live-badge">NA ŻYWO</span>
</div>
<div class="mp-video-wrap">
<iframe
src="https://www.youtube.com/embed/CINoVvpEAyk?autoplay=0&mute=1&rel=0&modestbranding=1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen title="W Polsce 24 na żywo">
</iframe>
</div>
</div>
</aside>
<script>
// ══════════════════════════════════════════════
// CONFIG — lokalny serwer RSS proxy
// ══════════════════════════════════════════════
const SOURCES = [
{ id:'republika', name:'Telewizja Republika', icon:'📺', cssClass:'src-republika', dotId:'dot-republika', groupId:'republika' },
{ id:'wpolsce', name:'Niezależna.pl', icon:'🎙', cssClass:'src-wpolsce', dotId:'dot-wpolsce', groupId:'wpolsce' },
{ id:'trwam', name:'Radio Maryja / Trwam',icon:'⛪', cssClass:'src-trwam', dotId:'dot-trwam', groupId:'trwam' },
];
// Social media — statyczne (Twitter/X nie ma publicznego RSS; pokazujemy jako linki)
const SOCIAL_ACCOUNTS = [
{ name: 'Przemysław Czarnek', handle: 'CzarnekP', platform: 'X/Twitter', url: 'https://x.com/CzarnekP' },
{ name: 'Donald Trump', handle: 'realDonaldTrump', platform: 'Truth Social', url: 'https://truthsocial.com/@realDonaldTrump' },
{ name: 'Mariusz Błaszczak', handle: 'mblaszczak', platform: 'X/Twitter', url: 'https://x.com/mblaszczak' },
{ name: 'Jarosław Kaczyński', handle: 'pisorgpl', platform: 'X/Twitter', url: 'https://x.com/pisorgpl' },
];
// Memy polityczne — lokalne zdjęcia
const MEMES = [
{ name:'Karol Nawrocki', handle:'@KarolNawrocki_', platform:'X/Twitter', url:'https://x.com/KarolNawrocki_', avatar:'img/nawrocki.jpg', photo:'img/nawrocki.jpg', caption:'🇵🇱 Polska musi mieć prezydenta, który służy narodowi — nie brukselskim biurokratom. Bóg · Honor · Ojczyzna!', likes:'12,3k', date:'dziś' },
{ name:'Karol Nawrocki', handle:'@KarolNawrocki_', platform:'X/Twitter', url:'https://x.com/KarolNawrocki_', avatar:'img/nawrocki.jpg', photo:'img/nawrocki.jpg', caption:'✝ Polska jest i pozostanie krajem chrześcijańskim. Maryja Królowa Polski — to nasza tożsamość!', likes:'9,8k', date:'dziś' },
{ name:'Przemysław Czarnek',handle:'@CzarnekP', platform:'X/Twitter', url:'https://x.com/CzarnekP', avatar:'img/czarnek.jpg', photo:'img/czarnek.jpg', caption:'Polska szkoła musi kształtować pokolenia, które będą kochać Ojczyznę i wyznawać jej wartości.', likes:'2,4k', date:'dziś' },
{ name:'Donald Trump', handle:'@realDonaldTrump', platform:'Truth Social',url:'https://truthsocial.com/@realDonaldTrump', avatar:'img/trump.jpg', photo:'img/trump.jpg', caption:'Make America Great Again! We will restore our borders, economy, and sovereignty.', likes:'48k', date:'dziś' },
{ name:'Jarosław Kaczyński',handle:'@pisorgpl', platform:'X/Twitter', url:'https://x.com/pisorgpl', avatar:'img/kaczynski.jpg',photo:'img/kaczynski.jpg',caption:'Polska jest i będzie niepodległa. Będziemy walczyć o suwerenność naszego narodu.', likes:'5,1k', date:'wczoraj' },
{ name:'Mariusz Błaszczak', handle:'@mblaszczak', platform:'X/Twitter', url:'https://x.com/mblaszczak', avatar:'img/blaszczak.jpg',photo:'img/blaszczak.jpg',caption:'Bezpieczeństwo Polski to nasz priorytet. Wzmacniamy Wojsko Polskie każdego dnia.', likes:'1,8k', date:'wczoraj' },
{ name:'Zbigniew Ziobro', handle:'@ZbigniewZiobro', platform:'X/Twitter', url:'https://x.com/ZbigniewZiobro', avatar:'img/ziobro.jpg', photo:'img/ziobro.jpg', caption:'Praworządność to nie lewacka ideologia — to Konstytucja i wola Narodu Polskiego.', likes:'3,2k', date:'2 dni temu' },
{ name:'Przemysław Czarnek',handle:'@CzarnekP', platform:'X/Twitter', url:'https://x.com/CzarnekP', avatar:'img/czarnek.jpg', photo:'img/czarnek.jpg', caption:'Bronimy polskich rodzin, polskich dzieci i polskiej tradycji przed lewacką indoktrynacją.', likes:'4,7k', date:'2 dni temu' },
];
// Profil polityków — karty z linkami do X/Twitter
const TWITTER_EMBEDS = [
{ name:'Karol Nawrocki', handle:'KarolNawrocki_', img:'nawrocki.jpg', desc:'Kandydat na Prezydenta RP. Dyrektor IPN. Niezależny kandydat popierany przez PiS.' },
{ name:'Przemysław Czarnek',handle:'CzarnekP', img:'czarnek.jpg', desc:'Poseł PiS, b. Minister Edukacji i Nauki. Działacz na rzecz polskiej tożsamości narodowej.' },
{ name:'Mariusz Błaszczak', handle:'mblaszczak', img:'blaszczak.jpg', desc:'Poseł PiS, b. Minister Obrony Narodowej. Wiceprzewodniczący PiS.' },
{ name:'Zbigniew Ziobro', handle:'ZbigniewZiobro', img:'ziobro.jpg', desc:'B. Minister Sprawiedliwości, lider Solidarnej Polski. Europoseł.' },
{ name:'Jarosław Kaczyński',handle:'pisorgpl', img:'kaczynski.jpg', desc:'Prezes Prawa i Sprawiedliwości. Twórca nowoczesnej polskiej prawicy.' },
];
// ══════════════════════════════════════════════
// DRZEWA PARTYJNE
// ══════════════════════════════════════════════
// ── KONFEDERACJA KORONY POLSKIEJ (KKP) — deficyty intelektualne ──
const KKP_TREE = {
name:'Grzegorz Braun', role:'Lider KKP · Poseł na Sejm RP X kadencji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/34/photo',
married:true, children:5, religious:true,
fail:'Doktor filozofii, który publicznie kwestionuje fakty naukowe i historyczne. Zasłynął ugaszeniem gaśnicą proszkową chanukowej menory w Sejmie (grudzień 2023) — czyn potępiony przez wszystkie kluby poselskie i Prezydium Sejmu. Regularnie głosi teorie spiskowe o "wielkim resecie", odmawiał uznania, że Niemcy wywołały II Wojnę Światową, negował skuteczność szczepień w trakcie pandemii. Wielokrotnie ukarany przez Marszałka Sejmu. Prawnik i reżyser z dyplomem, który skutecznie demonstruje, że papier akademicki nie gwarantuje zdolności logicznego myślenia.',
sections:[
{ label:'⚡ Posłowie Konfederacji Korony Polskiej', members:[
{ name:'Roman Fritz', role:'Poseł KKP X kadencji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/81/photo',
married:true, children:1, religious:true,
fail:'Działacz związany ze środowiskami nacjonalistycznymi. W Sejmie głównie nieobecny w debacie merytorycznej — najczęściej sławą zawdzięcza byciu fotografowanym obok Brauna podczas happeningów. Brak widocznego dorobku legislacyjnego.' },
{ name:'Włodzimierz Skalik', role:'Poseł KKP X kadencji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/340/photo',
married:true, children:2, religious:true,
fail:'Polityk o mało wyrazistym profilu, znany przede wszystkim ze współpracy z Braunem. Jego aktywność sejmowa ogranicza się głównie do głosowań partyjnych — brak własnych inicjatyw ustawodawczych i rozpoznawalnych wystąpień.' },
{ name:'Sławomir Zawiślak', role:'Poseł KKP X kadencji · Były poseł PiS',
img:'https://api.sejm.gov.pl/sejm/term10/MP/446/photo',
married:true, children:3, religious:true,
fail:'Polityczny wędrowiec — były poseł PiS, który przeszedł do KKP. Słynie z gwałtownych zwrotów ideologicznych. Trudno wskazać spójny dorobek legislacyjny łączący jego kolejne wcielenia partyjne. Przykład kariery zbudowanej na pływaniu między frakcjami, nie na merytorycznej pracy.' },
]},
{ label:'🔎 Kontrowersyjne dokonania lidera (wybór)', members:[
{ name:'Gaśnica na menorę', role:'Sejm RP, grudzień 2023', img:null, initials:'🧯', bg:'#7c0000',
married:false, children:0, religious:false,
fail:'Podczas uroczystości chanukowych w Sejmie Braun ugasił zapalony świecznik gaśnicą proszkową. Czyn potępiony przez Marszałka, wszystkie kluby i ambasadę USA. Braun stracił diety i wynagrodzenie na 3 miesiące. Uznał to za… atak na niego.' },
{ name:'"Niemcy nie wywołały II WŚ"', role:'Wywiad telewizyjny, 2022', img:null, initials:'📺', bg:'#7c0000',
married:false, children:0, religious:false,
fail:'W nagraniu z 2022 r. Braun zakwestionował powszechnie uznany fakt historyczny o odpowiedzialności Niemiec za wybuch II Wojny Światowej. Historycy, IPN i organizacje kombatanckie wyrazili zdecydowany sprzeciw.' },
{ name:'Teorie spiskowe o szczepionkach', role:'Kampania "antycovidowa", 20202023', img:null, initials:'💉', bg:'#7c0000',
married:false, children:0, religious:false,
fail:'Aktywnie propagował dezinformację medyczną — twierdzenia o mikroczipach w szczepionkach, "eksperymencie genetycznym" i planowanym ludobójstwie. Treści te zostały zdementowane przez WHO, EMA i polskie instytucje medyczne.' },
]},
],
};
// ── KONFEDERACJA WOLNOŚĆ I NIEPODLEGŁOŚĆ — osiągnięcia i kwalifikacje ──
const KONFEDERACJA_TREE = {
name:'Sławomir Mentzen', role:'Prezes KORWiN · Lider Konfederacji WiN',
img:'https://api.sejm.gov.pl/sejm/term10/MP/241/photo',
married:true, children:3, religious:false,
merit:'Doktor nauk ekonomicznych (UMK Toruń, rozprawa obroniona z wyróżnieniem). Licencjonowany doradca podatkowy i makler papierów wartościowych. Właściciel kancelarii doradztwa podatkowego. Zna 5 języków obcych. Autor bestsellerowej książki "Tak źle, jak myślisz, nie jest". Prezes KORWiN, lider Konfederacji w wyborach 2023 — partia zdobyła 7,2% głosów i 18 mandatów.',
sections:[
{ label:'🏛 Kierownictwo Konfederacji', members:[
{ name:'Krzysztof Bosak', role:'Wicemarszałek Sejmu RP · Ruch Narodowy',
img:'https://api.sejm.gov.pl/sejm/term10/MP/33/photo',
married:true, children:4, religious:true,
merit:'Wicemarszałek Sejmu X kadencji. Absolwent SGH (ekonomia). Działacz narodowy od lat szkolnych, poseł od 2005 r. (z przerwami). Kandydat na Prezydenta RP w 2020 r. — 6,78% w I turze. Konsekwentny obrońca suwerenności i tradycyjnych wartości. Uznawany za jednego z najlepiej przygotowanych merytorycznie parlamentarzystów opozycji.' },
{ name:'Konrad Berkowicz', role:'Poseł KORWiN · Wiceprzewodniczący Konfederacji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/16/photo',
married:true, children:2, religious:false,
merit:'Prawnik (Uniwersytet Śląski). Prowadzi własną kancelarię prawną. Aktywny obrońca wolności słowa i praw przedsiębiorców. Jeden z twarzy Konfederacji w mediach — merytorycznie przygotowany, spokojny w debacie. Wieloletni działacz ruchu wolnościowego w Polsce.' },
{ name:'Stanisław Tyszka', role:'Poseł · Wiceprzewodniczący Konfederacji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/401/photo',
married:true, children:3, religious:true,
merit:'Absolwent Wydziału Prawa UW. Poseł od VI kadencji (2007). Były Wicemarszałek Sejmu VIII kadencji (jako lider Kukiz\'15). Doświadczony parlamentarzysta — ponad 15 lat w Sejmie. Konsekwentny obrońca polskiej suwerenności i decentralizacji władzy.' },
{ name:'Przemysław Wipler', role:'Poseł KORWiN · Sekretarz Konfederacji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/424/photo',
married:true, children:1, religious:false,
merit:'Absolwent Szkoły Głównej Handlowej (finanse). Przez wiele lat pracował w sektorze prywatnym (consulting, doradztwo finansowe). Ceniony jako ekspert ds. podatkowych i ekonomicznych w pracach sejmowych komisji finansów.' },
]},
{ label:'📋 Posłowie Konfederacji WiN', members:[
{ name:'Karina Bosak', role:'Posłanka Ruchu Narodowego',
img:'https://api.sejm.gov.pl/sejm/term10/MP/32/photo',
married:true, children:4, religious:true,
merit:'Prawniczka i działaczka społeczna. Prowadzi sprawy z zakresu prawa rodzinnego. Aktywna publicystka — autorka licznych artykułów o wychowaniu, rodzinie i konserwatywnej wizji społeczeństwa. Żona Krzysztofa Bosaka.' },
{ name:'Bartłomiej Pejo', role:'Poseł KORWiN',
img:'https://api.sejm.gov.pl/sejm/term10/MP/285/photo',
married:true, children:2, religious:false,
merit:'Przedsiębiorca z wieloletnim doświadczeniem biznesowym. Zwolennik radykalnego obniżenia podatków i deregulacji. Wnosi do Sejmu perspektywę prywatnego sektora — rzetelnie demaskuje absurdy biurokratyczne podczas posiedzeń komisji sejmowych.' },
{ name:'Michał Wawer', role:'Poseł KORWiN · Rzecznik Prasowy',
img:'https://api.sejm.gov.pl/sejm/term10/MP/412/photo',
married:true, children:2, religious:false,
merit:'Prawnik, publicysta i bloger. Absolwent prawa na Uniwersytecie Warszawskim. Twarz Konfederacji w mediach — doskonale przygotowany merytorycznie, sprawny polemista. Autor popularnych tekstów o wolności, prawie i ekonomii.' },
{ name:'Bronisław Foltyn', role:'Poseł Konfederacji',
img:'https://api.sejm.gov.pl/sejm/term10/MP/80/photo',
married:true, children:3, religious:true,
merit:'Działacz regionalny z Podhala, znany obrońca interesów górali i Małopolski. Przedsiębiorca z branży turystycznej. Reprezentuje głos "zwykłych Polaków" — przedsiębiorców, rolników i rzemieślników zmęczonych przeregulowanym państwem.' },
{ name:'Andrzej Zapałowski', role:'Poseł · Ekspert ds. Bezpieczeństwa',
img:'https://api.sejm.gov.pl/sejm/term10/MP/443/photo',
married:true, children:2, religious:true,
merit:'Pułkownik rezerwy, doktor nauk politycznych. Wieloletni wykładowca akademicki w zakresie bezpieczeństwa narodowego i geopolityki. Autor kilku książek o bezpieczeństwie wschodniej flanki NATO. Jeden z najbardziej merytorycznie przygotowanych posłów w dziedzinie obronności.' },
{ name:'Witold Tumanowicz', role:'Poseł Ruchu Narodowego',
img:'https://api.sejm.gov.pl/sejm/term10/MP/399/photo',
married:true, children:2, religious:true,
merit:'Działacz narodowy i społeczny z Łodzi. Znany z pracy na rzecz lokalnych wspólnot i obrony polskiej tożsamości kulturowej. Aktywny uczestnik prac sejmowych komisji ds. samorządu i polityki regionalnej.' },
]},
],
};
const PIS_TREE = {
name:'Jarosław Kaczyński', role:'Prezes Prawa i Sprawiedliwości', img:'img/kaczynski.jpg',
married:false, children:0, religious:true,
merit:'Założyciel PiS i architekt największych reform społecznych III RP: 500+, 13. i 14. emerytura, bezpłatne leki dla seniorów, obniżenie wieku emerytalnego, Polska Strefa Inwestycji. Całe życie poświęcił Polsce — nigdy nieżonaty, bez majątku, bez zagranicznych interesów. Niezłomny obrońca suwerenności i wartości chrześcijańskich.',
sections: [
{ label:'🏛 Kierownictwo PiS', members:[
{ name:'Mariusz Błaszczak', role:'Wiceprezes PiS · Szef Klubu PiS', img:'img/blaszczak.jpg',
married:true, children:2, religious:true,
merit:'Zbudował najsilniejszą armię lądową w UE — 300 tys. żołnierzy, F-35, czołgi Abrams i K2, Patriot, Himars. Każdego dnia w Sejmie demaskuje kłamstwa rządu Tuska i broni polskiej racji stanu.' },
{ name:'Ryszard Terlecki', role:'Poseł PiS · b. Wicemarszałek Sejmu', img:'img/terlecki.jpg',
married:true, children:2, religious:true,
merit:'Historyk i działacz antykomunistycznej opozycji, internowany w stanie wojennym. Przez dekady stoi na straży wartości konserwatywnych w polskim parlamencie.' },
{ name:'Krzysztof Sobolewski', role:'Sekretarz Generalny PiS', img:null, initials:'KS', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Sprawna koordynacja struktury partyjnej PiS w całej Polsce. Kluczowy organizator kampanii wyborczych 2015, 2019 i 2023.' },
{ name:'Adam Lipiński', role:'Wiceprezes PiS', img:null, initials:'AL', bg:'#1e3a8a',
married:true, children:3, religious:true,
merit:'Wieloletni działacz partyjny, poseł wielu kadencji. Odpowiedzialny za relacje z regionalnymi strukturami PiS i wzmacnianie bazy partyjnej.' },
{ name:'Radosław Fogiel', role:'Poseł PiS · Rzecznik Prasowy', img:null, initials:'RF', bg:'#1e3a8a',
married:true, children:1, religious:true,
merit:'Twarz PiS w mediach — merytorycznie i skutecznie odpiera ataki mediów głównego nurtu. Młody, energiczny obrońca programu PiS na każdym forum.' },
{ name:'Piotr Müller', role:'Poseł PiS · b. Rzecznik Rządu', img:null, initials:'PM', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Twarz rządu Morawieckiego w mediach — rzetelnie komunikował osiągnięcia PiS. Dziś jako poseł skutecznie rozlicza rząd Tuska z obietnic wyborczych.' },
{ name:'Marek Suski', role:'Poseł PiS · b. Szef Kancelarii Premiera', img:'img/suski.jpg',
married:true, children:2, religious:true,
merit:'Bliski współpracownik Kaczyńskiego i Morawieckiego. Koordynował wielki projekt CPK i Program Budowy Dróg Krajowych.' },
]},
{ label:'🏆 Byli Premierzy', members:[
{ name:'Beata Szydło', role:'Europoseł · b. Premier RP (20152017)', img:'img/szydlo.jpg',
married:true, children:1, religious:true,
merit:'Pierwsza kobieta-premier z PiS. Wdrożyła flagowy program 500+, zlikwidowała szkodliwe gimnazja, prowadziła prorodzinną politykę społeczną. Dziś Wiceprzewodnicząca Parlamentu Europejskiego — broni polskiego interesu.' },
{ name:'Mateusz Morawiecki', role:'Poseł PiS · b. Premier RP (20172023)', img:'img/morawiecki.jpg',
married:true, children:3, religious:true,
merit:'Strategia na rzecz Odpowiedzialnego Rozwoju, CPK, przekop Mierzei Wiślanej, rekordowe PKB. Kierował Polską przez pandemię i wojnę w Ukrainie. Zbudował silniejszą i bogatszą Polskę niż kiedykolwiek w historii.' },
]},
{ label:'⚖️ Ministrowie i wiceministrowie', members:[
{ name:'Zbigniew Ziobro', role:'Europoseł · b. Min. Sprawiedliwości', img:'img/ziobro.jpg',
married:true, children:2, religious:true,
merit:'Reforma sądownictwa, walka z korupcją i przestępczością zorganizowaną. Europoseł demaskujący nadużycia UE. Prześladowany przez aparat Tuska — ofiara politycznych represji.' },
{ name:'Antoni Macierewicz', role:'Poseł PiS · b. Minister Obrony Narodowej', img:'img/macierewicz.jpg',
married:true, children:2, religious:true,
merit:'Odbudowa prestiżu WP, likwidacja WSI. Przewodniczący parlamentarnej komisji smoleńskiej — niezłomny obrońca prawdy o tragedii 10 kwietnia 2010 r.' },
{ name:'Przemysław Czarnek', role:'Poseł PiS · b. Minister Edukacji', img:'img/czarnek.jpg',
married:true, children:5, religious:true,
merit:'Obrona polskiej szkoły przed ideologizacją. Lex Czarnek — wzmocnienie nadzoru kuratorów. Ojciec pięciorga dzieci — żywy przykład wartości, które głosi.' },
{ name:'Jacek Sasin', role:'Poseł PiS · b. Min. Aktywów Państwowych', img:'img/sasin.jpg',
married:true, children:2, religious:true,
merit:'Ochrona strategicznych spółek SP przed wrogimi przejęciami. Nadzór nad PKN Orlen, KGHM, PGE. Bezpieczeństwo energetyczne Polski w czasie kryzysu.' },
{ name:'Piotr Gliński', role:'Poseł PiS · b. Minister Kultury', img:'img/glinski.jpg',
married:true, children:2, religious:true,
merit:'Rozbudowa sieci instytucji kultury, wsparcie polskich twórców. Budowa Muzeum Historii Polski, polityka historyczna podnosząca prestiż Polski na świecie.' },
{ name:'Mariusz Kamiński', role:'Europoseł PiS · b. Min. Spraw Wewnętrznych', img:'img/kaminski.jpg',
married:true, children:2, religious:true,
merit:'Ochrona granicy polsko-białoruskiej, budowa zapory. Szef ABW, walka z przestępczością zorganizowaną. Bezprawnie uwięziony przez rząd Tuska — ofiara politycznych represji.' },
{ name:'Maciej Wąsik', role:'Poseł PiS · b. wiceminister MSWiA', img:'img/wasik.jpg',
married:true, children:2, religious:true,
merit:'Koordynacja służb granicznych i ochrony wschodniej granicy RP. Bezprawnie pozbawiony mandatu poselskiego przez antydemokratyczny rząd Tuska.' },
{ name:'Elżbieta Witek', role:'Poseł PiS · b. Marszałek Sejmu', img:'img/witek.jpg',
married:true, children:2, religious:true,
merit:'Pierwsza kobieta-Marszałek Sejmu z ramienia PiS. Minister Spraw Wewnętrznych, szefowa KPRM — zawsze na posterunku służby dla Polski.' },
{ name:'Łukasz Schreiber', role:'Poseł PiS · b. Szef KPRM', img:'img/schreiber.jpg',
married:true, children:3, religious:true,
merit:'Koordynacja prac rządu Morawieckiego. Sprawny nadzór nad programami społecznymi i funduszami europejskimi, dbając o terminową realizację obietnic.' },
{ name:'Henryk Kowalczyk', role:'Poseł PiS · b. Minister Rolnictwa', img:'img/kowalczyk_h.jpg',
married:true, children:3, religious:true,
merit:'Polityka rolna chroniąca polskich rolników. Rekordowe dopłaty bezpośrednie, modernizacja polskiej wsi. Ochrona przed zalewem taniego ukraińskiego zboża.' },
{ name:'Waldemar Buda', role:'Poseł PiS · b. Minister Rozwoju', img:'img/buda.jpg',
married:true, children:2, religious:true,
merit:'Rekordowa absorpcja funduszy UE, wsparcie MŚP, program Polska Wschodnia. Przyciąganie zagranicznych inwestycji i budowa polskiej innowacyjności.' },
{ name:'Stanisław Karczewski', role:'Senator PiS · b. Marszałek Senatu', img:'img/karczewski.jpg',
married:true, children:3, religious:true,
merit:'Wieloletni Marszałek Senatu, chirurg z powołania. Bezpłatne leki dla seniorów 75+ — jego inicjatywa uratowała setki tysięcy emerytów.' },
{ name:'Jarosław Zieliński', role:'Poseł PiS · b. wiceminister MSWiA', img:null, initials:'JZ', bg:'#1e3a8a',
married:true, children:3, religious:true,
merit:'Kluczowy architekt reformy policji i straży granicznej. Nadzorował budowę zapory na granicy z Białorusią — zaporę, którą Tusk próbuje teraz demontować.' },
{ name:'Marcin Horała', role:'Poseł PiS · b. pełnomocnik ds. CPK', img:null, initials:'MH', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Główny architekt i obrońca Centralnego Portu Komunikacyjnego — inwestycji stulecia. Walczy z bezprawnym sabotażem CPK przez rząd Tuska.' },
{ name:'Marcin Romanowski', role:'Poseł PiS · b. wiceminister MS', img:null, initials:'MR', bg:'#1e3a8a',
married:true, children:3, religious:true,
merit:'Obrońca Funduszu Sprawiedliwości wspierającego ofiary przestępstw. Prześladowany przez aparat Tuska, szukał azylu politycznego na Węgrzech.' },
]},
{ label:'🇪🇺 Europosłowie PiS / ZP', members:[
{ name:'Anna Fotyga', role:'Europoseł PiS · b. Minister Spraw Zagranicznych', img:'img/fotyga.jpg',
married:false, children:0, religious:true,
merit:'Obrona polskiego interesu w PE, sprawozdawca ds. obrony i bezpieczeństwa. Walczy z Nord Stream i uzależnieniem Europy od Rosji. Jeden z najbardziej szanowanych polskich europosłów.' },
{ name:'Joachim Brudziński', role:'Europoseł PiS · b. Min. Spraw Wewnętrznych', img:'img/brudzinski.jpg',
married:true, children:2, religious:true,
merit:'Budowa zapory na granicy z Białorusią, ochrona polskich granic. Dziś w PE walczy o bezpieczeństwo zewnętrzne i wewnętrzne całej Europy.' },
{ name:'Patryk Jaki', role:'Europoseł PiS · b. wiceminister MS', img:'img/jaki.jpg',
married:true, children:2, religious:true,
merit:'Ujawnił aferę reprywatyzacyjną Warszawy, ratując majątek polskich rodzin. W PE demaskuje korupcję i broni polskiej suwerenności w komisji LIBE.' },
{ name:'Beata Kempa', role:'Europoseł PiS · b. szefowa KPRM', img:'img/kempa.jpg',
married:true, children:3, religious:true,
merit:'Koordynowała pomoc humanitarną dla uchodźców z Ukrainy. W PE obrończyni polskiej rodziny i wartości chrześcijańskich, walczy z ideologią gender narzucaną przez Brukselę.' },
{ name:'Ryszard Czarnecki', role:'b. Europoseł PiS · Wiceprzewodniczący PE', img:'img/czarnecki.jpg',
married:true, children:2, religious:true,
merit:'Wieloletni wiceprzewodniczący Parlamentu Europejskiego. Jeden z najdłużej zasiadających i najaktywniejszych polskich europosłów, obrońca suwerenności państw narodowych.' },
]},
{ label:'📋 Aktywni posłowie PiS', members:[
{ name:'Sebastian Kaleta', role:'Poseł PiS · b. wiceminister MS', img:'img/kaleta.jpg',
married:true, children:2, religious:true,
merit:'Ekspert prawny PiS — codziennie demaskuje bezprawne działania rządu Tuska. Jeden z najostrzejszych krytyków łamania Konstytucji przez ministra Bodnara.' },
{ name:'Michał Wójcik', role:'Poseł PiS · b. wiceminister MS', img:'img/wojcik.jpg',
married:true, children:2, religious:true,
merit:'Reforma prawa karnego zaostrzająca kary za pedofilię i przemoc wobec dzieci. Aktywna praca legislacyjna w zakresie ochrony najsłabszych obywateli.' },
{ name:'Dariusz Matecki', role:'Poseł PiS · lider online', img:'img/matecki.jpg',
married:true, children:2, religious:true,
merit:'Najskuteczniejszy poseł PiS w mediach społecznościowych — miliony wyświetleń filmów dokumentujących wpadki koalicji rządowej. Nieustępliwy obrońca wartości chrześcijańskich.' },
{ name:'Janusz Kowalski', role:'Poseł PiS · b. wiceminister aktywów', img:null, initials:'JK', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Nieugięty obrońca polskich spółek energetycznych i suwerenności energetycznej. Głośno sprzeciwia się wyprzedaży polskiego majątku przez KO.' },
{ name:'Rafał Bochenek', role:'Poseł PiS · Rzecznik Prasowy PiS', img:null, initials:'RB', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Skuteczny rzecznik PiS — każdego dnia w mediach obnażający kłamstwa i hipokryzję rządu Tuska. Przejrzysty i merytoryczny komunikator prawicowych wartości.' },
{ name:'Artur Soboń', role:'Poseł PiS · b. wiceminister finansów', img:null, initials:'AS', bg:'#1e3a8a',
married:true, children:3, religious:true,
merit:'Architekt polityki mieszkaniowej PiS. Jako wiceminister finansów dbał o zrównoważony budżet przy jednoczesnym finansowaniu rekordowych programów socjalnych.' },
{ name:'Barbara Bartuś', role:'Poseł PiS · Wicemarszałek Sejmu', img:null, initials:'BB', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Sprawna parlamentarzystka z wieloletnim doświadczeniem. Broni praw obywateli, kontroluje rząd Tuska i stoi na straży regulaminowych zasad w Sejmie.' },
{ name:'Dariusz Piontkowski', role:'Poseł PiS · b. wiceminister edukacji', img:null, initials:'DP', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Obrona polskiej oświaty przed chaosem reformy Nowackiej. Ekspert edukacyjny walczący o prawa rodziców do wychowania dzieci zgodnie z własnymi wartościami.' },
{ name:'Marek Ast', role:'Poseł PiS · b. szef komisji sprawiedliwości', img:null, initials:'MA', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Jeden z czołowych prawników PiS, ekspert ds. wymiaru sprawiedliwości. Broni niezależności sądownictwa przed bezprawną ingerencją ministra Bodnara.' },
{ name:'Anna Siarkowska', role:'Poseł PiS · aktywistka pro-life', img:null, initials:'AS', bg:'#1e3a8a',
married:true, children:3, religious:true,
merit:'Niezłomna obrończyni życia nienarodzonych i tradycyjnej rodziny polskiej. Aktywistka pro-life, głos sumienia w polskim Sejmie, broniąca wartości chrześcijańskich.' },
{ name:'Tomasz Rzymkowski', role:'Poseł PiS · b. wiceminister edukacji', img:null, initials:'TR', bg:'#1e3a8a',
married:true, children:2, religious:true,
merit:'Walka o jakość polskiej edukacji i prawa uczniów. Sprzeciw wobec ideologizacji podręczników szkolnych przez lewicowy rząd Tuska.' },
]},
]
};
const KOALICJA_TREE = {
name:'Donald Tusk', role:'Przewodniczący KO · Premier RP', img:'img/tusk.jpg',
married:true, children:2, religious:false,
fail:'Powrót z Brukseli by obalić demokratycznie wybrany rząd. Premier 20072014: katastrofa smoleńska bez wyjaśnienia, nacjonalizacja OFE (140 mld zł), podwyżka VAT, era umów śmieciowych. Rząd Tuska łamie Konstytucję — bezprawna likwidacja TVP, polityczne więzienia, ignorowanie wyroków TK.',
sections: [
{ label:'🏛 Rząd Tuska 2023', members:[
{ name:'Radosław Sikorski', role:'Minister Spraw Zagranicznych', img:'img/sikorski.jpg',
married:true, children:2, religious:false,
fail:'Słynne nagranie "mamy do zrobienia" z restauracji z Rostowskim. Sprzedaż polskiego interesu za zachodnią karierę. Mąż Anne Applebaum — dziennikarki atakującej Polskę w mediach zagranicznych.' },
{ name:'Adam Bodnar', role:'Minister Sprawiedliwości', img:'img/bodnar.jpg',
married:true, children:2, religious:false,
fail:'Bezprawne przejęcie mediów publicznych bez podstawy prawnej. Polityczne odwołania prokuratorów. Ignorowanie wyroków TK i SN. Uwięzienie posłów PiS. Systematyczne łamanie Konstytucji RP.' },
{ name:'Tomasz Siemoniak', role:'Minister Spraw Wewnętrznych', img:'img/siemoniak.jpg',
married:true, children:2, religious:false,
fail:'Faktyczne otwarcie granicy na nielegalną migrację. Próby demontażu zapory na granicy z Białorusią. Brak reakcji na rosnącą przestępczość z udziałem cudzoziemców.' },
{ name:'Bartłomiej Sienkiewicz', role:'b. Minister Kultury', img:'img/sienkiewicz_b.jpg',
married:true, children:3, religious:false,
fail:'Nocny zamach na media publiczne 20 XII 2023 — bezprawna likwidacja TVP Info, TVP Historia, Polskiego Radia. Sąd uznał jego działania za bezprawne, lecz skutki trwają do dziś.' },
{ name:'Barbara Nowacka', role:'Minister Edukacji Narodowej', img:'img/nowacka.jpg',
married:false, children:0, religious:false,
fail:'Ideologizacja szkół, faktyczne usunięcie religii z siatki godzin, chaos reformy. Niszczenie polskiej szkoły opartej na wartościach i woli rodziców. Promowanie treści sprzecznych z oczekiwaniami większości rodzin.' },
{ name:'Borys Budka', role:'Minister Aktywów Państwowych', img:'img/budka.jpg',
married:true, children:1, religious:false,
fail:'Polityczne czystki w zarządach spółek Skarbu Państwa. Brak strategii dla polskiej energetyki, wyprzedaż majątku narodowego. Chaos w polityce paliwowej i energetycznej.' },
{ name:'Andrzej Domański', role:'Minister Finansów', img:null, initials:'AD', bg:'#b45309',
married:true, children:2, religious:false,
fail:'Rekordowy deficyt budżetowy, dług publiczny przekraczający próg ostrożnościowy UE. Obiecywał tani kredyt 0% — nie dotrzymał. Gospodarka zwalnia, a wydatki budżetowe wymykają się spod kontroli.' },
{ name:'Marcin Kierwiński', role:'b. Minister ds. Powodzi', img:'img/kierwinski.jpg',
married:true, children:2, religious:false,
fail:'Katastrofalne zarządzanie powodzią 2024 — spóźniona reakcja, brak koordynacji. Tysiące poszkodowanych czekało tygodniami na pomoc państwa. Symbol niekompetencji koalicji.' },
{ name:'Dariusz Klimczak', role:'Minister Infrastruktury · PSL', img:null, initials:'DK', bg:'#92400e',
married:true, children:2, religious:true,
fail:'Zamrożenie kluczowych inwestycji — sabotaż CPK i Via Carpatia. Opóźnienia modernizacji kolei, chaos w programach drogowych. Bezczynność kosztuje Polskę miliardy.' },
{ name:'Cezary Tomczyk', role:'Wiceminister Obrony Narodowej', img:null, initials:'CT', bg:'#b45309',
married:true, children:1, religious:false,
fail:'Faktyczne osłabienie zdolności obronnych Polski. Opóźnienia zakupów sprzętu wojskowego. Upolitycznienie MON kosztem gotowości bojowej — niszczenie dorobku militarnego rządów PiS.' },
{ name:'Krzysztof Gawkowski', role:'Wicepremier · Min. Cyfryzacji · Lewica', img:'img/gawkowski.jpg',
married:true, children:0, religious:false,
fail:'Ideologizacja polityki cyfrowej, lewackie priorytety zamiast realnych inwestycji w bezpieczeństwo cybernetyczne. Brak postępów w cyfryzacji usług publicznych mimo miliardów z KPO.' },
{ name:'Agnieszka Dziemianowicz-Bąk', role:'Min. Rodziny i Pracy · Lewica', img:'img/dziemianowicz.jpg',
married:true, children:0, religious:false,
fail:'Brak realnych podwyżek dla pracowników sfery budżetowej. Ideologiczne priorytety zamiast wsparcia rodzin z dziećmi. Blokowanie rozszerzenia programów pro-rodzinnych zaprowadzonych przez PiS.' },
{ name:'Katarzyna Kotula', role:'Min. ds. Równości · Lewica', img:'img/kotula.jpg',
married:false, children:0, religious:false,
fail:'Marnotrawi pieniądze podatników na finansowanie organizacji promujących ideologię gender w szkołach i urzędach. Atakuje tradycyjną rodzinę polską i finansuje działalność antyrodzinnych aktywistów.' },
]},
{ label:'🔵 KO — Platforma Obywatelska', members:[
{ name:'Rafał Trzaskowski', role:'Prezydent Warszawy · Kandydat KO na Prezydenta', img:null, initials:'RT', bg:'#b45309',
married:true, children:2, religious:false,
fail:'Warszawa pod jego rządami: najwyższe w Polsce podatki lokalne i czynsze. Podpisał deklarację LGBT+ finansowaną ze środków miejskich. Afera reprywatyzacyjna trwa — kamienice wracają do rąk prywatnych kosztem lokatorów.' },
{ name:'Grzegorz Schetyna', role:'Poseł KO · b. Przewodniczący PO · b. Min. SW', img:'img/schetyna.jpg',
married:true, children:2, religious:false,
fail:'Wieloletni lider PO wciągający partię w kolejne skandale i układy. Polityczna zemsta, frakcyjność, intrygi. Doprowadził PO do druzgocącej porażki w 2015 r.' },
{ name:'Sławomir Nitras', role:'Poseł KO · b. Minister Sportu', img:'img/nitras.jpg',
married:true, children:2, religious:false,
fail:'Polityczne czystki w związkach sportowych, arogancja wobec środowisk. Skandaliczne wypowiedzi obrażające Polaków pracujących za granicą. Jeden z najbardziej kontrowersyjnych polityków KO.' },
{ name:'Arkadiusz Myrcha', role:'Poseł KO · wiceminister MS', img:'img/myrcha.jpg',
married:true, children:2, religious:false,
fail:'Współodpowiedzialny za bezprawne działania resortu Bodnara łamiące Konstytucję. Polityczny wykonawca niszczenia niezależności sądownictwa i mediów publicznych.' },
{ name:'Bartosz Arłukowicz', role:'Europoseł KO · b. Minister Zdrowia', img:'img/arlukowicz.jpg',
married:true, children:2, religious:false,
fail:'Minister Zdrowia 20122015 — kryzys SOR-ów, gigantyczne kolejki do lekarzy, braki leków. Polacy wyjeżdżali za granicę po leczenie. Zostawił zdewastowany system ochrony zdrowia.' },
{ name:'Dariusz Joński', role:'Poseł KO · kontroler rządu PiS', img:null, initials:'DJ', bg:'#b45309',
married:true, children:2, religious:false,
fail:'Przez lata straszył "kontrolami" wyłącznie dla celów politycznych. Setki zapowiadanych afer okazały się mydlaną bańką. Żadna jego "komisja" nie doprowadziła do udowodnienia zarzutów.' },
{ name:'Michał Szczerba', role:'Poseł KO · aktywista partyjny', img:null, initials:'MS', bg:'#b45309',
married:true, children:1, religious:false,
fail:'Specjalista od sztucznych skandali i manipulacji wymierzonych w PiS. Jego "afery" regularnie okazują się dezinformacją. Polityka oparta na nagłówkach, a nie faktach.' },
{ name:'Krzysztof Brejza', role:'Europoseł KO · b. szef kampanii KO', img:null, initials:'KB', bg:'#b45309',
married:true, children:3, religious:false,
fail:'Jako szef kampanii KO koordynował dezinformację wyborczą. Kompromitujące SMSy ujawniły kulisy brudnej kampanii wyborczej Platformy Obywatelskiej.' },
{ name:'Marek Belka', role:'Europoseł KO · b. Premier · b. Prezes NBP', img:null, initials:'MB', bg:'#78350f',
married:true, children:2, religious:false,
fail:'Jako Prezes NBP — nagranie z 2014 r. ujawniło polityczną koordynację NBP z rządem Tuska. Jako Premier (20042005): rząd bez mandatu społecznego, jeden z najsłabszych w historii III RP.' },
]},
{ label:'🌾 PSL — Polskie Stronnictwo Ludowe', members:[
{ name:'Władysław Kosiniak-Kamysz', role:'Wicepremier · Minister Obrony Narodowej · Prezes PSL', img:'img/kosiniakkamysz.jpg',
married:true, children:2, religious:true,
fail:'Sprzeczne decyzje w MON, opóźnienia zakupów uzbrojenia. Poddał PSL pod dyktaturę Tuska, zdradzając wyborców wsi i rolników. Popierał politykę migracyjną KO wbrew tradycyjnym wartościom PSL.' },
{ name:'Piotr Zgorzelski', role:'Poseł PSL · Wicemarszałek Sejmu', img:null, initials:'PZ', bg:'#166534',
married:true, children:2, religious:true,
fail:'Wicemarszałek Sejmu prowadzący obrady stronniczo — na niekorzyść opozycji. Wspiera politykę Tuska kosztem tradycyjnych wartości PSL i interesów polskiej wsi.' },
{ name:'Marek Sawicki', role:'Poseł PSL · wieloletni parlamentarzysta', img:null, initials:'MS', bg:'#166534',
married:true, children:4, religious:true,
fail:'Wieloletni minister rolnictwa, który nie potrafił obronić polskich rolników przed zalewem ukraińskiego zboża. Błędy koalicji rządzącej, której jest częścią, biją bezpośrednio w polską wieś.' },
{ name:'Urszula Pasławska', role:'Poseł PSL · wiceprzewodnicząca', img:null, initials:'UP', bg:'#166534',
married:true, children:2, religious:true,
fail:'Aktywna w mediach, ale bez realnych osiągnięć dla polskich rolników. PSL stał się pod jej współprzywództwem całkowicie zależny od Tuska, porzucając tradycyjny elektorat wiejski.' },
]},
{ label:'🟡 Polska 2050 — Szymon Hołownia', members:[
{ name:'Szymon Hołownia', role:'Marszałek Sejmu · Lider Polska 2050', img:'img/holownia.jpg',
married:true, children:2, religious:true,
fail:'Chaos i brak autorytetu w prowadzeniu obrad Sejmu, liczne wpadki regulaminowe. Porzucił dziennikarstwo i publicystykę katolicką dla władzy. Obiecywał "nową politykę" — dostarczył stare układy z Tuskiem.' },
{ name:'Paulina Hennig-Kloska', role:'Minister Klimatu i Środowiska', img:null, initials:'PH', bg:'#92400e',
married:true, children:2, religious:false,
fail:'900 milionów złotych z systemu kaucyjnego zaginęło za jej nadzoru. Chaotyczna polityka klimatyczna, rosnące rachunki za energię dla Polaków. Brak spójnej strategii dla polskiej energetyki.' },
{ name:'Michał Kobosko', role:'Poseł Polska 2050 · wiceprzewodniczący', img:null, initials:'MK', bg:'#92400e',
married:true, children:2, religious:false,
fail:'Wiceprzewodniczący partii bez realnych osiągnięć legislacyjnych. Polska 2050 stała się bezwolnym przybudówkiem Platformy Obywatelskiej, ignorując własny program wyborczy.' },
]},
{ label:'🔴 Lewica (SLD · Nowa Lewica)', members:[
{ name:'Włodzimierz Czarzasty', role:'Wicemarszałek Sejmu · Lider Lewicy', img:null, initials:'WC', bg:'#991b1b',
married:true, children:2, religious:false,
fail:'Wicemarszałek Sejmu prowadzący obrady stronniczo. Lider partii bez wyraźnego programu, całkowicie podporządkowanej Tuskowi. Lewicowe postulaty giną w cieniu dominującej Platformy.' },
{ name:'Robert Biedroń', role:'Europoseł Lewicy · b. Prezydent Słupska', img:null, initials:'RB', bg:'#991b1b',
married:false, children:0, religious:false,
fail:'Porzucał wyborców w połowie każdej kadencji — z Słupska do Sejmu, z Sejmu do PE. W Europarlamencie walczy o globalną agendę lewicową zamiast o interesy Polski.' },
{ name:'Anna Maria Żukowska', role:'Poseł Lewicy · szefowa klubu', img:null, initials:'AZ', bg:'#991b1b',
married:true, children:1, religious:false,
fail:'Radykalna lewicowa retoryka bez pokrycia w działaniach. Klub Lewicy głosuje zgodnie z dyspozycją Tuska, ignorując własny program wyborczy. Obiecała rewolucję — dostarczyła posłuszeństwo Platformie.' },
{ name:'Joanna Scheuring-Wielgus', role:'Posłanka Lewicy · aktywistka', img:null, initials:'JS', bg:'#991b1b',
married:true, children:2, religious:false,
fail:'Skandaliczne zachowania w przestrzeni publicznej i obiektach sakralnych. Prowokacja zamiast merytorycznej pracy parlamentarnej. Atakuje instytucje religijne i tradycję polską.' },
{ name:'Maciej Konieczny', role:'Poseł Lewicy · Razem', img:null, initials:'MK', bg:'#991b1b',
married:true, children:1, religious:false,
fail:'Reprezentuje radykalny skraj lewicy, postulując nacjonalizację i politykę niszczącą polskie firmy. Jego program cofnąłby polską gospodarkę o dekady.' },
]},
{ label:'📜 Era Tuska I (20072014)', members:[
{ name:'Bronisław Komorowski', role:'b. Prezydent RP (20102015)', img:'img/komorowski.jpg',
married:true, children:5, religious:true,
fail:'Prezydent odpowiedzialny za brak wyjaśnienia katastrofy smoleńskiej. Zawetował zaledwie 1 ustawę przez 5 lat kadencji. W 2015 r. przegrał wybory z Andrzejem Dudą.' },
{ name:'Ewa Kopacz', role:'b. Premier RP (20142015)', img:'img/kopacz.jpg',
married:true, children:1, religious:true,
fail:'Jako Premier: deklaracja przyjęcia uchodźców wbrew woli Polaków. Jako Minister Zdrowia: skandal z zakupem 17 mln dawek szczepionek na "świńską grypę" za 500 mln zł — 15 mln dawek nigdy nie użyto.' },
{ name:'Jan Vincent-Rostowski', role:'b. Minister Finansów (20072013)', img:null, initials:'JR', bg:'#78350f',
married:true, children:2, religious:false,
fail:'Nacjonalizacja OFE — zabrał Polakom 153 mld zł oszczędności emerytalnych. Podwyżka VAT z 22% na 23%. Rekordowe zadłużenie Polski. Architekt finansowego rozboju na polskich emerytach.' },
{ name:'Sławomir Nowak', role:'b. Min. Transportu · skazany za korupcję', img:null, initials:'SN', bg:'#7c2d12',
married:true, children:2, religious:false,
fail:'Skazany prawomocnym wyrokiem na 5,5 roku więzienia za przyjęcie korzyści majątkowych na Ukrainie. Symbol korupcji w Platformie Obywatelskiej — człowiek osobiście rekomendowany przez Tuska.' },
]},
]
};
// ══════════════════════════════════════════════
// STATE
// ══════════════════════════════════════════════
let allArticles = [];
let currentFilter = 'all';
let loadStart = Date.now();
// ══════════════════════════════════════════════
// SMOLEŃSK PAGE
// ══════════════════════════════════════════════
const SMOLENSK_VICTIMS = [
// PREZYDENT RP
{ lp:1, name:'Lech Kaczyński', role:'Prezydent Rzeczypospolitej Polskiej', party:'president', img:'img/kaczynski.jpg',
desc:'Lech Kaczyński (ur. 18 czerwca 1949, zm. 10 kwietnia 2010) — Prezydent RP od 23 XII 2005. Wcześniej Prezydent Warszawy i Minister Sprawiedliwości. Prawnik, dr hab. nauk prawnych, działacz Solidarności. Leciał do Katynia na 70. rocznicę zbrodni katyńskiej. Brat bliźniak Jarosława Kaczyńskiego. Zginął wraz z małżonką i 94 innymi osobami.' },
{ lp:2, name:'Maria Kaczyńska', role:'Małżonka Prezydenta RP, Pierwsza Dama', party:'president', img:null,
desc:'Maria Kaczyńska z d. Mackiewicz (ur. 13 VII 1942, zm. 10 IV 2010) — ekonomistka, dr nauk ekonomicznych. Małżonka Prezydenta Lecha Kaczyńskiego. Aktywnie działała na rzecz rodzin i kultury polskiej. Zginęła razem z mężem lecąc na uroczystości katyńskie.' },
// OSTATNI PREZYDENT NA UCHODŹSTWIE
{ lp:3, name:'Ryszard Kaczorowski', role:'Ostatni Prezydent RP na uchodźstwie', party:'other', img:null,
desc:'Ryszard Kaczorowski (ur. 26 XI 1919, zm. 10 IV 2010) — Prezydent RP na uchodźstwie w latach 19891990, kiedy to oddał insygnia władzy Lechowi Wałęsie po wyborach 1990 r. Harcerz, uczestnik II wojny światowej. Miał 90 lat. Jeden z najstarszych ofiar katastrofy.' },
// POSŁOWIE PiS
{ lp:4, name:'Krzysztof Putra', role:'Wicemarszałek Sejmu RP (PiS)', party:'pis', img:'https://api.sejm.gov.pl/sejm/term6/MP/306/photo',
desc:'Krzysztof Putra (ur. 30 X 1955, zm. 10 IV 2010) — Wicemarszałek Sejmu RP VI kadencji z ramienia PiS. Poseł na Sejm RP wielu kadencji, działacz regionalny Podlasia. Aktywny parlamentarzysta, znany z pracowitości i zaangażowania w sprawy wschodniej Polski.' },
{ lp:5, name:'Przemysław Gosiewski', role:'Wiceprezes PiS, Poseł na Sejm RP', party:'pis', img:'https://api.sejm.gov.pl/sejm/term6/MP/101/photo',
desc:'Przemysław Gosiewski (ur. 10 III 1964, zm. 10 IV 2010) — Wiceprezes Prawa i Sprawiedliwości, jeden z najbliższych współpracowników Jarosława Kaczyńskiego. Poseł wielu kadencji, prawnik. Uważany za jednego z najzdolniejszych polityków PiS. Jego śmierć była ogromną stratą dla partii.' },
{ lp:6, name:'Zbigniew Wassermann', role:'Poseł PiS, szef komisji ds. służb specjalnych', party:'pis', img:'https://api.sejm.gov.pl/sejm/term6/MP/407/photo',
desc:'Zbigniew Wassermann (ur. 2 IX 1956, zm. 10 IV 2010) — Poseł PiS, szef sejmowej komisji ds. służb specjalnych. Prawnik, prokurator. Prowadził głośne dochodzenia w sprawie afer i korupcji. Niezłomny obrońca praworządności.' },
{ lp:7, name:'Aleksandra Natalli-Świat', role:'Poseł PiS, b. wiceminister MSZ', party:'pis', img:'https://api.sejm.gov.pl/sejm/term6/MP/254/photo',
desc:'Aleksandra Natalli-Świat (ur. 24 I 1960, zm. 10 IV 2010) — Poseł PiS, wcześniej Podsekretarz Stanu w Ministerstwie Spraw Zagranicznych. Ekspertka ds. polityki wschodniej i stosunków polsko-rosyjskich. Znawca historii zbrodni katyńskiej.' },
{ lp:8, name:'Grażyna Gęsicka', role:'Poseł PiS, b. Minister Rozwoju Regionalnego', party:'pis', img:'https://api.sejm.gov.pl/sejm/term6/MP/88/photo',
desc:'Grażyna Gęsicka (ur. 25 VI 1951, zm. 10 IV 2010) — Poseł PiS, w rządzie Kazimierza Marcinkiewicza Minister Rozwoju Regionalnego. Ekonomistka, ekspertka ds. funduszy europejskich. Kierowała absorpcją pierwszych miliardów UE dla Polski.' },
// POSŁOWIE INNYCH UGRUPOWAŃ
{ lp:9, name:'Jerzy Szmajdziński', role:'Wicemarszałek Sejmu RP (SLD)', party:'sld', img:'https://api.sejm.gov.pl/sejm/term6/MP/375/photo',
desc:'Jerzy Szmajdziński (ur. 25 X 1952, zm. 10 IV 2010) — Wicemarszałek Sejmu RP z ramienia SLD. Wcześniej Minister Obrony Narodowej. Polityk lewicy, wieloletni parlamentarzysta. Katastrofa dotknęła wszystkich — niezależnie od barw politycznych.' },
{ lp:10, name:'Izabela Jaruga-Nowacka', role:'Poseł, b. Wicepremier (Lewica)', party:'other', img:'https://api.sejm.gov.pl/sejm/term6/MP/132/photo',
desc:'Izabela Jaruga-Nowacka (ur. 26 III 1950, zm. 10 IV 2010) — Działaczka lewicowa, Wicepremier w rządzie Marka Belki (20042005). Feministka, działaczka na rzecz praw kobiet. Zginęła jako jedna z reprezentantek całego polskiego parlamentu.' },
{ lp:11, name:'Sebastian Karpiniuk', role:'Poseł Platformy Obywatelskiej', party:'other', img:'https://api.sejm.gov.pl/sejm/term6/MP/146/photo',
desc:'Sebastian Karpiniuk (ur. 30 VII 1977, zm. 10 IV 2010) — Jeden z najmłodszych ofiar katastrofy (32 lata). Poseł PO, adwokat z Koszalina. Miał przed sobą całą karierę polityczną. Leciał jako przedstawiciel partii na uroczystości katyńskie.' },
{ lp:12, name:'Arkadiusz Rybicki', role:'Poseł Platformy Obywatelskiej', party:'other', img:'https://api.sejm.gov.pl/sejm/term6/MP/326/photo',
desc:'Arkadiusz Rybicki (ur. 14 III 1953, zm. 10 IV 2010) — Poseł PO, wieloletni działacz opozycji, współpracownik Lecha Wałęsy. Gdańszczanin, uczestnik wydarzeń Sierpnia 1980. Katastrofa zabrała reprezentantów całej polskiej sceny politycznej.' },
{ lp:13, name:'Jolanta Szymanek-Deresz', role:'Poseł SLD', party:'other', img:'https://api.sejm.gov.pl/sejm/term6/MP/382/photo',
desc:'Jolanta Szymanek-Deresz (ur. 19 VI 1965, zm. 10 IV 2010) — Prawnik, poseł SLD. Związana z lewicową kancelarią prawną. Leciała jako przedstawicielka lewicy polskiej na uroczystości katyńskie.' },
{ lp:14, name:'Edward Wojtas', role:'Poseł Polskiego Stronnictwa Ludowego', party:'other', img:'https://api.sejm.gov.pl/sejm/term6/MP/422/photo',
desc:'Edward Wojtas (ur. 21 IV 1947, zm. 10 IV 2010) — Poseł PSL, wieloletni działacz ludowy. Reprezentant środowisk wiejskich. Leciał jako przedstawiciel PSL na obchody rocznicy zbrodni katyńskiej.' },
// KANCELARIA PREZYDENTA
{ lp:15, name:'Władysław Stasiak', role:'Szef Kancelarii Prezydenta RP', party:'other', img:null,
desc:'Władysław Stasiak (ur. 4 VI 1966, zm. 10 IV 2010) — Szef Kancelarii Prezydenta RP, jeden z najbliższych współpracowników Prezydenta Kaczyńskiego. Prawnik, wcześniej Szef MSWiA. Jedna z kluczowych strat dla Kancelarii Prezydenta.' },
{ lp:16, name:'Paweł Wypych', role:'Sekretarz Stanu w Kancelarii Prezydenta RP', party:'other', img:null,
desc:'Paweł Wypych — Sekretarz Stanu w Kancelarii Prezydenta RP, zaufany współpracownik Lecha Kaczyńskiego. Organizator wielu oficjalnych wizyt i uroczystości państwowych.' },
{ lp:17, name:'Mariusz Handzlik', role:'Podsekretarz Stanu w Kancelarii Prezydenta', party:'other', img:null,
desc:'Mariusz Handzlik (ur. 1972, zm. 10 IV 2010) — Podsekretarz Stanu w Kancelarii Prezydenta RP, odpowiedzialny za politykę zagraniczną. Dyplomata i urzędnik służby cywilnej.' },
{ lp:18, name:'Aleksander Szczygło', role:'Szef Biura Bezpieczeństwa Narodowego', party:'other', img:null,
desc:'Aleksander Szczygło (ur. 4 XI 1963, zm. 10 IV 2010) — Szef Biura Bezpieczeństwa Narodowego, wcześniej Szef Agencji Bezpieczeństwa Wewnętrznego (20052007). Jeden z kluczowych urzędników ds. bezpieczeństwa państwa.' },
{ lp:19, name:'Andrzej Przewoźnik', role:'Sek. Gen. Rady Ochrony Pamięci Walk i Męczeństwa', party:'other', img:null,
desc:'Andrzej Przewoźnik (ur. 17 II 1963, zm. 10 IV 2010) — Historyk, Sekretarz Generalny Rady Ochrony Pamięci Walk i Męczeństwa. Jeden z głównych organizatorów uroczystości katyńskich — zginął jadąc na uroczystości, których organizacji poświęcił lata.' },
// RZĄD I URZĘDNICY
{ lp:20, name:'Sławomir Skrzypek', role:'Prezes Narodowego Banku Polskiego', party:'other', img:null,
desc:'Sławomir Skrzypek (ur. 1 X 1963, zm. 10 IV 2010) — Prezes NBP od 2007 r., ekonomista. Jego śmierć sparaliżowała polską politykę monetarną i wymagała pilnego wyłonienia następcy. Zginął jako jeden z kluczowych filarów stabilności polskiej gospodarki.' },
{ lp:21, name:'Janusz Kochanowski', role:'Rzecznik Praw Obywatelskich', party:'other', img:null,
desc:'Janusz Kochanowski (ur. 8 XI 1940, zm. 10 IV 2010) — Rzecznik Praw Obywatelskich, prawnik, profesor. Aktywny obrońca praw jednostki. Leciał jako strażnik praw obywatelskich na uroczystości upamiętniające ofiary Katynia.' },
{ lp:22, name:'Tomasz Merta', role:'Podsekretarz Stanu, Min. Kultury i Dziedzictwa', party:'other', img:null,
desc:'Tomasz Merta (ur. 5 II 1965, zm. 10 IV 2010) — Historyk idei, Podsekretarz Stanu w MKiDN. Ekspert ds. polityki historycznej, autor prac o pamięci i tożsamości narodowej. Zginął lecąc na uroczystości upamiętniające jedną z największych zbrodni w historii Polski.' },
{ lp:23, name:'Andrzej Kremer', role:'Wiceminister Spraw Zagranicznych', party:'other', img:null,
desc:'Andrzej Kremer (ur. 30 XI 1961, zm. 10 IV 2010) — Wiceminister Spraw Zagranicznych, dyplomata. Specjalista ds. prawa konsularnego i ochrony Polaków za granicą. Jeden z kluczowych dyplomatów MSZ.' },
{ lp:24, name:'Stanisław Mikke', role:'Adwokat, Redaktor Naczelny Palestry', party:'other', img:null,
desc:'Stanisław Mikke — Adwokat, Redaktor Naczelny miesięcznika Palestra. Leciał jako przedstawiciel palestry polskiej na uroczystości katyńskie. Autor wielu publikacji poświęconych zbrodni katyńskiej i losom polskich prawników.' },
// WOJSKO
{ lp:25, name:'gen. Franciszek Gągor', role:'Szef Sztabu Generalnego Wojska Polskiego', party:'mil', img:null,
desc:'Gen. broni Franciszek Gągor (ur. 24 IX 1952, zm. 10 IV 2010) — Szef Sztabu Generalnego WP od 2006 r. Najważniejszy dowódca polskich sił zbrojnych. Jego śmierć, wraz ze śmiercią dowódców wszystkich rodzajów sił zbrojnych, to bezprecedensowa w historii Polski tragedia wojskowa.' },
{ lp:26, name:'gen. Andrzej Błasik', role:'Dowódca Sił Powietrznych RP', party:'mil', img:null,
desc:'Gen. broni pil. Andrzej Błasik (ur. 24 IX 1962, zm. 10 IV 2010) — Dowódca Sił Powietrznych RP. Pilot wojskowy, jeden z najdoświadczejszych polskich lotników wojskowych. Komisja Macierewicza zarzuca, że jego obecność w kokpicie mogła wywierać presję na pilotów.' },
{ lp:27, name:'gen. Tadeusz Buk', role:'Dowódca Wojsk Lądowych RP', party:'mil', img:null,
desc:'Gen. broni Tadeusz Buk (ur. 28 VII 1956, zm. 10 IV 2010) — Dowódca Wojsk Lądowych RP. W jednej katastrofie Polska straciła dowódców wszystkich kluczowych rodzajów sił zbrojnych — taka strata nie wydarzyła się w żadnym innym kraju NATO.' },
{ lp:28, name:'adm. Andrzej Karweta', role:'Dowódca Marynarki Wojennej RP', party:'mil', img:null,
desc:'Wiceadm. Andrzej Karweta (ur. 20 VI 1956, zm. 10 IV 2010) — Dowódca Marynarki Wojennej RP. Wraz z nim zginęli dowódcy sił lądowych, powietrznych i specjalnych — w jednej chwili Polska straciła całe wojskowe kierownictwo.' },
{ lp:29, name:'gen. Włodzimierz Potasiński', role:'Dowódca Sił Specjalnych RP', party:'mil', img:null,
desc:'Gen. broni Włodzimierz Potasiński (ur. 16 VII 1956, zm. 10 IV 2010) — Dowódca Wojsk Specjalnych RP. Jeden z twórców polskich sił specjalnych, wieloletni żołnierz służący m.in. w GROM. Symbol profesjonalizmu polskiego wojska.' },
{ lp:30, name:'gen. Stanisław Nałęcz-Komornicki', role:'Szef Inspektoratu Wsparcia SZ', party:'mil', img:null,
desc:'Gen. dyw. Stanisław Nałęcz-Komornicki (ur. 4 VII 1955, zm. 10 IV 2010) — Szef Inspektoratu Wsparcia Sił Zbrojnych. Jeden z kluczowych generałów odpowiedzialnych za logistykę i wsparcie bojowe polskiej armii.' },
{ lp:31, name:'gen. Bronisław Kwiatkowski', role:'Komendant Główny Żandarmerii Wojskowej', party:'mil', img:null,
desc:'Gen. bryg. Bronisław Kwiatkowski — Komendant Główny Żandarmerii Wojskowej. Odpowiadał za bezpieczeństwo i dyscyplinę w Wojsku Polskim. Zginął jako jeden z wielu oficerów, którzy wybrali się uczcić pamięć ofiar Katynia.' },
{ lp:32, name:'gen. Tadeusz Płoski', role:'Ordynariusz Polowy Wojska Polskiego', party:'mil', img:null,
desc:'Bp gen. dyw. Tadeusz Płoski (ur. 13 IX 1956, zm. 10 IV 2010) — Biskup Polowy Wojska Polskiego, Ordynariusz Polowy WP. Kapłan i generał. Leciał jako duszpasterz wojska na modlitwę za dusze oficerów zamordowanych w Katyniu.' },
// KLER
{ lp:33, name:'ks. prał. Józef Joniec', role:'Kapelan Wojska Polskiego', party:'other', img:null,
desc:'Ks. prał. Józef Joniec — Kapelan Wojska Polskiego. Leciał razem z bp. Tadeuszem Płoskim na uroczystości religijno-patriotyczne do Katynia, gdzie zginęli polscy kapłani i oficerowie zamordowani przez NKWD.' },
{ lp:34, name:'ks. Ryszard Blajda', role:'Kapelan Biura Ochrony Rządu', party:'other', img:null,
desc:'Ks. Ryszard Blajda — Kapelan Biura Ochrony Rządu (BOR), duchowny towarzyszący oficjalnym delegacjom rządowym. Zginął pełniąc swą służbę kapelańską przy oficjalnej delegacji państwowej.' },
// ZAŁOGA TU-154M
{ lp:35, name:'ppłk Arkadiusz Protasiuk', role:'Kapitan samolotu Tu-154M (36 lat)', party:'mil', img:null,
desc:'Ppłk Arkadiusz Protasiuk (ur. 23 VII 1973, zm. 10 IV 2010) — Kapitan Tu-154M, pilot wojskowy z ponad 3500 godzinami nalotu. Miał 36 lat. Komisja Macierewicza kwestionuje ustalenia MAK obciążające załogę, twierdząc że piloci byli prowadzeni nieprawidłowo przez rosyjską kontrolę lotów.' },
{ lp:36, name:'mjr Robert Grzywna', role:'Drugi Pilot samolotu Tu-154M', party:'mil', img:null,
desc:'Mjr Robert Grzywna — Drugi Pilot Tu-154M, doświadczony wojskowy pilot transportowy. Zginął wykonując służbę, pilotując samolot z najważniejszymi osobami w państwie polskim.' },
{ lp:37, name:'kpt. Artur Ziętek', role:'Trzeci Pilot samolotu Tu-154M', party:'mil', img:null,
desc:'Kpt. Artur Ziętek — Trzeci Pilot Tu-154M. Jeden z trzech pilotów w kokpicie feralnego lotu. Wszyscy zginęli wraz z 93 pasażerami na pokładzie.' },
{ lp:38, name:'mjr Bartłomiej Michalak', role:'Nawigator samolotu Tu-154M', party:'mil', img:null,
desc:'Mjr Bartłomiej Michalak — Nawigator Tu-154M. Odpowiedzialny za nawigację podczas podejścia do lotniska Siewierny. Komisja Macierewicza zarzuca, że rosyjska kontrola lotów podawała błędne dane nawigacyjne.' },
{ lp:39, name:'chor. Andrzej Michalak', role:'Mechanik pokładowy samolotu Tu-154M', party:'mil', img:null,
desc:'Chor. Andrzej Michalak — Mechanik pokładowy Tu-154M. Odpowiadał za stan techniczny samolotu. Komisja Macierewicza stwierdza, że Tu-154M był sprawny technicznie przed katastrofą — co podważa tezę o awarii technicznej.' },
];
const MACIEREWICZ_TEZY = [
{ nr:'1', teza:'Dwa wybuchy przed zderzeniem z ziemią', opis:'Komisja stwierdza, że akustyczna analiza nagrań z CVR (rejestratora głosu) wykazuje dwa wybuchy o charakterystyce niezgodnej z uderzeniem w drzewo — w 8 s i 1 s przed katastrofą.', dowod:'Analiza spektralna nagrań CVR; zeznania biegłych dr hab. Kazimierza Nowaczyka i prof. Wiesława Biniendy.', status:'Kwestionowane przez MAK i inne niezależne analizy' },
{ nr:'2', teza:'Ślady trotylu i nitrogliceryny w szczątkach', opis:'Instytut Techniczny Wojsk Lotniczych (ITWL) i prof. M. Żyluk potwierdzają wykrycie śladów materiałów wybuchowych klasy RDX i PETN na szczątkach samolotu i ciałach ofiar.', dowod:'Badania ITWL; raporty kryminalistyczne zlecone przez komisję.', status:'Strona rosyjska i MAK zaprzeczają wynikom' },
{ nr:'3', teza:'Detonacja lewego skrzydła', opis:'Analiza wideo i zdjęć satelitarnych wskazuje na asymetryczny rozpad płatowca — lewe skrzydło zostało oderwane zanim doszło do uderzenia w ziemię, co sugeruje zewnętrzną detonację.', dowod:'Analiza nagrań z kamer lotniskowych; symulacje CFD Instytutu Lotnictwa.', status:'Brak potwierdzenia przez niezależnych biegłych lotniczych' },
{ nr:'4', teza:'Nieprawidłowe prowadzenie przez kontrolę lotów w Smoleńsku', opis:'Rosyjscy kontrolerzy lotów podawali błędne informacje o pozycji samolotu i warunkach meteorologicznych. Lotnisko Siewierny nie spełniało norm ICAO dla lądowań w złych warunkach.', dowod:'Nagrania łączności ATC; protokoły rosyjskie MAK; zeznania pilotów-biegłych.', status:'Potwierdzone częściowo przez raport MAK' },
{ nr:'5', teza:'Zapis CVR wskazuje na wejście obcych osób do kokpitu', opis:'Komisja interpretuje fragmenty nagrania CVR jako dowód wejścia nieautoryzowanych osób do kokpitu, co mogło zakłócić procedury pilotów.', dowod:'Transkrypcja CVR analizowana przez komisję — interpretacja alternatywna do wersji MAK.', status:'Wersja komisji — niepotwierdzony w innych analizach' },
{ nr:'6', teza:'Zatajenie i zniszczenie dowodów przez Rosję', opis:'Szczątki samolotu pozostały w Rosji i nie zostały w pełni zwrócone Polsce. Komisja stwierdza, że doszło do celowego niszczenia, przemieszczania i ukrywania dowodów materialnych.', dowod:'Lista niezwróconych elementów Tu-154M; protokoły przekazania szczątków; raporty KBWLLP.', status:'Potwierdzony fakt: szczątki nie zostały w pełni zwrócone' },
{ nr:'7', teza:'Celowe zniszczenie wraku przez stronę rosyjską', opis:'Komisja stwierdza, że wrak Tu-154M był celowo niszczony (rozcinanie elementów, przemieszczanie szczątków) przez władze rosyjskie, uniemożliwiając pełną rekonstrukcję zdarzenia.', dowod:'Dokumentacja fotograficzna z miejsca katastrofy; zeznania strony polskiej.', status:'Fakt: wrak przez lata przechowywany w Rosji, pełen dostęp odmówiony' },
];
function renderSmolensk() {
const featuredVictims = SMOLENSK_VICTIMS.filter(v => v.party === 'president' || v.party === 'pis').slice(0, 10);
const partyLabel = p => ({
president: ['vc-pres', 'PREZYDENT RP'],
pis: ['vc-pis', 'PiS'],
mil: ['vc-mil', 'WOJSKO'],
sld: ['vc-sld', 'SLD'],
other: ['vc-other', 'INNA'],
}[p] || ['vc-other', '']);
const victimFeaturedCard = v => {
const [cls, label] = partyLabel(v.party);
const photo = v.img
? `<img src="${escHtml(v.img)}" alt="${escHtml(v.name)}" onerror="this.onerror=null;this.style.display='none'">`
: `<div style="height:140px;display:flex;align-items:center;justify-content:center;font-size:3rem;background:var(--border)">👤</div>`;
return `
<div class="victim-card ${v.party === 'president' ? 'president' : v.party === 'pis' ? 'pis' : ''}" data-sm="${v.lp}" style="cursor:pointer">
${photo}
<div class="vc-body">
<div class="vc-name">${escHtml(v.name)}</div>
<div class="vc-role">${escHtml(v.role)}</div>
<span class="vc-party ${cls}">${label}</span>
</div>
</div>`;
};
const victimTableRow = v => {
const [cls, label] = partyLabel(v.party);
const rowCls = v.party === 'president' ? 'pres-row' : v.party === 'pis' ? 'pis-row' : '';
return `<tr class="${rowCls}" data-sm="${v.lp}" style="cursor:pointer">
<td class="lp">${v.lp}</td>
<td><strong>${escHtml(v.name)}</strong></td>
<td>${escHtml(v.role)}</td>
<td><span class="vc-party ${cls}" style="display:inline-block">${label}</span></td>
</tr>`;
};
return `<div class="smolensk-page">
<!-- HERO -->
<div class="sm-hero">
<div class="sm-candles">🕯🕯🕯🕯🕯🕯🕯🕯🕯🕯</div>
<div class="sm-hero-date">10 Kwietnia 2010 · Smoleńsk, Rosja · Godzina 08:41 UTC</div>
<div class="sm-hero-title">✈ KATASTROFA SMOLEŃSKA</div>
<div class="sm-hero-sub">Katastrofa lotnicza polskiego samolotu Tu-154M w pobliżu lotniska Siewierny w Smoleńsku, przewożącego polską delegację na obchody 70. rocznicy zbrodni katyńskiej. Zginęli Prezydent RP, dowódcy wszystkich rodzajów sił zbrojnych i najwyżsi urzędnicy państwowi.</div>
<div class="sm-hero-stats">
<div class="sm-stat"><div class="n">96</div><div class="l">Ofiar śmiertelnych</div></div>
<div class="sm-stat"><div class="n">0</div><div class="l">Ocalałych</div></div>
<div class="sm-stat"><div class="n">Tu-154M</div><div class="l">Typ samolotu</div></div>
<div class="sm-stat"><div class="n">2010</div><div class="l">Rok katastrofy</div></div>
</div>
<div class="sm-countdown-wrap">
<div class="sm-countdown-label">⏱ Kiedy dowiemy się prawdy? Minęło już:</div>
<div class="sm-countdown" id="sm-countdown">
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">lat</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">mies.</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">dni</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">godz.</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">min.</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit"><span class="cd-n"></span><span class="cd-l">sek.</span></span>
<span class="cd-sep">·</span>
<span class="cd-unit cd-ms"><span class="cd-n">–––</span><span class="cd-l">ms</span></span>
</div>
</div>
<div class="sm-candles">🕯🕯🕯🕯🕯🕯🕯🕯🕯🕯</div>
</div>
<!-- MAPA LOTU -->
<div class="sm-map-wrap">
<div class="sm-map-title">✈ Trasa lotu TU-154M &nbsp;·&nbsp; Warszawa → Smoleńsk &nbsp;·&nbsp; 10 IV 2010</div>
<svg class="sm-map-svg" viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="sm-glow" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="sm-fog" x="-20%" y="-20%" width="140%" height="140%">
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="4" result="noise"/>
<feColorMatrix type="saturate" values="0" in="noise" result="grey"/>
<feBlend in="SourceGraphic" in2="grey" mode="screen" result="blend"/>
<feComposite in="blend" in2="SourceGraphic" operator="in"/>
</filter>
<radialGradient id="sm-bg" cx="40%" cy="50%" r="70%">
<stop offset="0%" stop-color="#091624"/>
<stop offset="100%" stop-color="#04090f"/>
</radialGradient>
<linearGradient id="fog-grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#b0c4de" stop-opacity="0"/>
<stop offset="60%" stop-color="#b0c4de" stop-opacity="0.18"/>
<stop offset="100%" stop-color="#b0c4de" stop-opacity="0.35"/>
</linearGradient>
</defs>
<!-- Background ocean/land base -->
<rect width="1000" height="500" fill="url(#sm-bg)"/>
<rect width="1000" height="500" class="country-other"/>
<!-- ── ROSJA (duży obszar na wschodzie) ── -->
<path class="country-russia" d="M 554,83 L 1000,0 L 1000,500 L 430,500 L 430,314 L 571,300 L 714,277 L 714,183 L 643,115 Z"/>
<!-- ── BIAŁORUŚ ── -->
<polygon class="country-belarus" points="
404,188 436,188 482,138 519,97 554,83
643,115 714,183 714,277 571,300 430,314
421,273 404,188"/>
<!-- ── POLSKA ── corrected shape -->
<polygon class="country-poland" points="
79,188 90,165 147,156 191,151
236,156 245,170 310,165 390,183
404,188 421,273 430,314
376,410 290,396 234,388
143,343 107,320 93,283 82,232"/>
<!-- ── LITWA (schematyczna) ── -->
<polygon fill="#1e293b" fill-opacity="0.5" stroke="#334155" stroke-width="0.8"
points="390,183 404,188 436,188 482,138 519,97 429,80 380,100 360,150"/>
<!-- ── ŁOTWA (schematyczna) ── -->
<polygon fill="#172034" fill-opacity="0.5" stroke="#334155" stroke-width="0.8"
points="429,80 519,97 554,83 520,48 460,50 429,80"/>
<!-- ── UKRAINA (fragment południa) ── -->
<polygon fill="#172034" fill-opacity="0.4" stroke="#334155" stroke-width="0.8"
points="93,283 107,320 143,343 234,388 290,396 376,410 430,410 571,430 714,410 714,500 0,500 0,350"/>
<!-- Baltic sea -->
<ellipse cx="168" cy="110" rx="155" ry="78" class="sea" opacity="0.9"/>
<!-- small Gulf details -->
<ellipse cx="310" cy="105" rx="60" ry="30" class="sea" opacity="0.6"/>
<!-- Fog gradient overlay (eastern part — around Smolensk) -->
<rect x="500" y="0" width="500" height="500" fill="url(#fog-grad)" pointer-events="none"/>
<!-- Grid / graticule -->
<line x1="143" y1="0" x2="143" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="286" y1="0" x2="286" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="429" y1="0" x2="429" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="571" y1="0" x2="571" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="714" y1="0" x2="714" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="857" y1="0" x2="857" y2="500" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="0" y1="125" x2="1000" y2="125" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="0" y1="250" x2="1000" y2="250" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<line x1="0" y1="375" x2="1000" y2="375" stroke="#1e3a8a" stroke-width="0.4" opacity="0.2"/>
<!-- Country labels -->
<text x="200" y="280" fill="#60a5fa" font-size="18" font-weight="bold" opacity="0.5" letter-spacing="2">POLSKA</text>
<text x="530" y="210" fill="#9ca3af" font-size="14" opacity="0.45" letter-spacing="1">BIAŁORUŚ</text>
<text x="800" y="220" fill="#6b7280" font-size="14" opacity="0.38" letter-spacing="1">ROSJA</text>
<text x="420" y="145" fill="#475569" font-size="11" opacity="0.45">LITWA</text>
<text x="468" y="68" fill="#374151" font-size="10" opacity="0.4">ŁOTWA</text>
<text x="200" y="440" fill="#374151" font-size="12" opacity="0.35">UKRAINA</text>
<!-- ── TRASA LOTU ── -->
<!-- glow beneath path -->
<path d="M 321,264 Q 520,55 716,145" fill="none" stroke="#3b82f6" stroke-width="16" opacity="0.06"/>
<!-- main dashed path -->
<path id="sm-fp" d="M 321,264 Q 520,55 716,145"
fill="none" stroke="#3b82f6" stroke-width="2.5" stroke-dasharray="10,6" opacity="0.8"/>
<!-- distance label -->
<text dy="-9" font-size="11" fill="#93c5fd" opacity="0.7">
<textPath href="#sm-fp" startOffset="43%">1 312 km</textPath>
</text>
<!-- ── WARSZAWA ── -->
<g class="map-marker" data-sm-map="warsaw" style="cursor:pointer">
<circle cx="321" cy="264" r="11" fill="#1e40af" stroke="#3b82f6" stroke-width="2" opacity="0.95" filter="url(#sm-glow)"/>
<circle cx="321" cy="264" r="4.5" fill="#bfdbfe"/>
<text x="321" y="292" text-anchor="middle" font-size="12" fill="#93c5fd" font-weight="700" letter-spacing="0.5">WARSZAWA</text>
<text x="321" y="305" text-anchor="middle" font-size="9" fill="#60a5fa" opacity="0.7">Lotnisko Okęcie · start</text>
</g>
<!-- ── SOPOT (TuskPutin molo) ── -->
<g class="map-marker" data-sm-map="sopot" style="cursor:pointer">
<circle cx="235" cy="162" r="9" fill="#7c3aed" stroke="#a78bfa" stroke-width="2" opacity="0.9" filter="url(#sm-glow)"/>
<circle cx="235" cy="162" r="3.5" fill="#ddd6fe"/>
<text x="235" y="186" text-anchor="middle" font-size="10" fill="#c4b5fd" font-weight="600">SOPOT</text>
<text x="235" y="197" text-anchor="middle" font-size="8" fill="#a78bfa" opacity="0.8">01.09.2009</text>
</g>
<!-- ── SMOLEŃSK (crash) ── -->
<g class="map-marker crash-site" data-sm-map="smolensk" style="cursor:pointer">
<circle cx="716" cy="145" r="14" fill="#7f1d1d" stroke="#ef4444" stroke-width="3" filter="url(#sm-glow)"/>
<circle cx="716" cy="145" r="6" fill="#fca5a5"/>
<text x="716" y="122" text-anchor="middle" font-size="16" filter="url(#sm-glow)">💥</text>
<text x="716" y="175" text-anchor="middle" font-size="12" fill="#fca5a5" font-weight="700" letter-spacing="0.5">SMOLEŃSK</text>
<text x="716" y="189" text-anchor="middle" font-size="9" fill="#f87171" opacity="0.85">Siewierny · 10.04.2010 · 08:41</text>
</g>
<!-- ── KATYŃ ── -->
<g class="map-marker" data-sm-map="katyn" style="cursor:pointer">
<circle cx="746" cy="174" r="7" fill="#374151" stroke="#6b7280" stroke-width="1.5"/>
<circle cx="746" cy="174" r="2.5" fill="#9ca3af"/>
<text x="775" y="179" font-size="9" fill="#9ca3af" opacity="0.75">Katyń ✝</text>
</g>
<!-- ── SAMOLOT animowany ── (hover shows crew) -->
<g id="sm-plane-g" data-sm-map="plane" style="cursor:pointer">
<text font-size="22" dy="3" text-anchor="middle" fill="#fbbf24" filter="url(#sm-glow)">✈<animateMotion dur="11s" repeatCount="indefinite" rotate="auto"><mpath href="#sm-fp"/></animateMotion></text>
</g>
<!-- ── LEGENDA ── -->
<rect x="12" y="12" width="178" height="108" rx="7" fill="rgba(4,9,15,0.9)" stroke="#1e3a8a" stroke-width="1"/>
<text x="24" y="32" font-size="10" fill="#93c5fd" font-weight="700" letter-spacing="1">LEGENDA</text>
<circle cx="28" cy="50" r="6" fill="#1e40af" stroke="#3b82f6" stroke-width="1.5"/>
<text x="40" y="54" font-size="10" fill="#94a3b8">Punkt startowy</text>
<circle cx="28" cy="70" r="6" fill="#7f1d1d" stroke="#ef4444" stroke-width="1.5"/>
<text x="40" y="74" font-size="10" fill="#94a3b8">Katastrofa</text>
<circle cx="28" cy="90" r="6" fill="#7c3aed" stroke="#a78bfa" stroke-width="1.5"/>
<text x="40" y="94" font-size="10" fill="#94a3b8">Sopot · Tusk/Putin</text>
<line x1="20" y1="108" x2="50" y2="108" stroke="#3b82f6" stroke-width="2" stroke-dasharray="7,4"/>
<text x="58" y="112" font-size="10" fill="#94a3b8">Trasa lotu</text>
</svg>
<div style="font-size:0.7rem;color:var(--muted);padding:7px 16px;border-top:1px solid #1e3a8a;background:rgba(0,0,0,0.35)">
Najedź myszką na znaczniki mapy aby zobaczyć szczegóły · Animowany ✈ — najedź aby zobaczyć załogę · Mapa poglądowa
</div>
</div>
<!-- INTERAKTYWNY MODEL TUPOŁEWA TU-154M -->
<div class="sm-section">
<div class="sm-section-title">🛩 Interaktywny model Tu-154M — komponenty i uszkodzenia</div>
<p style="font-size:0.75rem;color:var(--muted);margin-bottom:12px">Najedź myszką na zaznaczone elementy, aby zobaczyć opis. Czerwone markery — miejsca rzekomych ładunków wg komisji Macierewicza. Pomarańczowe — miejsca uderzeń. Niebieski obrys — zasięg mgły przy podejściu.</p>
<div class="tu154-wrap">
<svg class="tu154-svg" viewBox="0 0 900 320" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="tu-glow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="4" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<radialGradient id="fog-r" cx="85%" cy="50%" r="50%">
<stop offset="0%" stop-color="#b0c8e0" stop-opacity="0.55"/>
<stop offset="100%" stop-color="#b0c8e0" stop-opacity="0"/>
</radialGradient>
<linearGradient id="fus-grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#374151"/>
<stop offset="40%" stop-color="#4b5563"/>
<stop offset="100%" stop-color="#1f2937"/>
</linearGradient>
<linearGradient id="wing-grad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#4b5563"/>
<stop offset="100%" stop-color="#374151"/>
</linearGradient>
</defs>
<!-- ══ KADŁUB (fuselage) ══ -->
<path class="tu-fuselage" data-tu="fuselage" style="cursor:pointer"
d="M 68,148
C 68,120 88,108 115,106
L 680,100
L 730,96 L 780,93 C 820,91 840,108 840,148
C 840,188 820,205 780,203
L 730,200 L 680,196
L 115,190 C 88,188 68,176 68,148 Z"/>
<!-- ══ LEWE SKRZYDŁO (left wing — bomb allegedly here) ══ -->
<path class="tu-wing" data-tu="left_wing" style="cursor:pointer"
d="M 360,190 L 460,190 L 560,295 L 480,295 Z"/>
<!-- ══ PRAWE SKRZYDŁO (right wing — top view hint) ══ -->
<path class="tu-wing" data-tu="right_wing" style="cursor:pointer"
d="M 360,106 L 460,106 L 560,10 L 480,10 Z"/>
<!-- ══ STATECZNIK PIONOWY (vertical stabilizer) ══ -->
<path class="tu-vstab" data-tu="vstab" style="cursor:pointer"
d="M 720,100 L 710,28 L 755,28 L 770,100 Z"/>
<!-- ══ STATECZNIKI POZIOME (horizontal stabilizers) ══ -->
<path class="tu-hstab" data-tu="hstab_l" style="cursor:pointer"
d="M 790,196 L 810,196 L 870,240 L 840,240 Z"/>
<path class="tu-hstab" data-tu="hstab_r" style="cursor:pointer"
d="M 790,100 L 810,100 L 870,60 L 840,60 Z"/>
<!-- ══ SILNIKI (engines) ══ -->
<!-- Lewy silnik boczny -->
<ellipse class="tu-engine" data-tu="engine_l" style="cursor:pointer" cx="800" cy="205" rx="40" ry="14"/>
<!-- Prawy silnik boczny -->
<ellipse class="tu-engine" data-tu="engine_r" style="cursor:pointer" cx="800" cy="91" rx="40" ry="14"/>
<!-- Środkowy silnik (w stateczniku pionowym) -->
<rect class="tu-engine" data-tu="engine_c" style="cursor:pointer" x="828" y="120" width="44" height="56" rx="4"/>
<!-- ══ NOS (cockpit + nose) ══ -->
<ellipse class="tu-nose" data-tu="nose" style="cursor:pointer" cx="85" cy="148" rx="42" ry="35"/>
<!-- Okna kabiny pilotów -->
<ellipse fill="#1d4ed8" fill-opacity="0.7" cx="100" cy="138" rx="12" ry="7"/>
<ellipse fill="#1d4ed8" fill-opacity="0.7" cx="100" cy="158" rx="12" ry="7"/>
<!-- ══ KABINA PASAŻERÓW (windows strip) ══ -->
<rect fill="#1d4ed8" fill-opacity="0.3" x="150" y="118" width="510" height="8" rx="3"/>
<rect fill="#1d4ed8" fill-opacity="0.3" x="150" y="170" width="510" height="8" rx="3"/>
<!-- ══ ZNACZNIKI USZKODZEŃ / ŁADUNKÓW ══ -->
<!-- ŁADUNEK 1 — lewe skrzydło (wg Macierewicza) -->
<g data-tu="bomb1" style="cursor:pointer">
<circle cx="430" cy="230" r="16" fill="#ef4444" fill-opacity="0.25" stroke="#ef4444" stroke-width="2" stroke-dasharray="5,3">
<animate attributeName="r" values="14;18;14" dur="1.8s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.5;1" dur="1.8s" repeatCount="indefinite"/>
</circle>
<text x="430" y="235" text-anchor="middle" font-size="14" fill="#ef4444">💣</text>
<text x="430" y="253" text-anchor="middle" font-size="8" fill="#fca5a5" font-weight="700">ŁADUNEK 1</text>
</g>
<!-- ŁADUNEK 2 — nosowa część (wg Macierewicza) -->
<g data-tu="bomb2" style="cursor:pointer">
<circle cx="130" cy="148" r="16" fill="#ef4444" fill-opacity="0.25" stroke="#ef4444" stroke-width="2" stroke-dasharray="5,3">
<animate attributeName="r" values="14;18;14" dur="2.2s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.5;1" dur="2.2s" repeatCount="indefinite"/>
</circle>
<text x="130" y="153" text-anchor="middle" font-size="14" fill="#ef4444">💣</text>
<text x="130" y="171" text-anchor="middle" font-size="8" fill="#fca5a5" font-weight="700">ŁADUNEK 2</text>
</g>
<!-- PANCERNA BRZOZA — uderzenie w skrzydło lewe -->
<g data-tu="birch" style="cursor:pointer">
<line x1="505" y1="250" x2="460" y2="220" stroke="#f59e0b" stroke-width="3" stroke-dasharray="6,3"/>
<circle cx="505" cy="255" r="12" fill="#f59e0b" fill-opacity="0.3" stroke="#f59e0b" stroke-width="2"/>
<text x="505" y="260" text-anchor="middle" font-size="14">🌳</text>
<text x="505" y="277" text-anchor="middle" font-size="8" fill="#fbbf24" font-weight="700">BRZOZA</text>
</g>
<!-- MGŁA wokół samolotu (przy podejściu) -->
<ellipse cx="700" cy="148" rx="220" ry="110" fill="url(#fog-r)" pointer-events="none"/>
<text x="865" y="148" text-anchor="middle" font-size="10" fill="#93c5fd" opacity="0.6">MGŁA</text>
<text x="865" y="162" text-anchor="middle" font-size="8" fill="#64748b" opacity="0.7">~500m widocz.</text>
<!-- ETYKIETY KOMPONENTÓW -->
<text x="85" y="260" text-anchor="middle" font-size="9" fill="#94a3b8">NOS</text>
<text x="85" y="272" text-anchor="middle" font-size="8" fill="#64748b">kabina pilotów</text>
<line x1="85" y1="184" x2="85" y2="252" stroke="#475569" stroke-width="0.8" stroke-dasharray="3,2"/>
<text x="310" y="270" text-anchor="middle" font-size="9" fill="#94a3b8">LEWE SKRZYDŁO</text>
<line x1="360" y1="240" x2="330" y2="262" stroke="#475569" stroke-width="0.8" stroke-dasharray="3,2"/>
<text x="310" y="50" text-anchor="middle" font-size="9" fill="#94a3b8">PRAWE SKRZYDŁO</text>
<line x1="360" y1="106" x2="330" y2="58" stroke="#475569" stroke-width="0.8" stroke-dasharray="3,2"/>
<text x="740" y="20" text-anchor="middle" font-size="9" fill="#94a3b8">STER WYSOKOŚCI</text>
<text x="870" y="148" text-anchor="start" font-size="9" fill="#94a3b8" x="875">SILNIK</text>
<text x="875" y="160" font-size="8" fill="#64748b">środkowy</text>
</svg>
<!-- legenda diagramu -->
<div class="tu154-legend">
<span class="tu154-leg-item red">💣 Rzekome miejsca ładunków wg Komisji Macierewicza</span>
<span class="tu154-leg-item orange">🌳 Miejsce uderzenia w "pancerną brzozę"</span>
<span class="tu154-leg-item blue">🌫 Zasięg mgły podczas podejścia do lądowania</span>
</div>
</div>
</div>
<!-- WERSJE KATASTROFY -->
<div class="sm-section">
<div class="sm-section-title">⚖️ Wersje przyczyn katastrofy — porównanie</div>
<div class="versions-grid">
<div class="version-box official">
<h4>📋 Wersja oficjalna — Raport MAK (Rosja) i KBWLLP</h4>
<ul>
<li>Wypadek lotniczy — błędy załogi podczas podejścia do lądowania</li>
<li>Nieprawidłowe decyzje o kontynuowaniu podejścia w złej pogodzie</li>
<li>Zejście poniżej minimalnej wysokości decyzji bez widoczności</li>
<li>Zderzenie z drzewami, rozpad samolotu, pożar</li>
<li>Możliwy wpływ presji psychologicznej na załogę</li>
<li>Nieodpowiednie wyszkolenie do lądowania w warunkach IMC</li>
</ul>
</div>
<div class="version-box macierewicz">
<h4>🔴 Tezy Komisji Macierewicza (raport 2018/2022) — twierdzenia komisji</h4>
<ul>
<li>Dwa wybuchy wykryte na pokładzie przed zderzeniem z ziemią</li>
<li>Ślady materiałów wybuchowych (RDX, PETN) na szczątkach</li>
<li>Asymetryczny rozpad płatowca sugerujący zewnętrzną detonację</li>
<li>Celowe wprowadzenie załogi w błąd przez rosyjską kontrolę lotów</li>
<li>Zniszczenie i ukrywanie dowodów przez stronę rosyjską</li>
<li>Komisja kwalifikuje zdarzenie jako zamach terrorystyczny</li>
</ul>
</div>
</div>
<p style="font-size:0.75rem;color:var(--muted);margin-top:10px;padding:8px 12px;background:rgba(255,255,255,0.03);border-radius:6px;border-left:3px solid var(--border)">
️ Powyższe tezy komisji Macierewicza są kwestionowane przez niezależnych biegłych lotniczych i kryminalistycznych. Komisja Badania Wypadków Lotniczych Lotnictwa Państwowego (KBWLLP) oraz raport MAK wskazują na wypadek. Tezy komisji parlamentarnej mają charakter polityczny i nie zostały potwierdzone w niezależnych postępowaniach sądowych.
</p>
</div>
<!-- RAPORT MACIEREWICZA — SZCZEGÓŁOWE TEZY -->
<div class="sm-section">
<div class="sm-section-title">📑 Raport Podkomisji Macierewicza — główne tezy i dowody (według komisji)</div>
<table class="sm-table">
<thead>
<tr>
<th>#</th>
<th>Teza komisji</th>
<th>Powołane dowody</th>
<th>Status</th>
</tr>
</thead>
<tbody>
${MACIEREWICZ_TEZY.map(t => `
<tr>
<td style="font-weight:700;color:#ef4444">${escHtml(t.nr)}</td>
<td class="teza">${escHtml(t.teza)}</td>
<td class="dowod">${escHtml(t.opis)}<br><em style="color:#64748b">${escHtml(t.dowod)}</em></td>
<td class="status-c">${escHtml(t.status)}</td>
</tr>`).join('')}
</tbody>
</table>
</div>
<!-- OFIARY — WYRÓŻNIENI -->
<div class="sm-section">
<div class="sm-section-title">🕯 Najwyżsi urzędnicy państwowi wśród ofiar — Prezydent RP i politycy PiS</div>
<div class="victims-featured">
${SMOLENSK_VICTIMS.filter(v => v.party === 'president' || v.party === 'pis').map(victimFeaturedCard).join('')}
</div>
</div>
<!-- PEŁNA LISTA OFIAR -->
<div class="sm-section">
<div class="sm-section-title">📜 Pełna lista ofiar katastrofy smoleńskiej (96 osób)</div>
<table class="victims-table">
<thead>
<tr><th>Lp.</th><th>Imię i Nazwisko</th><th>Stanowisko / Funkcja</th><th>Kategoria</th></tr>
</thead>
<tbody>
${SMOLENSK_VICTIMS.map(victimTableRow).join('')}
<tr><td colspan="4" style="color:var(--muted);font-size:0.72rem;padding:10px;font-style:italic">… łącznie 96 osób, w tym pozostali oficerowie, członkowie delegacji i obsługa naziemna. Pełna lista na podstawie oficjalnych danych IPN i Kancelarii Prezesa Rady Ministrów.</td></tr>
</tbody>
</table>
</div>
<!-- RZĄD TUSKA A SMOLEŃSK -->
<div class="sm-section">
<div class="sm-section-title">⚠️ Rząd Donalda Tuska a katastrofa smoleńska — chronologia zaniedbań</div>
<div class="sm-timeline">
<div class="sm-tl-item">
<div class="sm-tl-time">10 Kwi 2010 — godz. 14:00</div>
<div class="sm-tl-text">Premier Tusk spotyka się z szefem rządu Rosji Władimirem Putinem w Smoleńsku. Tusk akceptuje rosyjską narrację o wypadku <strong class="sm-tl-bad">jeszcze tego samego dnia</strong> — bez własnego śledztwa, bez niezależnych biegłych.</div>
</div>
<div class="sm-tl-item">
<div class="sm-tl-time">Kwiecień–Maj 2010</div>
<div class="sm-tl-text"><strong class="sm-tl-bad">Rosja przejęła kontrolę nad śledztwem.</strong> Polska delegacja śledcza nie miała pełnego dostępu do miejsca katastrofy, szczątków i dokumentacji. Czarne skrzynki — w rękach rosyjskich przez wiele miesięcy.</div>
</div>
<div class="sm-tl-item">
<div class="sm-tl-time">Lipiec 2011</div>
<div class="sm-tl-text">Rząd Tuska przyjmuje <strong class="sm-tl-bad">raport MAK</strong> jako podstawę wyjaśnienia katastrofy — pomimo poważnych zastrzeżeń polskiej komisji (KBWLLP) i braku dostępu do pełnej dokumentacji rosyjskiej.</div>
</div>
<div class="sm-tl-item">
<div class="sm-tl-time">20102015 (cały rząd PO-PSL)</div>
<div class="sm-tl-text"><strong class="sm-tl-bad">Wrak samolotu pozostał w Rosji.</strong> Pomimo wielokrotnych próśb strony polskiej, Rosja odmówiła zwrotu wraku Tu-154M. Rząd Tuska i Kopacz nie podjął skutecznych kroków dyplomatycznych.</div>
</div>
<div class="sm-tl-item">
<div class="sm-tl-time">20102015</div>
<div class="sm-tl-text"><strong class="sm-tl-bad">Brak ekshumacji.</strong> Wiele rodzin ofiar przez lata skarżyło się na błędy w identyfikacji ciał i pochówku. Rząd PO nie podjął decyzji o ekshumacjach, blokując wyjaśnienie okoliczności śmierci.</div>
</div>
<div class="sm-tl-item">
<div class="sm-tl-time">2018 — po zmianie rządu (PiS)</div>
<div class="sm-tl-text">Rząd PiS zleca ekshumacje — potwierdzają <strong style="color:#86efac">błędy w identyfikacji</strong> wielu ofiar. Komisja Macierewicza kontynuuje pracę. Polska domaga się od Rosji zwrotu wraku i dokumentacji.</div>
</div>
</div>
</div>
<!-- TUSK & PUTIN -->
<div class="sm-section">
<div class="sm-section-title">🤝 Tusk Putin: spotkanie w cieniu katastrofy</div>
<div class="tp-box">
<div class="tp-photo-wrap">
<img src="img/tusk_putin.jpg" alt="Tusk i Putin w Smoleńsku"
onerror="this.onerror=null;this.innerHTML='<div class=\\'tp-photo-placeholder\\'>🤝</div>'">
<div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.8));padding:8px;font-size:0.7rem;color:#fca5a5;text-align:center">
Donald Tusk i Władimir Putin · Smoleńsk · 10 kwietnia 2010
</div>
</div>
<div class="tp-text">
<h3>Premier Tusk w Smoleńsku — Polska oddała śledztwo Rosji</h3>
<p>10 kwietnia 2010 roku, w dniu katastrofy, Premier Donald Tusk spotkał się z Władimirem Putinem w Smoleńsku. Transmitowane na żywo, zdjęcia i nagrania ze spotkania pokazywały ciepłą, niemal poufałą atmosferę — w dzień, gdy zginęło 96 obywateli polskich, w tym głowa państwa.</p>
<p>Krytycy rządu PO wskazują, że to właśnie to spotkanie stało się symbolem <strong>zrzeczenia się przez Polskę prawa do samodzielnego śledztwa</strong>. Tusk publicznie pochwalił Putina za zachowanie i organizację pomocy — zanim polscy śledczy mieli jakikolwiek dostęp do miejsca katastrofy.</p>
<p>Mimo wieloletnich wysiłków komisji Macierewicza, <strong>teza o zamachu nie została udowodniona</strong> w żadnym niezależnym postępowaniu. Wrak samolotu do dziś nie wrócił w całości do Polski — to fakt, który wszystkie strony polityczne uznają za skandaliczny.</p>
<span class="tp-tag">❌ Wrak Tu-154M do dziś w Rosji</span>
<span class="tp-tag" style="margin-left:6px">❌ Pełna dokumentacja niedostępna</span>
</div>
</div>
</div>
<!-- PODSUMOWANIE -->
<div class="sm-section">
<div class="sm-section-title">📊 Zestawienie — co wiemy na pewno</div>
<table class="sm-table">
<thead><tr><th>Fakt</th><th>Status</th><th>Odpowiedzialność</th></tr></thead>
<tbody>
<tr><td>96 osób zginęło, w tym Prezydent RP</td><td style="color:#22c55e">✅ Fakt bezsporny</td><td>—</td></tr>
<tr><td>Rosja prowadzi śledztwo, Polska pozbawiona pełnego dostępu</td><td style="color:#22c55e">✅ Fakt potwierdzony</td><td class="sm-tl-bad">Rząd Tuska (PO)</td></tr>
<tr><td>Wrak Tu-154M przez lata przetrzymywany w Rosji</td><td style="color:#22c55e">✅ Fakt bezsporny</td><td class="sm-tl-bad">Rząd Tuska i Kopacz</td></tr>
<tr><td>Błędy w identyfikacji i pochówku ofiar</td><td style="color:#22c55e">✅ Potwierdzone ekshumacjami</td><td class="sm-tl-bad">Rząd PO-PSL</td></tr>
<tr><td>Ślady materiałów wybuchowych</td><td style="color:#f59e0b">⚠️ Twierdzi komisja — brak niezależnego potwierdzenia</td><td>Komisja Macierewicza</td></tr>
<tr><td>Wybuchy przed zderzeniem z ziemią</td><td style="color:#f59e0b">⚠️ Twierdzi komisja — kwestionowane przez ekspertów</td><td>Komisja Macierewicza</td></tr>
<tr><td>Zamach terrorystyczny</td><td style="color:#ef4444">❌ Nieudowodnione — teza komisji politycznej</td><td>Komisja Macierewicza</td></tr>
<tr><td>Odpowiedzialność karna kogokolwiek</td><td style="color:#ef4444">❌ Brak prawomocnych wyroków</td><td>—</td></tr>
</tbody>
</table>
</div>
</div>`;
}
// ══════════════════════════════════════════════
// FETCH FROM LOCAL SERVER
// ══════════════════════════════════════════════
async function fetchGroup(groupId) {
const resp = await fetch(`/api/feeds?groups=${groupId}`);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
return data[groupId] || { status: 'error', items: [] };
}
function mapItems(groupData, source, overrideSourceId) {
return (groupData.items || []).map(item => ({
sourceId: overrideSourceId || source.id,
sourceName: source.name,
sourceIcon: source.icon,
cssClass: source.cssClass || 'src-opozycja',
oppSource: overrideSourceId ? source.name : null,
title: item.title || '(bez tytułu)',
summary: item.summary || '',
link: item.link || '#',
pubDate: item.date ? new Date(item.date) : new Date(),
thumbnail: item.thumb || null,
}));
}
// ══════════════════════════════════════════════
// LOAD ALL
// ══════════════════════════════════════════════
async function loadAll() {
allArticles = [];
loadStart = Date.now();
setBtn(true);
document.getElementById('feed-container').innerHTML =
'<div class="spinner"><div class="spin"></div>Pobieranie artykułów...</div>';
SOURCES.forEach(s => setDot(s.dotId, 'loading'));
// Main right-wing sources
const mainP = SOURCES.map(source =>
fetchGroup(source.groupId)
.then(g => {
const arts = mapItems(g, source);
allArticles.push(...arts);
setDot(source.dotId, g.status === 'ok' && arts.length ? 'ok' : 'err');
renderFeed();
})
.catch(e => { console.warn(source.name, e); setDot(source.dotId, 'err'); })
);
// Opposition sources
const OPP = [
{ groupId:'opozycja_tvn', name:'TVN24', icon:'📺', cssClass:'src-opozycja' },
{ groupId:'opozycja_tvp', name:'TVP Info', icon:'📡', cssClass:'src-opozycja' },
{ groupId:'opozycja_wyborcza', name:'Gazeta Wyborcza', icon:'📰', cssClass:'src-opozycja' },
];
const oppP = OPP.map(src =>
fetchGroup(src.groupId)
.then(g => {
const arts = mapItems(g, src, 'opozycja');
allArticles.push(...arts);
renderFeed();
})
.catch(() => {})
);
await Promise.allSettled([...mainP, ...oppP]);
renderFeed();
updateStats();
updatePoliticianCounts();
updateTopics();
document.getElementById('last-updated').textContent =
'Aktualizacja: ' + new Date().toLocaleTimeString('pl-PL');
setBtn(false);
}
// (social cards are now rendered statically in renderFeed)
// ══════════════════════════════════════════════
// RENDER
// ══════════════════════════════════════════════
function renderFeed() {
const container = document.getElementById('feed-container');
// ── SMOLEŃSK ──
if (currentFilter === 'smolensk') {
container.innerHTML = renderSmolensk();
return;
}
// ── SEJM RP ──
if (currentFilter === 'sejm') {
renderSejmPage();
return;
}
// ── WIDEO ──
if (currentFilter === 'video') {
renderVideoPage();
return;
}
// ── WIELCY POLACY ──
if (currentFilter === 'wielcy') {
renderWielcyPolacy();
return;
}
if (currentFilter === 'jp2') {
renderJP2Page();
return;
}
// ── GRA: SEJM KOMBAT ──
if (currentFilter === 'gra') {
container.innerHTML = `
<div class="section-label">🎮 Sejm Kombat — Suwerenność vs Kondominium</div>
<div class="game-wrap">
<div class="game-header">
<div class="game-header-text">
<div class="game-title">⚔️ SEJM KOMBAT</div>
<div class="game-sub">Bijatyka 2D · Walcz o suwerenność Polski!</div>
</div>
<button class="game-fs-btn" onclick="document.getElementById('sejm-frame').requestFullscreen()">⛶ Pełny ekran</button>
</div>
<div class="game-frame-wrap">
<iframe id="sejm-frame" src="smolensk.html" class="game-frame"
allowfullscreen allow="autoplay" scrolling="no"></iframe>
</div>
<div class="game-footer">
Sterowanie: <strong>WASD</strong> / Strzałki — ruch &nbsp;·&nbsp;
<strong>J</strong> — cios &nbsp;·&nbsp;
<strong>K</strong> — kopnięcie &nbsp;·&nbsp;
<strong>L</strong> — specjalny &nbsp;·&nbsp;
<strong>P</strong> — pauza
</div>
</div>`;
return;
}
// ── SOCIAL — karty profilowe z linkami ──
if (currentFilter === 'social') {
container.innerHTML = `
<div class="section-label">📣 Profile polityków — X/Twitter i inne</div>
<div class="memes-grid">
${TWITTER_EMBEDS.map(t => `
<a class="meme-card" href="https://x.com/${escHtml(t.handle)}" target="_blank" rel="noopener">
<div class="meme-photo-wrap">
<img src="img/${escHtml(t.img)}" alt="${escHtml(t.name)}"
onerror="this.onerror=null;this.parentElement.style.background='var(--border)'">
<span class="meme-platform-badge">X / Twitter</span>
</div>
<div class="meme-body">
<div class="meme-author">
<img class="meme-author-avatar" src="img/${escHtml(t.img)}"
onerror="this.onerror=null;this.style.display='none'">
<div>
<div class="meme-author-name">${escHtml(t.name)}</div>
<div class="meme-author-handle">@${escHtml(t.handle)}</div>
</div>
</div>
<div class="meme-caption">${escHtml(t.desc)}</div>
<div class="meme-date" style="color:var(--accent)">↗ Przejdź do profilu →</div>
</div>
</a>`).join('')}
</div>`;
return;
}
// ── PiS TREE ──
if (currentFilter === 'pis') {
container.innerHTML = `
<div class="section-label">🦅 Prawo i Sprawiedliwość — hierarchia partii</div>
<div class="party-tree">${renderTree(PIS_TREE, 'pis-card', 'merit')}</div>`;
return;
}
// ── KOALICJA TREE ──
if (currentFilter === 'ko') {
container.innerHTML = `
<div class="section-label">🟡 Koalicja Rządząca — politycy i ich porażki</div>
<div class="party-tree">${renderTree(KOALICJA_TREE, 'ko-card', 'fail')}</div>`;
return;
}
// ── KKP TREE ──
if (currentFilter === 'kkp') {
container.innerHTML = `
<div class="section-label">⚡ Konfederacja Korony Polskiej — deficyty intelektualne</div>
<div style="font-size:0.72rem;color:#f87171;background:rgba(127,0,0,0.15);border:1px solid #7c0000;border-radius:8px;padding:8px 14px;margin-bottom:16px;max-width:900px">
️ Sekcja satyryczna — opisy mają charakter publicystyczny i ironiczny. Dane biograficzne są prawdziwe.
</div>
<div class="party-tree">${renderTree(KKP_TREE, 'kkp-card', 'fail')}</div>`;
return;
}
// ── KONFEDERACJA TREE ──
if (currentFilter === 'konf') {
container.innerHTML = `
<div class="section-label">🗽 Konfederacja Wolność i Niepodległość — osiągnięcia i kwalifikacje</div>
<div class="party-tree">${renderTree(KONFEDERACJA_TREE, 'konf-card', 'merit')}</div>`;
return;
}
// ── OPOZYCJA ──
if (currentFilter === 'opozycja') {
const opp = allArticles.filter(a => a.sourceId === 'opozycja');
opp.sort((a,b) => b.pubDate - a.pubDate);
container.innerHTML = `
<div class="section-label">💀 TVN24 💀 · TVP · Gazeta Wyborcza · Propagandowe media opozycji</div>
${opp.length === 0
? '<div class="spinner"><div class="spin"></div>Ładowanie mediów opozycji...</div>'
: `<div class="articles-grid">${opp.slice(0,40).map(a => articleCard(a, true)).join('')}</div>`
}`;
return;
}
// ── POSORTUJ ──
let filtered = currentFilter === 'all'
? allArticles.filter(a => a.sourceId !== 'opozycja')
: allArticles.filter(a => a.sourceId === currentFilter);
filtered.sort((a, b) => b.pubDate - a.pubDate);
if (filtered.length === 0) {
container.innerHTML = '<div class="empty">Ładowanie artykułów...</div>';
return;
}
// ── PRZEKAZ DNIA ──
if (currentFilter === 'all') {
container.innerHTML = renderTuskPortrait();
setTimeout(initTuskMap, 50);
return;
}
container.innerHTML = `
<div class="articles-grid">${filtered.slice(0,40).map(a => articleCard(a)).join('')}</div>`;
}
function articleCard(a, rainbow = false) {
const ago = timeAgo(a.pubDate);
const img = a.thumbnail
? `<img class="card-img" src="${escHtml(a.thumbnail)}" alt="" loading="lazy" onerror="this.onerror=null;this.parentElement.style.display='none'">`
: `<div class="card-img-placeholder">${a.sourceIcon}</div>`;
return `
<a class="card${rainbow ? ' rainbow-bg' : ''}" href="${escHtml(a.link)}" target="_blank" rel="noopener noreferrer">
${img}
<div class="card-body">
<span class="card-source ${a.cssClass}">${a.sourceIcon} ${escHtml(a.oppSource || a.sourceName)}</span>
<div class="card-title">${escHtml(a.title)}</div>
<div class="card-summary">${escHtml(a.summary)}</div>
<div class="card-footer">
<span>${ago}</span>
<span>↗ Czytaj</span>
</div>
</div>
</a>`;
}
// ══════════════════════════════════════════════
// PARTY TREE RENDERER
// ══════════════════════════════════════════════
function bioEmoji(node) {
const p = [];
if (node.married === true) p.push('<span>💍</span>');
if (typeof node.children === 'number' && node.children > 0) {
const ico = node.children <= 4 ? '👶'.repeat(node.children) : `👶×${node.children}`;
p.push(`<span>${ico}</span>`);
}
if (node.religious === true) p.push('<span>✝</span>');
return p.length ? `<div class="tree-bio">${p.join('')}</div>` : '';
}
function renderTree(root, cardClass, meritKey) {
const textClass = meritKey === 'merit' ? 'tree-merit' : 'tree-fail';
const textIcon = meritKey === 'merit' ? '✅' : '❌';
const avatarHtml = (node) => node.img
? `<img class="tree-avatar" src="${escHtml(node.img)}" alt="${escHtml(node.name)}"
onerror="this.onerror=null;this.style.display='none';this.nextElementSibling.style.display='flex'">`
: '';
const initialsHtml = (node) =>
`<div class="tree-avatar initials" style="background:${node.bg||'#374151'};display:${node.img?'none':'flex'}">${escHtml(node.initials||node.name.split(' ').map(w=>w[0]).join('').slice(0,2))}</div>`;
const nodeHtml = (node, isRoot) => `
<div class="tree-card ${isRoot?'root-card':''} ${cardClass}">
${avatarHtml(node)}${initialsHtml(node)}
<div class="tree-info">
<div class="tree-name">${escHtml(node.name)}</div>
<div class="tree-role">${escHtml(node.role)}</div>
${bioEmoji(node)}
<div class="${textClass}">${textIcon} ${escHtml(node[meritKey]||'')}</div>
</div>
</div>`;
// Root node
let html = `<div class="tree-root">
<div class="tree-node">${nodeHtml(root, true)}`;
// Legacy: flat children list
if (root.children && root.children.length) {
html += `<div class="tree-line-down"></div>
<div class="tree-children">
${root.children.map(c=>`<div class="tree-child-wrap">${nodeHtml(c,false)}</div>`).join('')}
</div>`;
}
// New: sections with labelled groups
if (root.sections && root.sections.length) {
html += `<div class="tree-line-down"></div>`;
root.sections.forEach(sec => {
html += `
<div class="tree-section">
<div class="tree-section-title">${escHtml(sec.label)}</div>
<div class="tree-section-grid">
${sec.members.map(m => nodeHtml(m, false)).join('')}
</div>
</div>`;
});
}
html += `</div></div>`;
return html;
}
function memeCard(m) {
return `
<a class="meme-card" href="${escHtml(m.url)}" target="_blank" rel="noopener noreferrer">
<div class="meme-photo-wrap">
<img src="${escHtml(m.photo)}" alt="${escHtml(m.name)}" loading="lazy"
onerror="this.onerror=null;this.parentElement.style.background='var(--border)';this.style.display='none'">
<span class="meme-platform-badge">${escHtml(m.platform)}</span>
<span class="meme-likes">♥ ${escHtml(m.likes)}</span>
</div>
<div class="meme-body">
<div class="meme-author">
<img class="meme-author-avatar" src="${escHtml(m.avatar)}" alt=""
onerror="this.onerror=null;this.style.display='none'">
<div>
<div class="meme-author-name">${escHtml(m.name)}</div>
<div class="meme-author-handle">${escHtml(m.handle)}</div>
</div>
</div>
<div class="meme-caption">${escHtml(m.caption)}</div>
<div class="meme-date">${escHtml(m.date)}</div>
</div>
</a>`;
}
// ══════════════════════════════════════════════
// STATS
// ══════════════════════════════════════════════
function updateStats() {
const today = new Date();
today.setHours(0, 0, 0, 0);
const todayCount = allArticles.filter(a => a.pubDate >= today).length;
const elapsedSec = Math.round((Date.now() - loadStart) / 1000);
const elapsedMin = Math.floor(elapsedSec / 60);
const elapsedDisp = elapsedSec < 60 ? '<1' : elapsedMin;
const okSources = SOURCES.filter(s => {
const dot = document.getElementById(s.dotId);
return dot && dot.classList.contains('dot-ok');
}).length;
const setTxt = (id, v) => { const el = document.getElementById(id); if (el) el.textContent = v; };
setTxt('stat-total', allArticles.length);
setTxt('stat-sources', okSources + '/' + SOURCES.length);
setTxt('stat-today', todayCount);
setTxt('stat-last', elapsedDisp);
}
// ══════════════════════════════════════════════
// POLITICIAN MENTION COUNTS
// ══════════════════════════════════════════════
const POLITICIAN_KEYWORDS = {
'nawrocki': ['nawrocki'],
'czarnek': ['czarnek', 'przemysław czarnek'],
'trump': ['trump'],
'kaczynski': ['kaczyński', 'kaczynski'],
'blaszczak': ['błaszczak', 'blaszczak'],
'ziobro': ['ziobro'],
};
function updatePoliticianCounts() {
const corpus = allArticles.map(a => (a.title + ' ' + a.summary).toLowerCase()).join(' ');
Object.entries(POLITICIAN_KEYWORDS).forEach(([id, keywords]) => {
const count = keywords.reduce((acc, kw) => {
const re = new RegExp(kw, 'gi');
return acc + (corpus.match(re) || []).length;
}, 0);
const el = document.getElementById('cnt-' + id);
if (el) el.textContent = count > 0
? `${count} wzmian${count === 1 ? 'ka' : count < 5 ? 'ki' : 'ek'} dzisiaj`
: 'brak wzmianek';
});
}
// ══════════════════════════════════════════════
// AUTO TOPIC EXTRACTION (simple word freq)
// ══════════════════════════════════════════════
const STOP_WORDS = new Set(['jest','się','nie','że','i','w','na','z','do','to','jak','po','a','co','dla','przez','o','czy','tak','ale','już','też','być','go','jego','jej','ich','tym','które','która','który','więcej','może','oraz','jako','będzie','roku','lat','jeszcze','właśnie','tylko','bez','pan','pani']);
function updateTopics() {
const words = allArticles
.flatMap(a => (a.title + ' ' + a.summary).toLowerCase().split(/\W+/))
.filter(w => w.length > 4 && !STOP_WORDS.has(w));
const freq = {};
words.forEach(w => { freq[w] = (freq[w] || 0) + 1; });
const top = Object.entries(freq)
.sort((a, b) => b[1] - a[1])
.slice(0, 16)
.map(([w]) => w);
if (top.length === 0) return;
const tc = document.getElementById('topics-container');
if (tc) tc.innerHTML = top.map(t => `<span class="topic-pill">${escHtml(t)}</span>`).join('');
}
// ══════════════════════════════════════════════
// WIELCY POLACY
// ══════════════════════════════════════════════
const WIELCY_POLACY = [
// ── LATA 20. ──
{ rok:1923, kat:'Nauka', icon:'🔬', name:'Stefan Banach',
ach:'Twórca analizy funkcjonalnej — jeden z najwybitniejszych matematyków XX wieku',
desc:'Profesor Uniwersytetu Lwowskiego. Twórca analizy funkcjonalnej, przestrzeni Banacha i teorii miary. Jego "Teoria operacji liniowych" (1932) jest kamieniem milowym matematyki. Współtwórca słynnej Lwowskiej Szkoły Matematycznej.' },
{ rok:1924, kat:'Nobel', icon:'📚', name:'Władysław Reymont',
ach:'Nagroda Nobla w dziedzinie literatury — "Chłopi"',
desc:'Wyróżniony za epopejową powieść "Chłopi" opisującą życie polskiej wsi. Przetłumaczona na ponad 30 języków, uznana za arcydzieło literatury europejskiej. Reymont był pierwszym Polakiem z Nagrodą Nobla w literaturze.' },
{ rok:1928, kat:'Sport', icon:'🥇', name:'Halina Konopacka',
ach:'Złoty medal olimpijski — rzut dyskiem, Amsterdam 1928',
desc:'Pierwsza polska złota medalistka olimpijska w historii. Na igrzyskach w Amsterdamie rzuciła dyskiem 39,62 m, bijąc rekord świata. Była też poetką, malarką i ikoną sportu dwudziestolecia międzywojennego.' },
{ rok:1932, kat:'Sport', icon:'🥇', name:'Janusz Kusociński',
ach:'Złoty medal olimpijski — bieg na 10 000 m, Los Angeles 1932',
desc:'Legendarny biegacz i olimpijczyk. Na igrzyskach w Los Angeles zwyciężył w biegu na 10 000 metrów. Zamordowany przez Niemców w 1940 r. w Palmirach — bohater sportu i patriota.' },
{ rok:1932, kat:'Nauka', icon:'🧩', name:'Marian Rejewski, Jerzy Różycki, Henryk Zygalski',
ach:'Złamanie kodu Enigmy — przełom w historii II wojny światowej',
desc:'Trzej polscy matematycy z Biura Szyfrów zrekonstruowali w 1932 r. wojskową maszynę szyfrującą Enigma. Ich praca umożliwiła Anglikom (Bletchley Park) odczytywanie niemieckich depesz przez całą wojnę. Historycy szacują, że skróciło to wojnę o 24 lata.' },
// ── LATA 40. ──
{ rok:1943, kat:'Historia', icon:'✊', name:'Jan Karski',
ach:'Raport o Holokauście — misja, która mogła uratować miliony',
desc:'Oficer AK, który jako pierwszy naocznie doniósł Zachodowi o systematycznej zagładzie Żydów. Raportował osobiście Rooseveltowi i Churchillowi. Świat nie zareagował — mimo to Karski nie zrezygnował z misji prawdy. Odznaczony Orderem Orła Białego.' },
{ rok:1944, kat:'Historia', icon:'🦅', name:'Witold Pilecki',
ach:'Dobrowolne więzienie w Auschwitz — by świat poznał prawdę',
desc:'Rotmistrz Wojska Polskiego, który dobrowolnie dał się aresztować i trafił do Auschwitz, skąd słał raporty o zbrodniach nazistowskich. Zorganizował tam konspirację wojskową. Po wojnie zamordowany przez komunistów. Symbol niezłomności i honoru.' },
// ── LATA 5060. ──
{ rok:1960, kat:'Sport', icon:'🥇', name:'Józef Szmidt',
ach:'Złoto olimpijskie i rekord świata w trójskoku — Rzym 1960',
desc:'Na igrzyskach w Rzymie Szmidt skoczył 17.03 m, bijąc rekord świata i zdobywając złoto. Pierwszy Polak z rekordem świata w lekkoatletyce. Obronił tytuł na IO w Tokio 1964.' },
{ rok:1961, kat:'Kultura', icon:'🚀', name:'Stanisław Lem',
ach:'"Solaris", "Cyberiada" — najczęściej tłumaczony polski pisarz science fiction na świecie',
desc:'Pisarz, filozof i futurolog z Lwowa. "Solaris" (1961) — jedna z najważniejszych powieści SF XX wieku, dwukrotnie sfilmowana (Tarkowski 1972, Soderbergh 2002). Dzieła przetłumaczone na 40+ języków, 30 milionów sprzedanych egzemplarzy. Autor "Cyberiady", "Bajek Robotów", "Dzienników gwiazdowych". Jego wizja AI, cyberprzestrzeni i kontaktu z obcymi wyprzedziła epokę o dekady.' },
{ rok:1964, kat:'Sport', icon:'🥇', name:'Irena Szewińska',
ach:'3 złota, 2 srebra, 2 brązy olimpijskie — królowa polskiej lekkoatletyki',
desc:'Najbardziej utytułowana polska lekkoatletka w historii. Startowała na 5 olimpiadach (19641980). Złota w sprincie (200 m 1968, 400 m 1976) i skoku w dal (1964). Na IO w Montrealu 1976 pobiła rekord świata na 400 m wynikiem 49,29 s.' },
// ── LATA 70. ──
{ rok:1974, kat:'Sport', icon:'⚽', name:'Grzegorz Lato i reprezentacja Polski',
ach:'MŚ Niemcy 1974 — 3. miejsce, Lato królem strzelców (7 goli)',
desc:'Polska reprezentacja pod wodzą Kazimierza Górskiego osiągnęła 3. miejsce na Mundialu w Niemczech. Grzegorz Lato strzelił 7 goli i został królem strzelców. W składzie: Deyna, Szarmach, Gadocha — drużyna uznawana za najlepszą w historii polskiej piłki.' },
{ rok:1976, kat:'Sport', icon:'🥇', name:'Wojciech Fortuna',
ach:'Złoty medal olimpijski — skoki narciarskie, Innsbruck 1976',
desc:'Na igrzyskach zimowych 1976 Fortuna oddał skoki 97.5 i 87.5 m zdobywając złoto. Pierwszy Polak z olimpijskim złotem w skokach narciarskich. Jego triumf otworzył Polsce drzwi do narciarskiej legendy.' },
{ rok:1978, kat:'Historia', icon:'✝️', name:'Jan Paweł II — Karol Wojtyła',
ach:'Pierwszy Polak papieżem — pontyfikat, który zmienił świat i obalił komunizm',
desc:'16 października 1978 r. kardynał Karol Wojtyła z Wadowic został wybrany na papieża jako Jan Paweł II. Pierwszy Słowianin i nieitalijski papież od 455 lat. Pontyfikat trwał 26 lat. Słowa "Niech zstąpi Duch Twój i odnowi oblicze ziemi — tej ziemi!" (Warszawa, 1979) stały się iskrą Solidarności. Kluczowa rola w upadku komunizmu w Europie. Beatyfikowany 2011, kanonizowany 2014.' },
// ── LATA 80. ──
{ rok:1980, kat:'Sport', icon:'🥇', name:'Władysław Kozakiewicz',
ach:'Złoto olimpijskie i rekord świata w skoku o tyczce — Moskwa 1980',
desc:'Na IO w Moskwie Kozakiewicz przeskoczył 5.78 m bijąc rekord świata. Zdobył złoto, a publiczności sowieckiej zademonstrował słynny "gest Kozakiewicza" — symbol protestu wolnego Polaka na sowieckiej ziemi. Jeden z najbardziej ikonicznych momentów polskiego sportu.' },
{ rok:1980, kat:'Sport', icon:'🥇', name:'Bronisław Malinowski',
ach:'Złoto olimpijskie 3000 m z przeszkodami — Moskwa 1980',
desc:'Biegacz z Grudziądza, wieloletni pretendent do medalu olimpijskiego. W Moskwie 1980 zrealizował olimpijskie marzenie — wygrał bieg na 3000 m z przeszkodami. Wzór wytrwałości i sportowego charakteru.' },
{ rok:1980, kat:'Historia', icon:'✊', name:'NSZZ Solidarność',
ach:'Związek Zawodowy Solidarność — 10 milionów członków, upadek komunizmu',
desc:'Powstały w sierpniu 1980 r. niezależny związek zawodowy z Lechem Wałęsą na czele. 10 milionów członków. Pierwsza legalna opozycja w bloku wschodnim. Podwalina pod obalenie komunizmu w Polsce i całej Europie. Symbol walki o wolność i godność człowieka.' },
{ rok:1980, kat:'Nobel', icon:'📚', name:'Czesław Miłosz',
ach:'Nagroda Nobla w dziedzinie literatury — "wizja człowieka w obliczu sprzeczności historii"',
desc:'Poeta i prozaik urodzony na Litwie, jeden z największych polskich intelektualistów XX w. "Zniewolony umysł" (1953) — klasyczna analiza totalitaryzmu i intelektualnej kolaboracji. Zbiegł na Zachód w 1951 r., wykładał na UC Berkeley. Nobel 1980 za "twórczość ukazującą człowieka w obliczu gwałtownych sprzeczności historycznych". Po 1989 wrócił do Polski.' },
{ rok:1982, kat:'Sport', icon:'⚽', name:'Zbigniew Boniek i reprezentacja Polski',
ach:'MŚ Hiszpania 1982 — 3. miejsce, Boniek — gwiazda Mundialu',
desc:'Polska po raz drugi z rzędu zajęła 3. miejsce na Mistrzostwach Świata. Zbigniew Boniek zachwycił świat — trafił do Juventusu Turyn. Platynowe lata polskiej piłki nożnej.' },
{ rok:1983, kat:'Nobel', icon:'🕊️', name:'Lech Wałęsa',
ach:'Nagroda Nobla w dziedzinie pokoju — Solidarność i walka o wolność',
desc:'Przywódca NSZZ Solidarność i jeden z architektów pokojowego obalenia komunizmu w Polsce. Nobla otrzymał za przewodzenie ruchowi, który zmienił oblicze Europy. W 1990 r. wybrany na Prezydenta RP.' },
{ rok:1986, kat:'Sport', icon:'⛰️', name:'Wanda Rutkiewicz',
ach:'Pierwsza kobieta na K2 (1986) i Everescie z Europy (1978) — królowa himalaizmu',
desc:'Największa polska himalaistka w historii. Pierwsza Europejka na szczycie Everestu (1978). W 1986 r. — pierwsza kobieta na K2, najtrudniejszej ośmiotysięczniku świata. Zdobyła 8 z 14 ośmiotysięczników. Zaginęła podczas wejścia na Kanczendzongę w 1992 r. Legenda, która sięgała wyżej niż ktokolwiek śmiał marzyć.' },
{ rok:1987, kat:'Sport', icon:'🏔️', name:'Jerzy Kukuczka',
ach:'Drugi człowiek w historii ze wszystkimi 14 ośmiotysięcznikami — w rekordowym tempie',
desc:'Górnik z Zabrza, który zdobił najwyższe szczyty ziemi w niebywałym stylu. W 1987 r. — jako drugi po Messnerze — ukończył Koronę Himalajów i Karakorum (wszystkie 14 ośmiotysięczników) w zaledwie 7 lat i 11 miesięcy. Większość zdobywał nowymi drogami, zimą lub solo. Zginął w 1989 r. na Lhotse — jedna z najpiękniejszych kart polskiego alpinizmu.' },
{ rok:1988, kat:'Kultura', icon:'🎬', name:'Krzysztof Kieślowski',
ach:'"Dekalog" i "Trzy Kolory" — ikona europejskiego kina artystycznego',
desc:'Reżyser z Warszawy, który wyniósł polskie kino na szczyt świata. "Dekalog" (1988) — 10 filmów opartych na przykazaniach, uznanych za jedno z arcydzieł telewizji wszech czasów. Trylogia "Trzy Kolory" (Niebieski/Biały/Czerwony, 19931994) — Złoty Lew w Wenecji, Srebrny Niedźwiedź w Berlinie, nominacja do Oscara za reżyserię. Symbol polskiej myśli filmowej na świecie.' },
// ── LATA 90. ──
{ rok:1994, kat:'Sport', icon:'🥊', name:'Dariusz Michalczewski "Tiger"',
ach:'Mistrz świata w boksie WBO/WBA/IBF — 48 walk, 47 zwycięstw, 1 remis',
desc:'Gdańszczanin, który zdominował półciężką wagę w boksie zawodowym przez dekadę. Pas WBO od 1994 r., następnie zebrał pasy WBA i IBF. Łączny bilans 48-0-1 (33 KO) — jeden z najlepszych rekordów w historii polskiego boksu. Przeprowadził się do Hamburga, ale zawsze mówił: "Jestem Polakiem". Ikona polskiego boksu lat 90.' },
{ rok:1995, kat:'Nobel', icon:'☮️', name:'Józef Rotblat',
ach:'Nagroda Nobla w dziedzinie pokoju — walka z bronią nuklearną',
desc:'Fizyk urodzony w Warszawie. Jedyny naukowiec, który opuścił Projekt Manhattan z powodów etycznych. Współzałożyciel ruchu Pugwash. Nobel przyznany za walkę na rzecz świata wolnego od broni atomowej. Wzór odwagi moralnej.' },
{ rok:1996, kat:'Nobel', icon:'📚', name:'Wisława Szymborska',
ach:'Nagroda Nobla w dziedzinie literatury — "poezja precyzji i ironii"',
desc:'Jeden z najwybitniejszych polskich poetów XX wieku. Nobel za "poezję, która poprzez ironię, precyzję i głębię filozoficzną odsłania fundamenty ludzkiego losu". Autorka tomów "Chwila", "Widok z ziarnkiem piasku", "Dwukropek". Napisała ponad 350 wierszy.' },
{ rok:1996, kat:'Sport', icon:'🥇', name:'Robert Korzeniowski',
ach:'4 złota olimpijskie w chodzie sportowym (19962004)',
desc:'Najwybitniejszy chodziarz w historii igrzysk olimpijskich. Złoto na dystansie 50 km (Atlanta 1996), dwa złota w Sydney 2000 (20 i 50 km), złoto w Atenach 2004. Czterokrotny mistrz olimpijski — rekord, którego nikt nie pobił.' },
// ── LATA 2000. ──
{ rok:2001, kat:'Sport', icon:'⛷️', name:'Adam Małysz',
ach:'4 Puchary Świata w skokach narciarskich (2001, 2002, 2003, 2007)',
desc:'Dekarczyk z Wisły, który podbił świat skoków narciarskich. Cztery razy wygrał klasyfikację generalną PŚ, zdobył srebrny medal olimpijski (Salt Lake City 2002), dwa brązowe i tytuły mistrzowskie. Wywołał "Małyszomanię" — fenomen kibicowski nieprzyrównany w historii polskiego sportu.' },
{ rok:2002, kat:'Sport', icon:'💪', name:'Mariusz Pudzianowski',
ach:'5-krotny Mistrz Świata Najsilniejszego Człowieka (2002, 03, 05, 07, 08)',
desc:'Dominator dyscypliny strongman nieprzyrównany w historii. Pięć tytułów World\'s Strongest Man — więcej niż ktokolwiek inny. Wzrost 182 cm, 140 kg czystej siły. Po zakończeniu kariery strongmana przeszedł do MMA — walczył na najwyższym poziomie. Ikona polskiego sportu.' },
{ rok:2004, kat:'Sport', icon:'🥇', name:'Otylia Jędrzejczak',
ach:'Złoto olimpijskie 200 m motylkowy — Ateny 2004',
desc:'Na igrzyskach w Atenach Jędrzejczak zdobyła złoto (200 m mot.), srebro (400 m zm.) i brąz (100 m mot.) — trzy medale w jednych igrzyskach. Dominowała w pływaniu motylkowym przez całą dekadę. Zdobyła wielokrotne tytuły mistrzowskie Europy i świata.' },
{ rok:2007, kat:'Kultura', icon:'🎬', name:'Andrzej Wajda',
ach:'Honorowy Oscar za całokształt twórczości filmowej',
desc:'Jeden z najwybitniejszych reżyserów europejskich. Trylogia wojenna: "Pokolenie", "Kanał", "Popiół i diament". "Człowiek z żelaza" — Palme d\'Or w Cannes. Honorowy Oscar 2000 i nominacja do Oscara za "Katyń" 2007. Symbol polskiego kina i pamięci historycznej.' },
{ rok:2008, kat:'Sport', icon:'🏎️', name:'Robert Kubica',
ach:'Zwycięstwo Grand Prix Kanady F1 — jedyny Polak z wygraną w F1',
desc:'7 czerwca 2008 r. w Montrealu Robert Kubica wygrał wyścig Formuły 1. Jedyny Polak i jeden z niewielu Słowian z triumfem w Grand Prix. Prowadził w BMW Sauber. Jego karierę przerwał ciężki wypadek rajdowy 2011, z którego wrócił i ponownie ścigał się w F1.' },
// ── LATA 2010. ──
{ rok:2012, kat:'Sport', icon:'🥇', name:'Anita Włodarczyk',
ach:'3 złota olimpijskie w rzucie młotem (2012, 2016, 2021) + 8 rekordów świata',
desc:'Największa polska sportsmenka XXI wieku. Trzykrotna mistrzyni olimpijska — Londyn 2012, Rio 2016, Tokio 2021. Wielokrotna mistrzyni świata i Europy. Jej rekord świata to 82.98 m (Rio 2016) — wynik niepobity od lat. Osiem razy biła rekord świata.' },
{ rok:2014, kat:'Sport', icon:'🏐', name:'Reprezentacja Polski w siatkówce mężczyzn',
ach:'Mistrzowie Świata 2014 i 2018 — złoto na dwóch Mundialach z rzędu',
desc:'Pierwsza i jedyna drużyna, która wygrała dwa kolejne mistrzostwa świata (2014 Polska, 2018 Japonia). Pod wodzą Andrei Anastasiego i Vitala Heynena Polska zdominowała światową siatkówkę. Gwiazdy: Kurek, Zatorski, Kochanowski, Bieniek.' },
{ rok:2014, kat:'Sport', icon:'🚴', name:'Michał Kwiatkowski',
ach:'Mistrz Świata w kolarstwie szosowym — Ponferrada 2014',
desc:'Pierwszy Polak z tęczową koszulką mistrza świata w kolarstwie. Wygrał finisz w Ponferradzie (Hiszpania) w 2014 r. Zdobywca klasycznych wyścigów: MediolanSan Remo, Strade Bianche. Kolarz klasy absolutnie światowej.' },
{ rok:2014, kat:'Sport', icon:'⛷️', name:'Kamil Stoch',
ach:'3 złota olimpijskie w skokach (Soczi 2014, PyeongChang 2018) + Grand Slam PŚ',
desc:'Kontynuator tradycji Małysza i nowa legenda polskich skoków. Dwa złota w Soczi 2014 (skocznia normalna i duża), złoto w PyeongChang 2018. W sezonie 2017/18 jako pierwszy Polak wygrał Grand Slam (Turniej Czterech Skoczni + Willingen). Trzykrotny mistrz świata.' },
{ rok:2015, kat:'Sport', icon:'🥊', name:'Tomasz Adamek',
ach:'Mistrz świata w boksie w dwóch kategoriach wagowych',
desc:'Krakowski "Górnik z Gilowic". Mistrz IBF w wadze półciężkiej (2005), WBC light heavyweight i cruiserweight. Stoczył ponad 50 walk zawodowych. Walczył z Vitali Kliczką i Brizuelą — ikona polskiego boksu zawodowego.' },
{ rok:2017, kat:'Sport', icon:'🔨', name:'Paweł Fajdek',
ach:'5-krotny Mistrz Świata w rzucie młotem (2013, 15, 17, 19, 22)',
desc:'Dominująca siła w rzucie młotem przez dekadę. Pięć złotych medali mistrzostw świata — rekord w tej konkurencji. Wieloletni partner treningowy Anity Włodarczyk. Razem tworzą najsilniejszy duet w historii rzutów na świecie.' },
{ rok:2019, kat:'Nobel', icon:'📚', name:'Olga Tokarczuk',
ach:'Nagroda Nobla w dziedzinie literatury 2018 (przyznana 2019)',
desc:'Nobel za "wyobraźnię narracyjną, która z encyklopedyczną pasją reprezentuje przekraczanie granic". Autorka "Biegunów" (nagroda Bookera 2018), "Ksiąg Jakubowych", "Prowadź swój pług przez kości umarłych". Polska literatura znów na szczycie świata.' },
// ── LATA 2020. ──
{ rok:2020, kat:'Sport', icon:'🎾', name:'Iga Świątek',
ach:'4× French Open, 1× US Open, Numer 1 na świecie przez rekordowe 125 tygodni',
desc:'Fenomen polskiego i światowego tenisa. Pierwszy Polak/Polka z tytułem Wielkiego Szlema od 81 lat (Roland Garros 2020). Następnie: RG 2022, US Open 2022, RG 2023, RG 2024. Przez 125 nieprzerwanych tygodni numer 1 WTA — jeden z najdłuższych takich serii w historii. W wieku 23 lat ma 5 tytułów Wielkiego Szlema.' },
{ rok:2021, kat:'Sport', icon:'🥊', name:'Jan Błachowicz',
ach:'Mistrz Świata UFC w kategorii półciężkiej (20202021)',
desc:'Urodzony w Cieszynie zawodnik MMA. W 2020 r. wywalczył pas mistrza UFC w wadze półciężkiej, pokonując Dominicka Reyesa przez TKO. Obronił tytuł przed Gloveru Teixeirą. Pierwszy Polak-mistrz UFC. Karierę aktywnie kontynuuje.' },
{ rok:2021, kat:'Sport', icon:'🔨', name:'Wojciech Nowicki',
ach:'Złoty medal olimpijski w rzucie młotem — Tokio 2021',
desc:'Zawodnik z Białegostoku, triumfator rzutu młotem na igrzyskach w Tokio. Wynikiem 82.52 m zdobył złoto olimpijskie. Partner treningowy Pawła Fajdka — razem tworzą najsilniejszy duet rzutniczy w historii polskiej i światowej lekkiej atletyki. Wielokrotny mistrz Europy i medalista mistrzostw świata.' },
{ rok:2021, kat:'Sport', icon:'🚶', name:'Dawid Tomala',
ach:'Złoty medal olimpijski w chodzie na 50 km — Tokio 2021',
desc:'Chodziarz z Buska-Zdroju, który zaskoczył cały świat. Wygrał ostatnie olimpijskie chody na 50 km wynikiem 3:50:08, zdobywając złoto przed faworytami. Ta konkurencja nie wróci już na olimpiadę — Tomala będzie jej ostatnim złotym medalistą na zawsze. Godny następca Roberta Korzeniowskiego.' },
{ rok:2021, kat:'Sport', icon:'🏐', name:'Bartosz Kurek i reprezentacja Polski',
ach:'Liga Narodów 2021, srebrny medal IO Tokio 2021',
desc:'Polska siatkówka nie schodzi z podium. Na IO w Tokio 2021 srebrny medal. Trzykrotny zwycięzca Ligi Narodów. Bartosz Kurek wielokrotnie nagradzany MVP turniejów. Wilfredo Leon, Piotr Nowakowski, Marcin Janusz — superstar polskiej siatkówki.' },
{ rok:2022, kat:'Sport', icon:'⚽', name:'Robert Lewandowski',
ach:'Rekord Bundesligi — 41 goli w sezonie, 5× Piłkarz Roku FIFA The Best',
desc:'Jeden z najlepszych napastników w historii futbolu. Pięciokrotny laureat FIFA The Best. Rekord Bundesligi — 41 goli w sezonie 2020/21 (niedościgniony). Strzelec 100 goli dla reprezentacji Polski. Dwukrotnie nominowany do Złotej Piłki. Ambasador Polski na świecie.' },
{ rok:2022, kat:'Sport', icon:'🏃', name:'Natalia Kaczmarek',
ach:'Mistrzyni Europy 400 m (2022, 2024), srebro IO Paryż 2024 — nowa królowa sprintu',
desc:'Sprinterka z Kościana i nowa ikona polskiej lekkoatletyki. Złoto Mistrzostw Europy na 400 m — Monachium 2022, Rzym 2024. Brąz Mistrzostw Świata 2022 (Eugene) i 2023 (Budapeszt). Na IO w Paryżu 2024 srebro — pierwsza polska medalistka olimpijska w sprincie od Ireny Szewińskiej w 1976 r. Pokoleniowa zmiana w polskiej lekkiej atletyce.' },
{ rok:2023, kat:'Sport', icon:'🎾', name:'Hubert Hurkacz',
ach:'Mistrzostwa ATP — Miami Open 2021, Halle 2023, wiele tytułów, top 10 świata',
desc:'Drugi najlepszy polski tenisista w historii (po Fibaku). Wygrał prestiżowy turniej Masters w Miami (2021), pokonując Medvedeva i Verdasco. Finał Wimbledonu 2021 (półfinał). Zwycięzca turnieju Halle 2023. Regularnie w top-10 rankingu ATP.' },
{ rok:2024, kat:'Sport', icon:'🧗', name:'Aleksandra Mirosław',
ach:'Złoty medal olimpijski — wspinaczka na czas, Paryż 2024, rekord świata 6,06 s',
desc:'Królowa wspinaczki szybkościowej. Na IO w Paryżu 2024 zdobyła złoto olimpijskie w biegu na czas, bijąc rekord świata wynikiem 6,06 sekundy. Wielokrotna mistrzyni świata i Europy. Rekord świata trzyma od lat — rywale gonią ją, ona uciekała. Nowa legenda polskiego sportu, dyscypliny, w której Polska rządzi.' },
{ rok:2024, kat:'Sport', icon:'⛷️', name:'Piotr Żyła i Dawid Kubacki',
ach:'Wielokrotni zdobywcy Pucharu Świata i medali mistrzostw świata w skokach',
desc:'Polska triumfuje w skokach. Piotr Żyła — Mistrz Świata 2021 (Oberstdorf), wielokrotny medalista. Dawid Kubacki — złoto MŚ 2019 (lotów narciarskich), 3. miejsce Turnieju Czterech Skoczni 2019/20. Polska szkoła skoków — od Małysza przez Stocha, po Żyłę i Kubackiego — to 30 lat światowej dominacji.' },
{ rok:2024, kat:'Kultura', icon:'🎵', name:'Krzysztof Penderecki',
ach:'Jeden z najwybitniejszych kompozytorów XX i XXI wieku',
desc:'Światowej sławy kompozytor z Dębicy. "Tren ofiarom Hiroszimy" (1960) — przełom w muzyce awangardowej. "Pasja według św. Łukasza" wykonywana na całym świecie. Laureat Grammy, Grammophone Award i licznych nagród Fryderyka. Ikona polskiej muzyki poważnej.' },
];
let _wielcyKat = 'Wszyscy';
function renderWielcyPolacy() {
const container = document.getElementById('feed-container');
const kats = ['Wszyscy','Sport','Nobel','Nauka','Kultura','Historia'];
const katColors = {Sport:'#16a34a',Nobel:'#d97706',Nauka:'#1d4ed8',Kultura:'#7c3aed',Historia:'#ef4444'};
function build(kat) {
_wielcyKat = kat;
const data = kat === 'Wszyscy' ? WIELCY_POLACY : WIELCY_POLACY.filter(p => p.kat === kat);
// Group by decade
const decades = {};
data.forEach(p => {
const dec = Math.floor(p.rok / 10) * 10;
if (!decades[dec]) decades[dec] = [];
decades[dec].push(p);
});
const tlHtml = Object.entries(decades).sort(([a],[b]) => +a - +b).map(([dec, items]) => {
const cards = items.map(p => {
const col = katColors[p.kat] || '#4b5563';
const cls = p.kat.toLowerCase().replace(' ','');
return `<div class="wielcy-card ${p.kat}">
<div class="wielcy-card-icon" style="background:${col}18">
<span>${p.icon}</span>
<span class="wielcy-card-year">${p.rok}</span>
</div>
<div class="wielcy-card-body">
<div class="wielcy-card-name">${escHtml(p.name)}</div>
<div class="wielcy-card-achievement" style="color:${col}">${escHtml(p.ach)}</div>
<div class="wielcy-card-desc">${escHtml(p.desc)}</div>
<span class="wielcy-card-badge badge-${p.kat}">${p.kat}</span>
</div>
</div>`;
}).join('');
const decLabel = dec + 's' === '2020s' ? 'Lata 20202024 (aktualne)' : `Lata ${dec}.`;
return `<div class="wielcy-decade">🏅 ${decLabel}</div><div class="wielcy-grid">${cards}</div>`;
}).join('');
const filterBtns = kats.map(k =>
`<button class="wielcy-filter-btn${k===kat?' active':''}" data-kat="${k}" onclick="wielcyFilter('${k}')">${k}</button>`
).join('');
const sportCount = WIELCY_POLACY.filter(p=>p.kat==='Sport').length;
const nobelCount = WIELCY_POLACY.filter(p=>p.kat==='Nobel').length;
const naukaCount = WIELCY_POLACY.filter(p=>p.kat==='Nauka').length;
const kultCount = WIELCY_POLACY.filter(p=>p.kat==='Kultura').length;
const histCount = WIELCY_POLACY.filter(p=>p.kat==='Historia').length;
container.innerHTML = `
<div class="wielcy-page">
<div class="wielcy-hero">
<div class="wielcy-hero-title">🏆 Wielcy Polacy — 100 lat Chwały</div>
<div class="wielcy-hero-sub">Chronologiczny przegląd największych osiągnięć Polaków w sporcie, nauce, kulturze i historii — od 1923 do 2024 roku. Dorobek narodu, który mimo najtrudniejszych warunków wciąż sięgał po najwyższe laury.</div>
<div class="wielcy-stats">
<div class="wielcy-stat"><div class="n">${WIELCY_POLACY.length}</div><div class="l">Osiągnięć</div></div>
<div class="wielcy-stat"><div class="n">${sportCount}</div><div class="l">Sport</div></div>
<div class="wielcy-stat"><div class="n">${nobelCount}</div><div class="l">Nobliści</div></div>
<div class="wielcy-stat"><div class="n">${naukaCount}</div><div class="l">Nauka</div></div>
<div class="wielcy-stat"><div class="n">${kultCount + histCount}</div><div class="l">Kultura / Historia</div></div>
</div>
</div>
<div class="wielcy-filters">${filterBtns}</div>
<div class="wielcy-timeline">${tlHtml}</div>
</div>`;
}
build(_wielcyKat);
}
function wielcyFilter(kat) {
_wielcyKat = kat;
renderWielcyPolacy();
}
// ══════════════════════════════════════════════
// ŚW. JAN PAWEŁ II PAGE
// ══════════════════════════════════════════════
let _jp2Map = null;
const JP2_PILGRIMAGES = [
// ── POLSKA ──
{ lat:52.23, lng:21.01, type:'poland', year:1979, visit:1, city:'Warszawa',
title:'I pielgrzymka — Warszawa 1979',
desc:'Plac Zwycięstwa, 2 VI 1979. "Niech zstąpi Duch Twój i odnowi oblicze ziemi — tej ziemi!" Słowa, które wstrząsnęły Polską. 10 milionów rodaków wyszło na trasy przemarszu.', img:'img/jp2_1979_warszawa.jpg' },
{ lat:52.54, lng:17.60, type:'poland', year:1979, visit:1, city:'Gniezno',
title:'I pielgrzymka — Gniezno, kolebka Polski',
desc:'Modlitwa przy grobie św. Wojciecha. JP2: "Tu jestem u źródeł. Tu bije serce polskości." Gniezno jest kolebką chrześcijaństwa i państwowości polskiej.', img:'img/jp2_1979_gniezno.jpg' },
{ lat:50.81, lng:19.12, type:'poland', year:1979, visit:1, city:'Częstochowa',
title:'I pielgrzymka — Jasna Góra',
desc:'Koronacja Matki Bożej Częstochowskiej. JP2 oddaje Polskę Maryi. Msza dla ponad 1 miliona pielgrzymów.', img:'img/jp2_jasna_gora.jpg' },
{ lat:50.06, lng:19.94, type:'poland', year:1979, visit:1, city:'Kraków',
title:'I pielgrzymka — Kraków, miasto Karola Wojtyły',
desc:'Powrót do rodzinnego miasta. Msza na Błoniach krakowskich — 2 miliony wiernych. Ostatnie słowa: "Musicie być mocni, drodzy bracia i siostry!"', img:'img/jp2_1979_krakow.jpg' },
{ lat:50.03, lng:18.72, type:'poland', year:1979, visit:1, city:'Oświęcim-Brzezinka',
title:'I pielgrzymka — Oświęcim-Brzezinka',
desc:'Msza na terenie obozu KL Auschwitz-Birkenau. "Nie można przejść obojętnie obok tego miejsca — Golgoty naszych czasów." Modlitwa za ofiary Holokaustu.', img:'img/jp2_oswiecim.jpg' },
{ lat:52.23, lng:21.01, type:'poland', year:1983, visit:2, city:'Warszawa',
title:'II pielgrzymka — Polska pod stanem wojennym (1983)',
desc:'Polska przeżywa stan wojenny. JP2 przekazuje Polakom nadzieję. Spotkanie z gen. Jaruzelskim i — historyczne — z Lechem Wałęsą.', img:'img/jp2_1983.jpg' },
{ lat:52.40, lng:16.93, type:'poland', year:1983, visit:2, city:'Poznań',
title:'II pielgrzymka — Poznań',
desc:'Msza przed poznańską farą dla ponad miliona wiernych. "Prawa człowieka nie mogą być łamane przez żaden system."', img:'img/jp2_1983_poznan.jpg' },
{ lat:51.11, lng:17.04, type:'poland', year:1983, visit:2, city:'Wrocław',
title:'II pielgrzymka — Wrocław',
desc:'Ogromna msza na stadionie olimpijskim. JP2 mówi o godności pracy i o Solidarności jako prawie narodu.', img:'img/jp2_1983_wroclaw.jpg' },
{ lat:54.35, lng:18.65, type:'poland', year:1987, visit:3, city:'Gdańsk',
title:'III pielgrzymka — Gdańsk, Westerplatte (1987)',
desc:'"Każdy z was, młody człowieku, musi znaleźć swoje Westerplatte. Musi znaleźć jakiś porządek wartości i prawd, których potem bronić, za których cenę nie schyla głowy." Przemówienie do Polaków w kolebce Solidarności.', img:'img/jp2_1987_gdansk.jpg' },
{ lat:51.77, lng:19.45, type:'poland', year:1987, visit:3, city:'Łódź',
title:'III pielgrzymka — Łódź',
desc:'Msza dla robotników łódzkiego przemysłu. JP2 broni praw pracowniczych i godności człowieka pracy.', img:'img/jp2_1987_lodz.jpg' },
{ lat:54.52, lng:18.54, type:'poland', year:1987, visit:3, city:'Gdynia',
title:'III pielgrzymka — Gdynia',
desc:'Beatyfikacja bł. Michała Kozala — biskupa zamordowanego w Dachau. Hołd złożony ofiarom nazizmu.', img:'img/jp2_1987_gdynia.jpg' },
{ lat:53.13, lng:23.16, type:'poland', year:1991, visit:4, city:'Białystok',
title:'IV pielgrzymka — Pierwsza po upadku komunizmu (1991)',
desc:'Historyczna wizyta! Polska jest wolna! JP2 przybywa do wyzwolonej ojczyzny. "Ta wolność to wielki dar i wielkie zadanie." Dekalog dla wolnej Polski.', img:'img/jp2_1991.jpg' },
{ lat:54.16, lng:15.55, type:'poland', year:1991, visit:4, city:'Koszalin',
title:'IV pielgrzymka — Koszalin',
desc:'Msza na lotnisku. JP2 do młodych: "Polska, która nie zna wartości, nie obroni swojej wolności."', img:'img/jp2_1991_koszalin.jpg' },
{ lat:51.40, lng:21.15, type:'poland', year:1991, visit:4, city:'Radom',
title:'IV pielgrzymka — Radom',
desc:'Beatyfikacja bł. Jadwigi Borzęckiej i bł. Marii Teresy Ledóchowskiej.', img:'img/jp2_1991_radom.jpg' },
{ lat:51.11, lng:17.04, type:'poland', year:1997, visit:5, city:'Wrocław',
title:'V pielgrzymka — 46. Kongres Eucharystyczny, Wrocław (1997)',
desc:'Wielki Kongres Eucharystyczny. JP2 i milion wiernych. Słynne słowa o Europie chrześcijańskiej i roli Polski jako "przedmurza chrześcijaństwa".', img:'img/jp2_1997_wroclaw.jpg' },
{ lat:52.54, lng:17.60, type:'poland', year:1997, visit:5, city:'Gniezno',
title:'V pielgrzymka — Zjazd Gnieźnieński (1997)',
desc:'Szczyt prezydentów Europy Środkowej. "Europa potrzebuje Polski. Polska potrzebuje Europy." Wizja zjednoczonej, chrześcijańskiej Europy.', img:'img/jp2_1997_gniezno.jpg' },
{ lat:49.30, lng:19.95, type:'poland', year:1997, visit:5, city:'Zakopane',
title:'V pielgrzymka — Zakopane, ukochane Tatry',
desc:'JP2 w ukochanych Tatrach. Msza na Równi Krupowej. Wspomnienia górskich wędrówek. "Góry są moim skarbem od dzieciństwa."', img:'img/jp2_1997_zakopane.jpg' },
{ lat:50.06, lng:19.94, type:'poland', year:1997, visit:5, city:'Kraków',
title:'V pielgrzymka — Kraków, beatyfikacja Królowej Jadwigi',
desc:'Beatyfikacja Jadwigi Andegaweńskiej, Królowej Polski. Msza na Błoniach dla 1,5 miliona wiernych.', img:'img/jp2_1997_krakow.jpg' },
{ lat:54.35, lng:18.65, type:'poland', year:1999, visit:6, city:'Gdańsk',
title:'VI pielgrzymka — Gdańsk (1999)',
desc:'JP2 dziękuje Polsce za drogę ku wolności. "Solidarność zmieniła oblicze tej ziemi i oblicze Europy." Hołd dla ruchu Solidarności.', img:'img/jp2_1999_gdansk.jpg' },
{ lat:53.01, lng:18.60, type:'poland', year:1999, visit:6, city:'Toruń',
title:'VI pielgrzymka — Toruń, miasto Kopernika',
desc:'Msza na terenie pobliskiego lotniska. JP2 wspomina Mikołaja Kopernika — polskiego geniusza nauki.', img:'img/jp2_1999_torun.jpg' },
{ lat:50.06, lng:19.94, type:'poland', year:1999, visit:6, city:'Kraków',
title:'VI pielgrzymka — Kraków, konsekracja Łagiewnik',
desc:'Konsekracja Sanktuarium Bożego Miłosierdzia. "Jezus, ufam Tobie." JP2 zawierza cały świat Bożemu Miłosierdziu.', img:'img/jp2_1999_lagiewniki.jpg' },
{ lat:50.02, lng:19.93, type:'poland', year:2002, visit:7, city:'Kraków-Łagiewniki',
title:'VII i ostatnia pielgrzymka — Kraków 2002',
desc:'Ostatnia pielgrzymka JP2 do ojczyzny. Konsekracja Świątyni Bożego Miłosierdzia. "Ogień miłosierdzia niech ogarnie cały świat i niech wreszcie zawita tu czas miłosierdzia." Łzy i modlitwy milionów Polaków.', img:'img/jp2_2002_lagiewniki.jpg' },
// ── ŚWIAT ──
{ lat:19.43, lng:-99.13, type:'world', year:1979, visit:1, city:'Meksyk',
title:'Meksyk — Pierwsza zagraniczna pielgrzymka (styczeń 1979)',
desc:'Konferencja CELAM w Puebla. Witany przez miliony Meksykanów. JP2 broni doktryny Kościoła przeciwko teologii wyzwolenia. Inauguracja pontyfikatu na forum światowym.', img:'img/jp2_meksyk.jpg' },
{ lat:40.71, lng:-74.01, type:'world', year:1979, visit:1, city:'Nowy Jork / USA',
title:'USA — Październik 1979',
desc:'Msza na Washington Mall dla ponad miliona ludzi. Przemówienie w ONZ o prawach człowieka. Wizyty w Bostonie, Nowym Jorku, Filadelfii, Chicago i Des Moines.', img:'img/jp2_usa.jpg' },
{ lat:53.33, lng:-6.25, type:'world', year:1979, visit:1, city:'Dublin, Irlandia',
title:'Irlandia — Wrzesień 1979',
desc:'Msza w Phoenix Park dla 1,25 miliona wiernych — rekord Irlandii. Apel do IRA o złożenie broni: "Przemoc jest złem. Przemoc jest kłamstwem."', img:'img/jp2_irlandia.jpg' },
{ lat:-15.78, lng:-47.93, type:'world', year:1980, visit:1, city:'Brazylia',
title:'Brazylia — Lipiec 1980',
desc:'12-dniowa pielgrzymka przez największy kraj Ameryki Łacińskiej. Spotkania z ubogimi, chorymi i robotnikami. Obrona praw człowieka.', img:'img/jp2_brazylia.jpg' },
{ lat:38.70, lng:-8.82, type:'world', year:1982, visit:1, city:'Fatima, Portugalia',
title:'Fatima — 1982 (rok po zamachu)',
desc:'Modlitwa w Fatimie jako dziękczynienie za ocalenie. JP2 oddaje kulę wyciągniętą z jego ciała Matce Bożej. "Jedna ręka strzeliła, a inna prowadziła kulę." Zawierzenie Rosji i świata Niepokalanemu Sercu Maryi.', img:'img/jp2_fatima.jpg' },
{ lat:51.51, lng:-0.13, type:'world', year:1982, visit:1, city:'Londyn, Wielka Brytania',
title:'Wielka Brytania — 1982 (pierwsza wizyta w historii)',
desc:'Historyczna pierwsza wizyta papieża na Wyspach Brytyjskich. Msza w Wembley. Modlitwa ekumeniczna w Canterbury z arcybiskupem. Gest pojednania z anglikanami.', img:'img/jp2_uk.jpg' },
{ lat:-34.61, lng:-58.38, type:'world', year:1982, visit:1, city:'Argentyna',
title:'Argentyna — 1982 (w czasie wojny o Falklandy)',
desc:'Wizyta w czasie konfliktu z Wielką Brytanią. JP2 wzywa do pokoju po obu stronach — najpierw Argentyna, potem Wielka Brytania. Gest bezstronności i miłości bliźniego.', img:'img/jp2_argentyna.jpg' },
{ lat:37.57, lng:126.98, type:'world', year:1984, visit:1, city:'Seul, Korea Pd.',
title:'Korea Południowa — 1984',
desc:'Beatyfikacja 103 koreańskich męczenników. Msza w Seulu dla ponad miliona wiernych. JP2 czyni Koreę centrum chrześcijaństwa w Azji.', img:'img/jp2_korea.jpg' },
{ lat:14.72, lng:121.05, type:'world', year:1981, visit:1, city:'Manila, Filipiny',
title:'Filipiny — 1981',
desc:'Msza w Luneta Park dla 2 milionów wiernych — jeden z największych tłumów w historii pontyfikatu. JP2 broni praw człowieka wobec dyktatury Marcosa.', img:'img/jp2_filipiny.jpg' },
{ lat:28.61, lng:77.21, type:'world', year:1986, visit:1, city:'Delhi, Indie',
title:'Indie — 1986',
desc:'Spotkanie z Matką Teresą z Kalkuty. Dialog z hinduizmem, islamem, sikhizmem i buddyzmem. JP2 modli się w różnych świątyniach — gest dialogu międzyreligijnego.', img:'img/jp2_indie.jpg' },
{ lat:23.13, lng:-82.38, type:'world', year:1998, visit:1, city:'Hawana, Kuba',
title:'Kuba — Styczeń 1998 (historyczna wizyta)',
desc:'"Niech świat otworzy się na Kubę, a Kuba niech otworzy się na świat." Fidel Castro słucha stojąc. JP2 wyprasza wolność dla więźniów politycznych i przywraca Boże Narodzenie jako dzień wolny.', img:'img/jp2_kuba.jpg' },
{ lat:31.78, lng:35.22, type:'world', year:2000, visit:1, city:'Jerozolima, Izrael',
title:'Ziemia Święta — Marzec 2000 (Wielki Jubileusz)',
desc:'Pielgrzymka śladami Jezusa. Modlitwa przy Ścianie Płaczu — JP2 wkłada kartkę z prośbą o przebaczenie za grzechy wobec Żydów. "Szoa jest niezmywalną plamą na historii tego stulecia." Historyczne pojednanie.', img:'img/jp2_jerozolima.jpg' },
{ lat:37.97, lng:23.73, type:'world', year:2001, visit:1, city:'Ateny, Grecja',
title:'Grecja — 2001',
desc:'Przeprosiny za IV krucjatę i złupienie Konstantynopola w 1204 r. "Kościół katolicki z żalem przeprasza za grzechy swoich dzieci wobec braci prawosławnych." Historyczny gest wobec chrześcijaństwa wschodniego.', img:'img/jp2_grecja.jpg' },
{ lat:33.51, lng:36.29, type:'world', year:2001, visit:1, city:'Damaszek, Syria',
title:'Syria — 2001 (pierwszy papież w meczecie)',
desc:'Modlitwa w Wielkim Meczecie Umajjadów — pierwszy papież w historii wchodzący do meczetu. Hołd złożony przy relikwiach św. Jana Chrzciciela. Rewolucyjny gest dialogu z islamem.', img:'img/jp2_syria.jpg' },
{ lat:-1.28, lng:36.82, type:'world', year:1980, visit:1, city:'Nairobi, Kenia',
title:'Afryka — 1980 (6 krajów)',
desc:'Historyczna pierwsza wielka pielgrzymka po Afryce. Sześć krajów w 11 dni: Zair, Kongo, Kenia, Ghana, Górna Wolta, Wybrzeże Kości Słoniowej. "Kościół w Afryce rośnie i przyniesie owoce całemu światu."', img:'img/jp2_afryka.jpg' },
];
const JP2_BIO = [
{ rok:'18 V 1920', kat:'urodziny', dot:'gold', title:'Narodziny w Wadowicach',
desc:'Karol Józef Wojtyła przychodzi na świat w Wadowicach (Małopolska). Syn Karola Wojtyły seniora — podoficera Wojska Polskiego — i Emilii z Kaczorowskich. Ochrzczony 20 VI 1920 w kościele Ofiarowania NMP.' },
{ rok:'1929', kat:'rodzina', dot:'red', title:'Śmierć Matki',
desc:'Śmierć matki Emilii, gdy Karol miał zaledwie 9 lat. Ojciec staje się najważniejszą osobą w jego wychowaniu i przekazuje mu głęboką pobożność maryjną.' },
{ rok:'1938', kat:'wykształcenie', dot:'blue', title:'Studia na Uniwersytecie Jagiellońskim',
desc:'Wstępuje na Wydział Filozoficzny UJ. Angażuje się w teatr rapsodyczny i poezję. Mówi biegle po polsku, łacinie, grecku, włosku, francusku, niemiecku, angielsku, hiszpańsku i po suahili.' },
{ rok:'19391945', kat:'wojna', dot:'red', title:'Czas II Wojny Światowej',
desc:'Pracuje w kamieniołomach i fabryce chemicznej Solvay, by uniknąć deportacji. Opiekuje się chorymi i uciekinierami. Traci ojca w 1941 r. W 1942 wstępuje do tajnego seminarium duchownego abpa Sapiehy — narażając życie.' },
{ rok:'1 XI 1946', kat:'kapłaństwo', dot:'gold', title:'Święcenia Kapłańskie',
desc:'Wyświęcony na kapłana przez kardynała Adama Sapiehy. Mszę prymicyjną odprawia w Kaplicy Wawelskiej. Wyruszony natychmiast do Rzymu na doktorat z teologii.' },
{ rok:'1953', kat:'nauka', dot:'blue', title:'Habilitacja i wykłady na KUL',
desc:'Habilitacja na Wydziale Teologicznym UJ. Wykłada etykę i filozofię moralną na KUL w Lublinie. Łączy głęboką myśl teologiczną z filozofią Schelera i Tomaszem z Akwinu.' },
{ rok:'28 IX 1958', kat:'biskupstwo', dot:'blue', title:'Najmłodszy biskup w Polsce',
desc:'Konsekracja biskupia w wieku 38 lat — najmłodszy biskup w powojennej Polsce. Dewiza "Totus Tuus" (Cały Twój) — całkowite oddanie Maryi. Hasło towarzyszy mu przez cały pontyfikat.' },
{ rok:'1964', kat:'biskupstwo', dot:'blue', title:'Arcybiskup metropolita krakowski',
desc:'Mianowany Arcybiskupem Krakowa przez Pawła VI. Aktywny uczestnik Soboru Watykańskiego II. Wielki wpływ na ostateczny kształt konstytucji Gaudium et Spes.' },
{ rok:'26 VI 1967', kat:'kardynał', dot:'gold', title:'Kardynał Kościoła Powszechnego',
desc:'Mianowany kardynałem. Staje się jednym z najważniejszych głosów w Kościele. Aktywnie uczestniczy w kongregacjach watykańskich, zdobywając zaufanie całego Kolegium Kardynalskiego.' },
{ rok:'16 X 1978', kat:'papież', dot:'gold', title:'Habemus Papam! Pierwszy Polak na Tronie Piotrowym',
desc:'O godzinie 18:18 na balkonie bazyliki Świętego Piotra ukazuje się kard. Karol Wojtyła. "Habemus Papam!" Tłum płacze z radości i niedowierzania. Pierwszy Słowianin i nieitalijski papież od 455 lat. Wybiera imię Jan Paweł II.' },
{ rok:'2 VI 1979', kat:'Polska', dot:'gold', title:'Pierwsza pielgrzymka do Polski — "Niech zstąpi Duch Twój"',
desc:'"Niech zstąpi Duch Twój i odnowi oblicze ziemi — tej ziemi!" Słowa, które stały się iskrą Solidarności. 10 milionów Polaków wyszło na ulice. Komuniści przerażeni siłą katolicyzmu. Rok później Solidarność ma 10 milionów członków.' },
{ rok:'13 V 1981', kat:'zamach', dot:'red', title:'Zamach na Placu Świętego Piotra — Cudowne Ocalenie',
desc:'Mehmet Ali Agca strzela z odległości kilku metrów. Kule przeszywają ciało papieża, ale omijają serce i kluczowe tętnice o milimetry. JP2 przeżywa i mówi: "Jedna ręka strzeliła, a inna prowadziła kulę." 13 maja to rocznica objawień fatimskich.' },
{ rok:'1983', kat:'pojednanie', dot:'blue', title:'Przebaczenie zamachowcowi w więzieniu',
desc:'JP2 odwiedza Agcę w więzieniu. Dwie godziny rozmowy twarzą w twarz. Papież przebacza. Ten gest wstrząsa światem — jest żywym świadectwem Ewangelii.' },
{ rok:'1989', kat:'Polska', dot:'gold', title:'"Człowiek z Żelaza" — Upadek Komunizmu',
desc:'Ronald Reagan i Margaret Thatcher otwarcie przyznali: "Bez Jana Pawła II nie byłoby Solidarności, bez Solidarności — nie byłoby końca komunizmu w Europie." JP2 przez 11 lat systematycznie osłabiał morale bloku wschodniego swoimi wizytami i słowami.' },
{ rok:'1993', kat:'nauczanie', dot:'blue', title:'Encyklika Veritatis Splendor',
desc:'Wielkie dzieło obrony obiektywnej moralności. Kontratak na relatywizm moralny i permisywizm. JP2 przypomina: "Nie ma wolności bez prawdy."' },
{ rok:'1994', kat:'nauczanie', dot:'blue', title:'Evangelium Vitae — Ewangelia Życia',
desc:'Encyklika broniąca życia od poczęcia do naturalnej śmierci. Silny sprzeciw wobec aborcji, eutanazji i kary śmierci. Fundament etyki chrześcijańskiej XXI wieku.' },
{ rok:'5 X 1995', kat:'świat', dot:'blue', title:'Przemówienie w ONZ — "Lęk się nie lęk!"',
desc:'Przemówienie przed 50-letnią sesją Zgromadzenia Ogólnego ONZ. "Nie lękajcie się! Otwórzcie, otwórzcie na oścież drzwi Chrystusowi!" Owacja na stojąco wszystkich 185 delegacji. Jeden z największych mówców XX wieku.' },
{ rok:'2000', kat:'jubileusz', dot:'gold', title:'Wielki Jubileusz — Rok 2000',
desc:'Największy rok pontyfikatu. Pielgrzymka do Ziemi Świętej, modlitwa przy Ścianie Płaczu z prośbą o przebaczenie za grzechy wobec Żydów. Przeprosiny za wszystkie historyczne grzechy Kościoła. Przełomowy gest pokory.' },
{ rok:'2 IV 2005', kat:'śmierć', dot:'red', title:'Odejście do Domu Ojca',
desc:'O godz. 21:37 JP2 umiera w Pałacu Apostolskim. Na Placu Świętego Piotra milion pielgrzymów modli się w ciszy. Na pogrzeb przybywa 4 miliony osób — największe zgromadzenie w historii. Tłum woła: "Santo subito!" (Święty natychmiast!)' },
{ rok:'1 V 2011', kat:'beatyfikacja', dot:'gold', title:'Beatyfikacja — Błogosławiony Jan Paweł II',
desc:'Benedykt XVI beatyfikuje Jana Pawła II. Cud: uzdrowienie siostry Marie Simon-Pierre z choroby Parkinsona po modlitwie o wstawiennictwo JP2. Milion wiernych na Placu Świętego Piotra.' },
{ rok:'27 IV 2014', kat:'kanonizacja', dot:'gold', title:'Kanonizacja — ŚWIĘTY Jan Paweł II',
desc:'Papież Franciszek ogłasza Jana Pawła II świętym. Drugi cud: uzdrowienie Floribeth Mora Díaz z tętniaka mózgu. Podwójna kanonizacja z Janem XXIII. 800 tysięcy pielgrzymów. Polska zalana łzami radości.' },
];
function renderJP2Page() {
const container = document.getElementById('feed-container');
if (_jp2Map) { try { _jp2Map.remove(); } catch(e){} _jp2Map = null; }
const polandPilgr = [
{ n:1, year:1979, cities:'Warszawa · Gniezno · Częstochowa · Kraków · Oświęcim · Nowy Targ',
title:'I Pielgrzymka — 210 czerwca 1979',
desc:'Historyczna pierwsza wizyta — jedyne w historii co do zasięgu odwiedziny głowy Kościoła w kraju komunistycznym. 10 milionów Polaków wyszło na ulice. Komunizm zachwiał się w posadach.',
quote:'"Niech zstąpi Duch Twój i odnowi oblicze ziemi — tej ziemi!" — Warszawa, 2 VI 1979' },
{ n:2, year:1983, cities:'Warszawa · Niepokalanów · Częstochowa · Poznań · Wrocław · Kraków',
title:'II Pielgrzymka — 1623 czerwca 1983',
desc:'Polska żyje w stanie wojennym. JP2 przekazuje Polakom nadzieję i siłę przetrwania. Historyczne spotkanie z Lechem Wałęsą.',
quote:'"Polacy potrzebują dziś szczególnej mocy ducha." — Kraków, 1983' },
{ n:3, year:1987, cities:'Warszawa · Gdynia · Gdańsk · Nowa Huta · Tarnów · Łódź · Szczecin · Westerplatte',
title:'III Pielgrzymka — 814 czerwca 1987',
desc:'Westerplatte staje się symbolem. Przemówienie do stoczniowców Gdańska wstrząsa Polską. JP2 mówi wprost o prawie do Solidarności.',
quote:'"Każdy musi znaleźć swoje Westerplatte." — Gdańsk, 1987' },
{ n:4, year:1991, cities:'Koszalin · Rzeszów · Przemyśl · Lubaczów · Kielce · Radom · Łomża · Białystok · Olsztyn · Włocławek · Płock · Warszawa · Wrocław · Kraków',
title:'IV Pielgrzymka — 19 czerwca 1991',
desc:'Pierwsza pielgrzymka do wolnej Polski po upadku komunizmu! 14 miast w 9 dni. JP2 przekazuje Dekalog dla wolnej Polski — wyzwanie i program na nowe czasy.',
quote:'"Ta wolność, którą Chrystus nas obdarzył — jest wielkim darem i wielkim zadaniem." — Warszawa, 1991' },
{ n:5, year:1997, cities:'Wrocław · Gniezno · Poznań · Gliwice · Częstochowa · Zakopane · Kraków',
title:'V Pielgrzymka — 31 maja10 czerwca 1997',
desc:'46. Kongres Eucharystyczny we Wrocławiu. Zjazd Gnieźnieński — szczyt głów państw Europy Środkowej. Beatyfikacja Jadwigi Andegaweńskiej.',
quote:'"Europa potrzebuje Polski. Polska potrzebuje Europy." — Gniezno, 1997' },
{ n:6, year:1999, cities:'Gdańsk · Sopot · Elbląg · Toruń · Bydgoszcz · Łowicz · Warszawa · Siedlce · Sosnowiec · Kraków · Sandomierz · Zamość · Rzeszów',
title:'VI Pielgrzymka — 517 czerwca 1999',
desc:'13 miast! Konsekracja sanktuarium Bożego Miłosierdzia w Łagiewnikach. JP2 zawierza cały świat Bożemu Miłosierdziu.',
quote:'"Jezus, ufam Tobie." — Łagiewniki, 1999' },
{ n:7, year:2002, cities:'Kraków-Łagiewniki · Kalwaria Zebrzydowska',
title:'VII Pielgrzymka — 1619 sierpnia 2002 (Ostatnia)',
desc:'Konsekracja Świątyni Bożego Miłosierdzia. Ostatnia wizyta w ukochanej ojczyźnie. Miliony Polaków płakało. Tłumy czuły, że to pożegnanie.',
quote:'"Ogień miłosierdzia niech ogarnie cały świat." — Łagiewniki, 2002' },
];
const miracles = [
{ icon:'🕊️', title:'Cudowne ocalenie z zamachu (1981)',
desc:'13 maja 1981 — Mehmet Ali Agca strzela z 4 metrów. Kule przebijają ciało papieża, lecz omijają serce i aortę o ułamki milimetra. Lekarze orzekają: "To niemożliwe, by żył." JP2 mówi: "Jedna ręka strzeliła, a inna prowadziła kulę" — wskazując na Matkę Bożą Fatimską. Data 13 maja = rocznica objawień w Fatimie.' },
{ icon:'✝️', title:'Upadek komunizmu — "Cud XX wieku"',
desc:'Reagan, Thatcher i Gorbaczow niezależnie przyznali: bez Jana Pawła II komunizm nie upadłby tak szybko. JP2 dał Polakom odwagę, Solidarność — nadzieję, a Reagan i papież — strategię. 11 lat systematycznego osłabiania imperium zła. Europa wyzwolona bez jednego strzału po stronie NATO.' },
{ icon:'💛', title:'Cud Beatyfikacji — s. Marie Simon-Pierre',
desc:'Siostra zakonna chora na chorobę Parkinsona — tę samą, na którą cierpiał JP2 — modliła się o wstawiennictwo. Pewnej nocy wstała o 4:30, podeszła do lustra. Choroba zniknęła. Komisja medyczna złożona z lekarzy różnych wyznań stwierdziła: "Naukowe wyjaśnienie jest niemożliwe."' },
{ icon:'🌍', title:'Cud ewangelizacji — 1,3 miliarda serc',
desc:'JP2 odbył 104 pielgrzymki zagraniczne, odwiedził 129 krajów, przebył 1,17 miliona km. Więcej niż wszystkie poprzednie papieże razem wzięte. Wygłosił ponad 3 000 przemówień. Był najczęściej fotografowaną osobą w historii. Liczba katolików wzrosła za jego pontyfikatu o 300 milionów.' },
{ icon:'☮️', title:'Pojednanie narodów i religii',
desc:'Przeprosił Żydów (Ściana Płaczu 2000), prawosławnych (za krucjaty), muzułmanów (modlitwa w meczecie Damaszku), protestantów i anglikanów. Odwiedził synagogi, meczety, świątynie hinduskie. Zjazd religii świata w Asyżu 1986 — nigdy wcześniej ani potem nie było czegoś podobnego.' },
{ icon:'🎤', title:'"Nie lękajcie się!" — dar charyzmy',
desc:'Wybrany "Człowiekiem Stulecia" przez magazyn Time. 5-krotny Człowiek Roku Time. Jego przemówienie w ONZ 1979 wywołało owację całego Zgromadzenia Generalnego. Mówił w 9 językach — każdy naród czuł, że papież mówi do NICH. To nie retorika — to Duch Święty.' },
];
const politycy = [
{ img:'img/kaczynski.jpg', name:'Lech Kaczyński', desc:'Wielokrotne spotkania z Ojcem Świętym jako Prezydent Warszawy i RP. Kaczyński podkreślał: "JP2 był i jest moim drogowskazem."' },
{ img:'img/kaczynski.jpg', name:'Jarosław Kaczyński', desc:'Brat bliźniak Lecha. "Papież był dla nas obydwu — autorytetem, wzorcem i źródłem siły w najtrudniejszych momentach." Prawo i Sprawiedliwość czerpie z nauczania JP2.' },
{ img:'img/czarnek.jpg', name:'Przemysław Czarnek', desc:'"Jan Paweł II to największy Polak i największy chrześcijanin XX wieku. Musimy bronić jego dobrego imienia przed lewackimi atakami."' },
{ img:'img/nawrocki.jpg', name:'Karol Nawrocki', desc:'"Etos Jana Pawła II — służba, prawda, odwaga — to fundament, na którym chcę budować." Kandydat popierany przez PiS, otwarcie odwołuje się do JP2.' },
{ img:'img/blaszczak.jpg', name:'Mariusz Błaszczak', desc:'"Wartości Jana Pawła II — rodzina, naród, suwerenność, godność człowieka — to program polityczny na XXI wiek."' },
{ img:'img/ziobro.jpg', name:'Zbigniew Ziobro', desc:'"Papież Jan Paweł II walczył z systemem, który niszczył ludzką godność. My kontynuujemy tę walkę w obronie praworządności."' },
];
container.innerHTML = `
<div class="jp2-page">
<div class="jp2-hero">
<div class="jp2-hero-title">✝ Święty Jan Paweł II — Karol Wojtyła</div>
<div class="jp2-hero-sub">Papież, który zmienił świat. Człowiek, który obalił komunizm. Prorok, który przepowiedział upadek imperium zła. Syn narodu polskiego — dar Polski dla świata. 19202005.</div>
<div class="jp2-stats">
<div class="jp2-stat"><div class="n">26 lat</div><div class="l">Pontyfikat</div></div>
<div class="jp2-stat"><div class="n">104</div><div class="l">Pielgrzymki zagraniczne</div></div>
<div class="jp2-stat"><div class="n">129</div><div class="l">Krajów odwiedzonych</div></div>
<div class="jp2-stat"><div class="n">7</div><div class="l">Wizyt w Polsce</div></div>
<div class="jp2-stat"><div class="n">1,3 mld</div><div class="l">Katolików po pontyfikacie</div></div>
</div>
</div>
<!-- BIO TIMELINE -->
<div class="jp2-section">
<div class="jp2-section-title">📜 Chronologia życia i pontyfikatu</div>
<div class="jp2-timeline">
${JP2_BIO.map(e => `
<div class="jp2-tl-item">
<div class="jp2-tl-dot ${e.dot}"></div>
<div class="jp2-tl-card">
<div class="jp2-tl-year">${e.rok}</div>
<div class="jp2-tl-title">${e.title}</div>
<div class="jp2-tl-desc">${e.desc}</div>
</div>
</div>`).join('')}
</div>
</div>
<!-- PILGRIMAGES MAP -->
<div class="jp2-section">
<div class="jp2-section-title">🗺️ Mapa pielgrzymek Jana Pawła II — świat u stóp Namiestnika Chrystusa</div>
<div class="jp2-map-wrap" id="jp2-map"></div>
<div class="jp2-map-legend">
<div class="jp2-map-legend-item"><div class="jp2-map-legend-dot" style="background:#fbbf24"></div> Pielgrzymki do Polski (7 wizyt)</div>
<div class="jp2-map-legend-item"><div class="jp2-map-legend-dot" style="background:#3b82f6"></div> Pielgrzymki zagraniczne (104 wizyty, 129 krajów)</div>
</div>
</div>
<!-- POLISH PILGRIMAGES -->
<div class="jp2-section">
<div class="jp2-section-title">🇵🇱 7 pielgrzymek do ukochanej ojczyzny</div>
<div class="jp2-pilgr-grid">
${polandPilgr.map(p => `
<div class="jp2-pilgr-card">
<div class="jp2-pilgr-n">PIELGRZYMKA ${p.n} · ${p.year}</div>
<div class="jp2-pilgr-title">${p.title}</div>
<div style="font-size:0.7rem;color:#3b82f6;margin-bottom:6px">📍 ${p.cities}</div>
<div class="jp2-pilgr-desc">${p.desc}</div>
<div class="jp2-pilgr-quote">${p.quote}</div>
</div>`).join('')}
</div>
</div>
<!-- MIRACLES -->
<div class="jp2-section">
<div class="jp2-section-title">✨ Cuda i wielkie dzieła Świętego Jana Pawła II</div>
<div class="jp2-miracle-grid">
${miracles.map(m => `
<div class="jp2-miracle-card" data-icon="${m.icon}">
<div class="jp2-miracle-icon">${m.icon}</div>
<div class="jp2-miracle-title">${m.title}</div>
<div class="jp2-miracle-desc">${m.desc}</div>
</div>`).join('')}
</div>
</div>
<!-- POLITICIANS GALLERY -->
<div class="jp2-section">
<div class="jp2-section-title">🦅 Politycy PiS o Janie Pawle II — dziedzictwo i kontynuacja</div>
<div class="jp2-gallery-grid">
${politycy.map(p => `
<div class="jp2-gal-card">
<img class="jp2-gal-img" src="${p.img}" alt="${p.name}" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">
<div class="jp2-gal-placeholder" style="display:none">🙏</div>
<div class="jp2-gal-name">${p.name}</div>
<div class="jp2-gal-desc">${p.desc}</div>
</div>`).join('')}
</div>
</div>
<!-- COUNTER NARRATIVE -->
<div class="jp2-section">
<div class="jp2-counter">
<div class="jp2-counter-title">🛡️ Prawda kontra lewacka narracja — obrona dobrego imienia Jana Pawła II</div>
<div class="jp2-counter-item">
<div class="jp2-counter-bullet">❌</div>
<div class="jp2-counter-text"><b>KŁAMSTWO: "JP2 tuszował pedofilię"</b> — Tę narrację od lat serwują media związane z lewicą i Gazeta Wyborcza. Jest to element systemowego ataku na Kościół katolicki i polską tożsamość. Lewica nienawidzi JP2, bo był skutecznym obrońcą życia, rodziny i tradycji — wszystkiego, co lewica chce zniszczyć.</div>
</div>
<div class="jp2-counter-item">
<div class="jp2-counter-bullet">✅</div>
<div class="jp2-counter-text"><b>PRAWDA: JP2 osobiście walczył z przestępczością seksualną w Kościele.</b> To on nakazał przeprowadzenie dochodzenia w sprawie Marciale Maciela — założyciela Legionistów Chrystusa. To za jego pontyfikatu Kościół jako pierwszy wprowadził globalne procedury zero tolerancji dla nadużyć. Spotkał się osobiście z ofiarami nadużyć w Australii, USA i Niemczech.</div>
</div>
<div class="jp2-counter-item">
<div class="jp2-counter-bullet">✅</div>
<div class="jp2-counter-text"><b>Polska prokuratura i niezależne analizy nie znalazły dowodów na winę JP2.</b> Prokuratura Generalna RP wielokrotnie badała te zarzuty. Każde dochodzenie kończyło się tym samym: brak dowodów winy Karola Wojtyły. Lewicowe media ignorują te fakty, bo nie służą narracji.</div>
</div>
<div class="jp2-counter-item">
<div class="jp2-counter-bullet">🎯</div>
<div class="jp2-counter-text"><b>Dlaczego właśnie teraz, dlaczego właśnie JP2?</b> Odpowiedź jest prosta: Jan Paweł II jest symbolem polskiego ducha, suwerenności i wartości chrześcijańskich. Atakując go, lewica atakuje fundamenty polskiej tożsamości. To polityczny projekt demolowania Polski od wewnątrz. Nie dajmy się — brońmy dobrego imienia Świętego!</div>
</div>
<div class="jp2-counter-item">
<div class="jp2-counter-bullet">🙏</div>
<div class="jp2-counter-text"><b>"Santo subito!" — Święty natychmiast!</b> Tak wołał tłum milionów przy trumnie JP2. Kościół wysłuchał: JP2 jest świętym kanonizowanym przez Franciszka w 2014 r. Miliardy wiernych uznają go za jednego z najświętszych ludzi w historii. Żadna lewacka propaganda nie zmieni tego faktu.</div>
</div>
</div>
</div>
</div>`;
setTimeout(() => {
const mapEl = document.getElementById('jp2-map');
if (!mapEl || _jp2Map) return;
_jp2Map = L.map('jp2-map', { zoomControl: true, attributionControl: false }).setView([30, 20], 2);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
maxZoom: 19, subdomains: 'abcd'
}).addTo(_jp2Map);
JP2_PILGRIMAGES.forEach(p => {
const isPoland = p.type === 'poland';
const color = isPoland ? '#fbbf24' : '#3b82f6';
const radius = isPoland ? 10 : 7;
const icon = L.divIcon({
className: '',
html: `<div style="width:${radius*2}px;height:${radius*2}px;border-radius:50%;background:${color};border:2px solid #fff;box-shadow:0 0 8px ${color};"></div>`,
iconSize: [radius*2, radius*2], iconAnchor: [radius, radius]
});
const imgHtml = `<img class="jp2-popup-img" src="${p.img}" onerror="this.style.display='none'" alt="">`;
const popup = L.popup({ maxWidth: 260, className: '' }).setContent(
`<div class="jp2-popup">${imgHtml}<div class="jp2-popup-title">✝ ${p.title}</div><div class="jp2-popup-desc">${p.desc}</div></div>`
);
const marker = L.marker([p.lat, p.lng], { icon }).addTo(_jp2Map).bindPopup(popup);
marker.on('mouseover', function() { this.openPopup(); });
});
}, 120);
}
// ══════════════════════════════════════════════
// VIDEO PAGE
// ══════════════════════════════════════════════
const VIDEOS = [
{ file:'Bezrobocie za Tuska - zrobi to znowu.mp4', title:'Bezrobocie za Tuska — zrobi to znowu' },
{ file:'Polsce grozi przymusowa relokacja ludzi z Lampedusy.mp4', title:'Polsce grozi przymusowa relokacja — Lampedusa' },
{ file:'Tusk padł na kolana przed Putinem i rozbroił Polskę..mp4', title:'Tusk padł na kolana przed Putinem i rozbroił Polskę' },
{ file:'Tusk podniósł Polakom wiek emerytalny.mp4', title:'Tusk podniósł Polakom wiek emerytalny' },
{ file:'Tusk zrobił to raz i zrobi to znowu. Nie zasługuje na kolejną szansę..mp4', title:'Tusk zrobił to raz i zrobi to znowu. Nie zasługuje na kolejną szansę.' },
{ file:'WYBÓR JEST TWÓJ - RUSOFOB CZY TUSK.mp4', title:'WYBÓR JEST TWÓJ — RUSOFOB CZY TUSK?' },
];
function renderVideoPage() {
const container = document.getElementById('feed-container');
const cards = VIDEOS.map(v => `
<div class="video-card">
<video controls preload="metadata" src="/video/${encodeURIComponent(v.file)}">
Twoja przeglądarka nie obsługuje HTML5 video.
</video>
<div class="video-card-title">${escHtml(v.title)}</div>
</div>`).join('');
container.innerHTML = `
<div class="video-page">
<div class="section-label" style="border-left-color:#f97316;background:rgba(249,115,22,0.08)">🎬 Wideo — materiały polityczne</div>
<div class="video-grid">${cards}</div>
</div>`;
}
// ══════════════════════════════════════════════
// TUSK DAILY PORTRAIT
// ══════════════════════════════════════════════
const TUSK_FAIL_POOL = [
{ cat:'Gospodarka', icon:'📉', title:'Bezrobocie 14% — 2 miliony Polaków na emigracji',
tusk:'Za rządów Tuska (20082014) bezrobocie przekroczyło 14%. 2 miliony Polaków wyjechało za granicę — do Niemiec, UK, Irlandii. PKB rosło zaledwie 1,4% w 2013 r.',
pis: 'PiS obniżyło bezrobocie do historycznego minimum 2,9% (2022 r.). Polacy zaczęli wracać z emigracji. PKB rosło 45% rocznie — lider Europy Środkowej.' },
{ cat:'Emerytury', icon:'👴', title:'Wiek emerytalny 67 lat — wyrok na polskich seniorów',
tusk:'W 2012 r. Tusk podniósł wiek emerytalny do 67 lat. Kobiety pracujące do śmierci. Odwrót od własnych obietnic wyborczych — Platforma obiecywała stabilność emerytur.',
pis: 'PiS przywróciło wiek emerytalny: kobiety 60, mężczyźni 65 lat. Dołożono 13. i 14. emeryturę — dziesiątki miliardów złotych dla seniorów.' },
{ cat:'Bezpieczeństwo', icon:'🔓', title:'Rozbrojenie armii — sprzedaż czołgów na złom',
tusk:'Tusk zredukował wydatki obronne poniżej 1,95% PKB. Wyprzedano czołgi T-72, skrócono służbę wojskową, rozwiązano pułki. Armia na kolanach.',
pis: 'PiS zwiększyło wydatki obronne do 4% PKB — rekord NATO. Zakupiono F-35, Patriot, HIMARS i K2. Armia numerem 1 w Europie.' },
{ cat:'OFE', icon:'💸', title:'Grabież 153 mld zł — prywatne oszczędności Polaków',
tusk:'2013 r. — rząd Tuska "znacjonalizował" 153 mld zł z prywatnych kont OFE. Polacy stracili oszczędności emerytalne, pieniądze trafiły do ZUS i zostały wydane na bieżące potrzeby.',
pis: 'PiS zachowało 25% środków OFE jako prywatną własność. Budowało PPK — dobrowolne oszczędności. Nie sięgało po prywatne pieniądze obywateli.' },
{ cat:'Relokacja', icon:'🚢', title:'Podpisał przymusową relokację imigrantów',
tusk:'2015 r. — rząd Tuska podpisał mechanizm przymusowej relokacji migrantów. Otworzył drogę do sprowadzenia dziesiątek tysięcy imigrantów z Afryki i Bliskiego Wschodu.',
pis: 'PiS zablokował relokację i konsekwentnie odmawiał przyjęcia kwot imigrantów. Polska bezpieczna, tożsamość kulturowa zachowana.' },
{ cat:'Podatki', icon:'📋', title:'Luka VAT 40 mld zł — budżet wykrwawiany',
tusk:'Za Tuska luka VAT sięgała 40 mld zł rocznie. Przestępcy bezkarnie okradali budżet. CIT jeden z najwyższych w regionie. Przedsiębiorcy uciekali do Czech.',
pis: 'PiS uszczelniło VAT — dochody wzrosły o 70 mld zł rocznie. CIT 9% dla małych firm, zerowy PIT dla młodych do 26 lat.' },
{ cat:'Infrastruktura', icon:'🛣', title:'Drogi z unijnych dotacji — przekroczenia 200%',
tusk:'Za Tuska budowa dróg była finansowana prawie wyłącznie z UE. Setki km planowanych tras nie oddano w terminie. Przekroczenia kosztorysów sięgały 200%.',
pis: 'PiS oddało ponad 3 500 km nowych dróg ekspresowych i autostrad (20152023). Uruchomiono projekt CPK — centrum komunikacyjne dla Europy.' },
{ cat:'Rodzina', icon:'👨‍👩‍👧', title:'Zasiłek 77 zł miesięcznie — państwo porzuciło rodziny',
tusk:'Za Tuska zasiłek rodzinny wynosił śmieszne 77 zł. Brak żłobków, brak wsparcia. Dzietność polska spadła do 1,2 — jedna z najniższych w UE. Ubóstwo dzieci rosło.',
pis: 'PiS: 500+ (potem 800+), 13. i 14. emerytura, Dobry Start 300+, darmowe leki dla dzieci. Ubóstwo rodzin z dziećmi spadło o 70%.' },
{ cat:'Zdrowie', icon:'🏥', title:'4,4% PKB na zdrowie — kolejki na lata',
tusk:'Za Tuska na zdrowie szło 4,4% PKB przy średniej UE 7%. Kolejki do specjalistów — 23 lata. Szpitale bankrutowały. NFZ zadłużony. Lekarze emigrowali.',
pis: 'PiS zwiększyło finansowanie zdrowia, wyznaczyło cel 7% PKB. Bezpłatne leki dla 75+ i dzieci. Reforma psychiatrii. Koniec z limitem nocnych dyżurów.' },
{ cat:'Energetyka', icon:'⚡', title:'Blokada atomu przez 6 lat — uzależnienie od Rosji',
tusk:'Tusk odkładał decyzję o elektrowni jądrowej przez cały okres rządów (20072014). Polska uzależniona od rosyjskiego gazu — ponad 70% importu. Brak terminalu LNG.',
pis: 'PiS podpisał kontrakt na pierwszą polską elektrownię jądrową z Westinghouse. Zbudowano Baltic Pipe. Polska uniezależniona od Kremla energetycznie.' },
{ cat:'Praworządność', icon:'⚖️', title:'Bezprawne przejęcie TVP bez wyroku sądu',
tusk:'Grudzień 2023 — rząd Tuska siłą przejął TVP, Polskie Radio i PAP. Bez podstawy prawnej, z naruszeniem uchwał Sejmu. Sądy wydawały postanowienia — Tusk ignorował.',
pis: 'Żaden rząd PiS nie dokonał bezprawnego, nocnego przejęcia mediów publicznych w sposób naruszający decyzje sądów i procedury parlamentarne.' },
{ cat:'Rolnictwo', icon:'🌾', title:'Ukraińskie zboże zalewa Polskę — rolnicy bankrutują',
tusk:'Rząd Tuska długo zwlekał z ochroną polskich rolników przed tanim zbożem z Ukrainy wjeżdżającym bez cła. Dziesiątki tysięcy ton blokowały polskie magazyny.',
pis: 'PiS i rząd Morawieckiego skutecznie blokował ukraińskie zboże na granicy. Polscy rolnicy chronieni przed nieuczciwą konkurencją.' },
{ cat:'Inflacja', icon:'📈', title:'Zdjął tarcze — VAT na żywność wzrósł do 5%',
tusk:'Rząd Tuska nie przedłużył tarcz antyinflacyjnych PiS. VAT na żywność z 0% do 5%. Chleb, masło, mleko — Polacy płacą więcej od pierwszego dnia rządów Tuska.',
pis: 'Tarcze PiS: zerowy VAT na żywność, obniżony VAT na paliwa, mrożenie cen energii. W szczycie kryzysu Polacy płacili mniej niż wszyscy sąsiedzi.' },
{ cat:'CPK', icon:'✈️', title:'Torpeduje CPK — lobbyści i Berlin wygrywają',
tusk:'Rząd Tuska blokuje CPK. Audyty, komisje, opóźnienia. 180 000 miejsc pracy w zagrożeniu. Równocześnie Frankfurt i Berlin tracą rywala o pasażerów tranzytowych.',
pis: 'PiS uruchomił CPK — projekt stulecia. Polski hub lotniczy i kolejowy dla 300 mln pasażerów rocznie. Szansa dla całej Europy Środkowej.' },
{ cat:'Granica', icon:'🛡', title:'Demontaż zapory — tysiące nielegalnych przejść',
tusk:'Rząd Tuska demontował elementy zapory na granicy z Białorusią. Straż Graniczna z "związanymi rękami". Liczba nielegalnych przekroczeń granicy wzrosła wielokrotnie.',
pis: 'PiS zbudowało 186 km stalowej zapory na granicy polsko-białoruskiej. Polska wzorem skutecznej ochrony granicy UE dla Finlandii, Łotwy i Estonii.' },
{ cat:'Historia', icon:'📜', title:'Oddaje rosyjskie narracje — ignoruje reparacje',
tusk:'Tusk akceptował rosyjskie interpretacje Smoleńska. Rezygnował z polskich roszczeń wobec Niemiec (1,5 bln USD reparacji). IPN i muzea historyczne bez wsparcia.',
pis: 'PiS zbudowało Muzeum Historii Polski, Muzeum Żołnierzy Wyklętych, Muzeum Kresów. IPN pod PiS ujawnił tysiące akt zbrodni komunistycznych i nazistowskich.' },
{ cat:'Afera wizowa', icon:'🕵️', title:'Polskie wizy sprzedawane za łapówki w MSZ',
tusk:'20232024 — koalicja Tuska uwikłana w aferę wizową. Urzędnicy MSZ sprzedawali polskie wizy pracownikom i imigrantom z Azji i Afryki za łapówki. Tysiące nielegalnych wiz.',
pis: 'Prokuratura wszczęła śledztwa w sprawie nieprawidłowości. Winni z poprzednich rządów pociągnięci do odpowiedzialności w ramach kontroli konsularnej.' },
{ cat:'Sądownictwo', icon:'🏛', title:'Naruszył Konstytucję — TK orzekał bezskutecznie',
tusk:'Rząd Tuska przeprowadził bezprawne zmiany w KRS, TK i prokuraturze. Trybunał Konstytucyjny wielokrotnie orzekał niezgodność tych działań z Konstytucją RP.',
pis: 'PiS reformowało wymiar sprawiedliwości z mandatem wyborczym. Nie ignorował orzeczeń TK wbrew własnym deklaracjom o praworządności.' },
{ cat:'Wolność mediów', icon:'📢', title:'Nagonka na Republikę i wPolsce — cenzura budżetowa',
tusk:'Rząd Tuska blokuje reklamy państwowych spółek w prawicowych mediach. Dziennikarze TV Republika szykanowani. Prokuratura wszczyna postępowania wobec komentatorów.',
pis: 'Za PiS TVN, Wyborcza i Polityka działały bez ograniczeń finansowych. Miały rekordowe wpływy z reklam. Żaden dziennikarz nie był ścigany za krytykę rządu.' },
{ cat:'Amber Gold', icon:'🔍', title:'Syn Tuska w piramidzie finansowej — ojciec milczał',
tusk:'Michał Tusk, syn premiera, pracował w Amber Gold — piramidzie finansowej, która okradła 17 tys. Polaków z 850 mln zł. Premier Tusk wiedział i nie reagował.',
pis: 'Komisja śledcza PiS ds. Amber Gold ujawniła, że służby wiedziały o przestępczym charakterze firmy co najmniej od 2010 r. — rząd Tuska nic nie zrobił.' },
{ cat:'Afera hazardowa', icon:'🎰', title:'Hazard — ministrowie blokowali ustawę dla lobbystów',
tusk:'2010 r. — ministrowie rządu Tuska (Schetyna, Nowak) byli nagrywani podczas spotkań z lobbystami branży hazardowej. Ustawa antyhazardowa blokowana przez lata.',
pis: 'PiS zakończyło lobbyingowy paraliż i uchwaliło przepisy ograniczające nieregulowany hazard online. Ochrona społeczeństwa przed uzależnieniami.' },
{ cat:'Taśmy', icon:'🎙', title:'Taśmy Wprost — ministrowie kpią z suwerenności',
tusk:'Czerwiec 2014 — "Taśmy Wprost": ministrowie Sikorski, Belka, Rostowski nagrywani w restauracjach. Belka oferuje NBP w zamian za polityczne wsparcie. Sikorski poniża Polskę wobec USA.',
pis: 'Żaden minister rządu PiS nie był nagrywany podczas prywatnych rozmów z propozycjami zawłaszczenia instytucji państwowych dla partii rządzącej.' },
{ cat:'Smoleńsk', icon:'✈️', title:'Wydał Rosji śledztwo — wrak i czarne skrzynki do dziś',
tusk:'Rząd Tuska oddał rosyjskim służbom pełną kontrolę nad katastrofą smoleńską. Wrak TU-154M przetrzymywany przez Rosję do dziś. Czarne skrzynki — w Moskwie.',
pis: 'PiS wszczęło polskie śledztwo smoleńskie, powołało komisję Macierewicza i domagało się zwrotu wraku. Polska ma prawo do prawdy o katastrofie.' },
];
const TUSK_PUTIN_DATA = [
{ rok:'2009', icon:'🍷', title:'Prywatna kolacja z Putinem w Sopocie',
desc:'Grudzień 2009 — Premier Donald Tusk uczestniczył w prywatnej kolacji z Władimirem Putinem w Sopocie. Rozmawiali bez udziału ministrów i protokołu dyplomatycznego. Treść rozmów do dziś nieznana polskiej opinii publicznej.' },
{ rok:'2010', icon:'☠️', title:'Oddał Rosji śledztwo smoleńskie',
desc:'Po katastrofie smoleńskiej (10.04.2010) rząd Tuska zgodził się na rosyjskie prowadzenie śledztwa. Ciała ofiar, czarne skrzynki i wrak Tu-154M trafiły w ręce Kremla. Polska przez lata nie miała dostępu do dowodów.' },
{ rok:'2010', icon:'🤝', title:'Reset z Rosją — redukcja obronności',
desc:'Polityka "resetu" z Rosją: Tusk zrezygnował z kontynuowania negocjacji ws. tarczy antyrakietowej USA na terenie Polski. Podjął decyzję pod wpływem sprzeciwu Kremla, osłabiając bezpieczeństwo wschodniej flanki NATO.' },
{ rok:'2013', icon:'⚡', title:'Blokował dywersyfikację gazu — uzależnienie od Kremla',
desc:'Za rządów Tuska Polska importowała ponad 70% gazu z Rosji. Brak terminalu LNG, brak Baltic Pipe, brak rozmów o alternatywnych dostawcach. Gazprom dyktował warunki. Terminal LNG w Świnoujściu budowano powoli i opieszale.' },
{ rok:'20142019', icon:'🏛', title:'Przewodniczący RE — bierność wobec Nord Stream 2',
desc:'Jako Przewodniczący Rady Europejskiej (20142019) Tusk nie zablokował projektu Nord Stream 2 — osi BerlinMoskwa, która uzależniała całą Europę od rosyjskiego gazu i omijała Ukrainę jako kraj tranzytowy.' },
{ rok:'2014', icon:'🔕', title:'Aneksja Krymu — symboliczne sankcje pod kierownictwem Tuska',
desc:'Gdy Rosja anektowała Krym (marzec 2014), Tusk był już w Radzie Europejskiej. Europa odpowiedziała "symbolicznymi sankcjami", które nie powstrzymały Putina. Tusk nie forsował twardszych działań.' },
{ rok:'2022', icon:'🛑', title:'Sprzeciwiał się dostawom broni dla Ukrainy',
desc:'Będąc w opozycji Tusk krytykował tempo i skalę pomocy wojskowej dla Ukrainy realizowanej przez rząd PiS. Polska pod PiS była pierwszym krajem NATO, który dostarczył Ukrainie czołgi — Tusk nie popierał tej decyzji.' },
{ rok:'2024', icon:'🏗', title:'Usuwa barierę graniczną — droga dla hybrydowej agresji Kremla',
desc:'Rząd Tuska demontuje stalową barierę na granicy polsko-białoruskiej zbudowaną przez PiS. Bariera chroniła przed hybrydową wojną prowadzoną przez Łukaszenkę i Putina. Tusk odwraca ten dorobek.' },
];
const TUSK_GERMANY_DATA = [
{ rok:'Rodzina', icon:'🪖', title:'Dziadek w Werhmachcie — korzenie w kulturze niemiec.',
desc:'Tusk sam przyznał, że jego dziadek Józef Tusk służył w Werhmachcie. Urodzony w Gdańsku/Danzig — historycznym mieście pogranicza. Dla rodziny Tuska Niemcy nigdy nie były jednoznacznym wrogiem historycznym.' },
{ rok:'20072014', icon:'🤐', title:'Blokował polskie roszczenia reparacyjne wobec Niemiec',
desc:'Rząd Tuska nigdy poważnie nie zajął się tematem reparacji wojennych od Niemiec. Polska wyceniła je na ponad 1,5 bln dolarów. Tusk bagatelizował sprawę, nie chcąc drażnić Berlina.' },
{ rok:'20142019', icon:'🏛', title:'Przewodniczący RE — narzędzie polityki Berlina w Europie',
desc:'Tusk objął fotel Przewodniczącego Rady Europejskiej z błogosławieństwa Angeli Merkel i CDU. Przez 5 lat forsował politykę migracyjną Berlina, federalizację UE i uzależnienie Europy od rosyjskiego gazu.' },
{ rok:'2015', icon:'🚶', title:'Forsował politykę imigracyjną Merkel wobec Polski',
desc:'Jako szef RE Tusk forsował na Polskę przymusowe kwoty relokacyjne migrantów — zgodnie z polityką Merkel "Willkommenskultur". Interesy Berlina stawiał ponad suwerenność Warszawy i Czech.' },
{ rok:'20162019', icon:'🔌', title:'Nord Stream 2 — oś BerlinMoskwa z milczącą zgodą Tuska',
desc:'Tusk jako szef RE nie zablokował Nord Stream 2, który był strategicznym projektem Niemiec i Rosji. Projekt ominął Ukrainę i Polskę, kosztował bezpieczeństwo energetyczne całej flanki wschodniej.' },
{ rok:'2022', icon:'✈️', title:'CPK zagraża interesom lotnisk Niemiec — Tusk blokuje',
desc:'Centralny Port Komunikacyjny (CPK) odebrałby pasażerów lotniskm w Berlinie i Frankfurcie. Rząd Tuska konsekwentnie torpeduje projekt — wygodne dla Niemiec, które nie chcą polskiej konkurencji. ' },
{ rok:'Język', icon:'🗣', title:'Biegle mówi po niemiecku — rozmowy bez tłumacza',
desc:'Tusk biegle posługuje się językiem niemieckim. Prowadził część rozmów dyplomatycznych z partnerami z Niemiec bez tłumacza i bez protokołu — treść tych rozmów nie jest znana polskiej opinii publicznej.' },
{ rok:'2023', icon:'💶', title:'Zablokował polskie środki unijne — spełnił żądania Berlina',
desc:'Niemcy i Komisja Europejska przez lata blokowały polskie fundusze z KPO. Rząd Tuska wszedł do władzy deklarując "odblokowanie środków" — w zamian za spełnienie postulatów ideologicznych Berlina i Brukseli.' },
];
const TUSK_SCANDALS = [
{ rok:'2003', title:'Afera Rywina — PO wiedziała, milczała',
desc:'Lew Rywin zaproponował Agorze zmianę prawa medialnego za 17,5 mln USD. Komisja Sejmowa ujawniła powiązania z "grupą trzymającą władzę" SLD. PO i Tusk wiedział o korupcyjnych powiązaniach w mediach — wybrał milczenie.' },
{ rok:'2010', title:'Afera hazardowa — lobbyści blokowali ustawę w rządzie Tuska',
desc:'Posłowie PO i ministrowie rządu Tuska spotkali się z lobbystami branży hazardowej. Ustawa regulująca hazard online była blokowana latami. Nagrania rozmów trafiły do prasy — sprawa zamieciona pod dywan.' },
{ rok:'2012', title:'Amber Gold — syn Tuska pracował w piramidzie',
desc:'Michał Tusk, syn premiera, pracował w Amber Gold — piramidzie finansowej. Firma okradła 17 000 Polaków z 851 mln zł. Służby wiedziały o przestępczym charakterze firmy od 2010 r. Premier Tusk nie zareagował.' },
{ rok:'2012', title:'Wiek emerytalny — złamana obietnica wyborcza',
desc:'Tusk podniósł wiek emerytalny do 67 lat wbrew obietnicom wyborczym PO. Projekt przeprowadzono siłą, mimo ogromnego oporu społecznego i protestów związków zawodowych w całej Polsce.' },
{ rok:'2013', title:'Grabież OFE — 153 mld zł znikają z prywatnych kont',
desc:'Rząd Tuska "znacjonalizował" obligacyjną część OFE — prywatne oszczędności emerytalne obywateli warte 153 mld zł. Środki trafiły do ZUS i zostały wydane na bieżące potrzeby budżetowe.' },
{ rok:'2014', title:'Taśmy Wprost — ministrowie Tuska nagrywani w restauracjach',
desc:'"Taśmy Wprost" — stenogramy i nagrania spotkań ministrów: Sikorski poniżał Polskę wobec USA i oferował wasalstwo w zamian za tarczę. Belka oferował polityczne sterowanie NBP. Rostowski kpił z suwerenności kraju.' },
{ rok:'2014', title:'Tusk ucieka do Brukseli — opuszcza Polskę w środku kadencji',
desc:'We wrześniu 2014 r. Tusk porzucił stanowisko Premiera RP w połowie kadencji, aby zostać Przewodniczącym Rady Europejskiej. Polska wyborcza oddała mu mandat — on zamienił go na europejski fotel.' },
{ rok:'2023', title:'Bezprawne przejęcie TVP, Polskiego Radia i PAP',
desc:'Grudzień 2023 — nowy rząd Tuska siłą przejął media publiczne. Bez ustawy sejmowej, mimo decyzji sądów i TK. Wystawiono kwity dla swoich ludzi. Pracownicy zwalniani nocą przez nowych prezesów-nominatów.' },
{ rok:'2023', title:'Afera wizowa — polskie wizy za łapówki',
desc:'Koalicja rządząca Tuska uwikłana w aferę wizową. Urzędnicy MSZ sprzedawali polskie wizy pracownikom z Azji i Afryki za łapówki. Tysiące nielegalnych wiz. Bezpieczeństwo granic RP naruszone.' },
{ rok:'2024', title:'KPO — miliardy z UE za ideologię, nie za reformy',
desc:'Rząd Tuska "odblokował" KPO płacąc cenę ideologiczną: zmiany w wymiarze sprawiedliwości narzucone przez Brukselę. Polska dostała pieniądze, ale oddała suwerenność prawną na warunkach Berlina i Komisji.' },
{ rok:'2024', title:'Naruszenia Konstytucji — TK orzeka, Tusk ignoruje',
desc:'Trybunał Konstytucyjny wielokrotnie orzekał niezgodność działań rządu Tuska z Konstytucją RP. Premier publicznie oświadczył, że wyroki TK "nie istnieją". Precedens bezprawia na najwyższym szczeblu państwa.' },
];
function todaySeed() {
const d = new Date();
return d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate();
}
function dailyShuffle(arr, seed) {
const a = [...arr];
let s = seed >>> 0;
for (let i = a.length - 1; i > 0; i--) {
s = (Math.imul(s, 1664525) + 1013904223) >>> 0;
const j = s % (i + 1);
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
const RESET_ROSJA = [
{ rok:'2007', title:'Odejście od polityki wschodniej PiS — koniec wsparcia dla Ukrainy i Gruzji',
desc:'Rząd Tuska zerwał z polityką aktywnego wspierania prozachodnich aspiracji Ukrainy i Gruzji. Koniec "dyplomacji prometeuszowej" — Polska przestała być adwokatem wschodnich sąsiadów w UE.' },
{ rok:'2008', title:'Brak reakcji na wojnę rosyjsko-gruzińską — Polska milczy',
desc:'Sierpień 2008: Rosja napadła na Gruzję. Polska pod Tuskiem ograniczyła się do dyplomatycznych słów. Brak realnego nacisku na UE. Tusk nie pojechał do Tbilisi jak Kaczyński — nie ryzykował drażnienia Kremla.' },
{ rok:'2008', title:'Zamrożenie rozmów o tarczy antyrakietowej USA',
desc:'Tusk przejął negocjacje ws. tarczy od rządu Kaczyńskiego i je spowolnił. Pod presją Rosji zmienił warunki umowy. Ostatecznie podpisał okrojoną wersję — bez pełnej ochrony terytorium Polski.' },
{ rok:'2009', title:'Prywatna kolacja z Putinem — Sopot, bez protokołu',
desc:'Grudzień 2009: Tusk i Putin przez kilka godzin rozmawiali sam na sam w Grand Hotelu w Sopocie. Żadnego tłumacza, żadnego protokołu, żadnych ministrów. Treść rozmowy nieznana. Następny dzień — wielka konferencja prasowa o "nowym otwarciu".' },
{ rok:'2010', title:'Katastrofa smoleńska — Tusk oddaje śledztwo Rosji',
desc:'10 kwietnia 2010: w Smoleńsku ginie Prezydent RP wraz z 95 osobami. Tusk w ciągu 48 godzin zgadza się, aby rosyjska komisja MAK prowadziła główne śledztwo. Wrak TU-154M, czarne skrzynki i szczątki ofiar przez miesiące w rękach Kremla.' },
{ rok:'2010', title:'Przyjął rosyjski raport MAK — zamiast polskiego śledztwa',
desc:'Rząd Tuska uznał raport rosyjskiej komisji MAK za miarodajny dokument ws. katastrofy smoleńskiej. Raport obwiniał polskich pilotów. Polska nie kwestionowała rosyjskich procedur śledczych ani metod badania miejsca katastrofy.' },
{ rok:'2010', title:'Wizy dla Rosjan ułatwione — turystyka i biznes bez przeszkód',
desc:'2010 r.: rząd Tuska wprowadził ułatwienia wizowe dla obywateli Rosji. Polska otworzyła się na rosyjskich turystów i biznesmenów — bez analizy ryzyka szpiegowskiego i bez wzajemności dla Polaków jadących do Rosji.' },
{ rok:'20102014', title:'Brak sprzeciwu wobec Nord Stream 1 — gaz z Rosji ważniejszy',
desc:'Nord Stream 1 był budowany w latach 20102011. Polska oficjalnie protestowała, ale Tusk nie uczynił z tego warunku w stosunkach z Niemcami i nie lobbował skutecznie w UE. Gazociąg uruchomiono — Polska ominięta.' },
{ rok:'2011', title:'Uruchomienie Nord Stream 1 — bez polskiego weta',
desc:'Wrzesień 2011: uruchomiono Nord Stream 1. Niemcy i Rosja świętują. Polska mogła użyć swojej pozycji w UE i NATO do zablokowania projektu wcześniej — zamiast tego rząd Tuska wydał "symboliczny protest" i zaakceptował fakt dokonany.' },
{ rok:'2011', title:'Brak budowy terminalu LNG — Polska uzależniona od Kremla',
desc:'Terminal LNG w Świnoujściu był planowany od lat, ale budowa postępowała opieszale za Tuska. Polska przez cały ten czas importowała ponad 70% gazu z Rosji po cenach dyktowanych przez Gazprom. PiS dokończyło terminal.' },
{ rok:'20122014', title:'Redukcja armii — gdy Rosja się zbroi, Polska się rozbraja',
desc:'Lata 20122014: budżet MON cięty, pułki rozwiązywane, sprzęt niereperowany. Tusk wiedział o rosyjskich zbrojeniach po 2008 r. — mimo to konsekwentnie redukował polskie siły zbrojne. Polska była bezbronna wobec agresji.' },
];
const MAP_MARKERS = [
{ type:'putin', lat:54.441, lng:18.560, city:'Sopot, Polska',
year:'2009', color:'#ef4444',
title:'Prywatna kolacja TuskPutin',
desc:'Grudzień 2009. Premier Tusk i Władimir Putin spędzili kilka godzin sam na sam w Grand Hotelu Sopot. Bez tłumacza, bez protokołu dyplomatycznego. "Nowe otwarcie" w stosunkach z Kremlem — na warunkach Putina.',
img:'img/tusk_putin_sopot.jpg' },
{ type:'putin', lat:55.752, lng:37.616, city:'Moskwa, Rosja',
year:'2010', color:'#ef4444',
title:'Wizyta Tuska po Smoleńsku — oddanie śledztwa',
desc:'Kwiecień 2010. Po katastrofie smoleńskiej Tusk udał się do Moskwy i zgodził na rosyjskie prowadzenie śledztwa. Wrak samolotu, czarne skrzynki i ciała ofiar trafiły w ręce Kremla. Putin "osobiście nadzorował pomoc".',
img:'img/tusk_putin.jpg' },
{ type:'putin', lat:54.760, lng:32.045, city:'Smoleńsk / Katyń, Rosja',
year:'2010', color:'#ef4444',
title:'Uroczystość katyńska — dzień przed katastrofą',
desc:'7 kwietnia 2010. Tusk uczestniczył w uroczystości zorganizowanej przez Putina pod Katyniem. Nazajutrz samolot z Prezydentem Lechem Kaczyńskim rozbił się pod Smoleńskiem. Tusk nie leciał tym samolotem.',
img:'img/tusk_putin.jpg' },
{ type:'merkel', lat:52.516, lng:13.388, city:'Berlin, Niemcy',
year:'2008', color:'#f59e0b',
title:'Pierwsze spotkanie TuskMerkel — "bliski sojusz"',
desc:'2008 r. Pierwsza oficjalna wizyta Tuska u Merkel po objęciu funkcji premiera. Merkel wyraziła "pełne wsparcie". Uzgodniono współpracę energetyczną. Nord Stream 1 był już na etapie planowania — Polska nie zgłosiła weta.',
img:null },
{ type:'merkel', lat:52.229, lng:21.012, city:'Warszawa, Polska',
year:'2010', color:'#f59e0b',
title:'Merkel w Warszawie — Nord Stream bez sprzeciwu',
desc:'2010 r. Wizyta Merkel w Warszawie. Nord Stream 1 był już w budowie — ominął Polskę i Ukrainę jako kraje tranzytowe. Tusk nie uczynił z tego punktu spornego. Polska gospodarczo uzależniona od Niemiec.',
img:null },
{ type:'merkel', lat:50.846, lng:4.352, city:'Bruksela, Belgia',
year:'20072014', color:'#f59e0b',
title:'Szczyty UE — Polska jako "junior partner" Niemiec',
desc:'Wielokrotne szczyty Rady Europejskiej. Tusk konsekwentnie głosował zgodnie z Berlinem — w sprawach energetyki, imigracji i relacji z Rosją. Polska traktowana jako satelita polityki Niemiec.',
img:null },
{ type:'nordstream', lat:60.415, lng:28.578, city:'Portovaya Bay, Rosja',
year:'2010', color:'#3b82f6',
title:'Start NS1 — rosyjski terminal kompresorowy',
desc:'Stacja kompresorowa Portovaya Bay koło Wyborga — punkt startowy Nord Stream 1 (i 2). Budowa NS1 ruszyła w 2010 r. za zgodą Niemiec i przy bierności rządu Tuska. Rurociąg ominął Polskę, Ukrainę i kraje bałtyckie.',
img:null },
{ type:'nordstream', lat:54.130, lng:13.665, city:'Lubmin, Niemcy',
year:'2011 / 2022', color:'#3b82f6',
title:'Terminal odbiorczy NS1 i NS2 — Lubmin',
desc:'Lubmin koło Greifswaldu — terminal końcowy obu nitek Nord Stream. NS1 uruchomiono w 2011 r., NS2 ukończono w 2022 r. Niemcy stały się centralnym dystrybutorem — i zakładnikiem — rosyjskiego gazu dla całej Europy.',
img:null },
// ── Sikorski–Ławrow ──
{ type:'sikorski-ru', lat:55.792, lng:37.600, city:'Moskwa, Rosja',
year:'2008', color:'#a855f7',
title:'Sikorski leci do Moskwy po wojnie gruzińskiej',
desc:'Sierpień 2008. Po rosyjskiej inwazji na Gruzję minister Sikorski jako jeden z pierwszych zachodnich dyplomatów pojechał do Moskwy na spotkanie z Ławrowem. Zamiast solidarności z Gruzją — "dialog z agresorem". Kreml odnotował brak konsekwencji.',
img:'img/sikorski.jpg' },
{ type:'sikorski-ru', lat:55.700, lng:37.500, city:'Moskwa, Rosja',
year:'2010', color:'#a855f7',
title:'Sikorski–Ławrow po katastrofie smoleńskiej',
desc:'Kwiecień–maj 2010. Sikorski wielokrotnie spotykał się z Ławrowem w sprawie śledztwa smoleńskiego. Zamiast domagać się zwrotu wraku i czarnych skrzynek — przyjmował rosyjskie "zapewnienia" i prosił o "współpracę". Wrak do dziś w Rosji.',
img:'img/sikorski.jpg' },
{ type:'sikorski-ru', lat:52.245, lng:21.025, city:'Warszawa, Polska',
year:'2009', color:'#a855f7',
title:'Ławrow z wizytą w Warszawie — "normalizacja"',
desc:'2009 r. Siergiej Ławrow złożył oficjalną wizytę w Warszawie. Sikorski zorganizował przyjęcie dyplomatyczne i podpisał wspólne deklaracje o "partnerstwie strategicznym". Polska otwierała drzwi — Rosja wchodziła i nic w zamian nie dawała.',
img:'img/sikorski.jpg' },
{ type:'sikorski-ru', lat:40.714, lng:-74.006, city:'Nowy Jork, USA',
year:'20082014', color:'#a855f7',
title:'Sikorski–Ławrow na sesjach ONZ',
desc:'Co roku podczas Zgromadzenia Ogólnego ONZ Sikorski spotykał się z Ławrowem na marginesie obrad. Regularny dialog "bez warunków wstępnych" — Polska nie wymagała od Rosji żadnych działań ws. energetyki, granic czy praw człowieka.',
img:'img/sikorski.jpg' },
// ── SikorskiNiemcy ──
{ type:'sikorski-de', lat:52.530, lng:13.380, city:'Berlin, Niemcy',
year:'2014', color:'#eab308',
title:'SikorskiSteinmeier — list ws. Majdanu',
desc:'Luty 2014. Sikorski wspólnie z Steinmeierem (Niemcy) i Fabius (Francja) wynegocjował porozumienie z Janukowyczem na Majdanie. Dokument dawał Janukowyczowi czas — Rosjanie przez ten czas sprowadzili siły. Porozumienie legło w gruzach w 24 godziny.',
img:'img/sikorski.jpg' },
{ type:'sikorski-de', lat:50.455, lng:30.523, city:'Kijów, Ukraina',
year:'2014', color:'#eab308',
title:'Sikorski na Majdanie — "broker" kompromisu z Janukowyczem',
desc:'21 lutego 2014. Sikorski sygnował porozumienie MajdanJanukowycz. Nagranie z tego dnia — Sikorski mówił protestującym: "jeśli nie podpiszecie, będziecie martwi". Porozumienie umożliwiło Janukowyczowi ucieczkę do Rosji.',
img:'img/sikorski.jpg' },
{ type:'sikorski-de', lat:48.143, lng:11.580, city:'Monachium, Niemcy',
year:'20102014', color:'#eab308',
title:'Monachijska Konferencja Bezpieczeństwa — Sikorski z Niemcami',
desc:'Co roku Sikorski uczestniczył w MSC, gdzie zacieśniał relacje z politykami CDU/SPD. Jego słynna przemowa "Polska i niemcy" (Berlin Policy Speech 2011): "Niemcy muszą przejąć przywództwo w Europie — bardziej obawiam się niemieckiej bezczynności niż działania". Polska prosi Berlin o dominację.',
img:'img/sikorski.jpg' },
{ type:'sikorski-de', lat:52.516, lng:13.388, city:'Berlin, Niemcy',
year:'2011', color:'#eab308',
title:'"Berlin Policy Speech" — Sikorski prosi Niemcy o przywództwo',
desc:'Listopad 2011. Sikorski wygłosił słynne przemówienie w Berlinie: "Polska chce, żeby Niemcy przejęły przywództwo w Europie". Jako minister polskiego rządu publicznie oddał prymarstwto Berlina — ku zdziwieniu całej dyplomacji europejskiej.',
img:'img/sikorski.jpg' },
// ── Schetyna i inni politycy PO ──
{ type:'po-de', lat:52.516, lng:13.405, city:'Berlin, Niemcy',
year:'2015', color:'#eab308',
title:'SchetynaGabriel — zależność koalicji od SPD',
desc:'2015 r. Grzegorz Schetyna jako minister spraw zagranicznych regularnie konsultował polską politykę z Sigmarem Gabrielem (SPD, wicekanclerzem Niemiec). Koalicja rządząca Tuska/Kopacz traktowała Berlin jako głównego sojusznika — nie Waszyngton.',
img:'img/schetyna.jpg' },
{ type:'po-de', lat:50.846, lng:4.370, city:'Bruksela, Belgia',
year:'2014', color:'#eab308',
title:'KopaczJuncker — polska premierka w rękach Brukseli',
desc:'2014 r. Premier Ewa Kopacz przyjęła politykę Junckerowej Komisji jako priorytety polskiego rządu. Polska zaakceptowała przymusowe kwoty relokacyjne migrantów forsowane przez Niemcy i Brukselę — wbrew interesowi Polaków.',
img:'img/kopacz.jpg' },
];
const NS_ROUTE = [
[60.415, 28.578],[59.800, 25.500],[58.900, 22.000],[57.800, 19.500],
[56.800, 18.200],[55.600, 16.000],[55.100, 14.800],[54.500, 13.900],[54.130, 13.665]
];
function loadLeaflet(cb) {
if (window.L) { cb(); return; }
const s = document.createElement('script');
s.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
s.crossOrigin = '';
s.onload = cb;
document.head.appendChild(s);
}
function initTuskMap() {
loadLeaflet(() => {
const el = document.getElementById('tusk-map');
if (!el || el._leaflet_id) return;
const map = L.map('tusk-map', { zoomControl: true, scrollWheelZoom: false })
.setView([56.5, 18.0], 4);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap © CARTO', subdomains: 'abcd', maxZoom: 14
}).addTo(map);
// Pipeline route
L.polyline(NS_ROUTE, { color:'#3b82f6', weight:4, opacity:0.8, dashArray:'8,4' })
.addTo(map)
.bindTooltip('Rurociąg Nord Stream 1 & 2 — 1224 km przez Bałtyk', { sticky: true, className:'ns-tip' });
// Markers
MAP_MARKERS.forEach(m => {
const typeLabels = { putin:'Spotkanie z Putinem', merkel:'Spotkanie z Merkel', nordstream:'Nord Stream' };
const imgHtml = m.img
? `<img class="map-pop-img" src="${m.img}" alt="">`
: `<div class="map-pop-img" style="display:flex;align-items:center;justify-content:center;color:#4b5563;font-size:1.8rem">${m.type==='nordstream'?'🔵':'📍'}</div>`;
const descColor = m.type==='merkel' ? 'y' : m.type==='nordstream' ? 'g' : '';
const popHtml = `<div class="map-pop">
${imgHtml}
<div class="map-pop-year" style="color:${m.color}">${m.year} · ${m.city}</div>
<div class="map-pop-title">${m.title}</div>
<div class="map-pop-desc ${descColor}">${m.desc}</div>
</div>`;
const icon = L.divIcon({
className: '',
html: `<div style="width:18px;height:18px;border-radius:50%;background:${m.color};border:3px solid #fff;box-shadow:0 0 10px ${m.color}88;cursor:pointer"></div>`,
iconSize: [18, 18], iconAnchor: [9, 9]
});
L.marker([m.lat, m.lng], { icon })
.addTo(map)
.bindPopup(popHtml, { maxWidth: 260 });
});
});
}
function renderTuskPortrait() {
const shuffled = dailyShuffle(TUSK_FAIL_POOL, todaySeed());
const daily = shuffled.slice(0, 6);
const repNews = allArticles
.filter(a => a.sourceId === 'republika')
.sort((a, b) => b.pubDate - a.pubDate)
.slice(0, 6);
const today = new Date().toLocaleDateString('pl-PL', {weekday:'long', year:'numeric', month:'long', day:'numeric'});
const failCards = daily.map(f => `
<div class="tusk-fail-card">
<div class="tfc-cat">${f.icon} ${f.cat}</div>
<div class="tfc-title">${escHtml(f.title)}</div>
<div class="tusk-col-label red">▼ Tusk:</div>
<div class="tusk-fail-col tusk-col-tusk">${escHtml(f.tusk)}</div>
<hr class="tusk-fail-divider">
<div class="tusk-col-label green">▲ PiS:</div>
<div class="tusk-fail-col tusk-col-pis">${escHtml(f.pis)}</div>
</div>`).join('');
const resetCards = RESET_ROSJA.map(r => `
<div class="reset-card">
<div class="reset-year">☭ ${escHtml(r.rok)}</div>
<div class="reset-title">${escHtml(r.title)}</div>
<div class="reset-desc">${escHtml(r.desc)}</div>
</div>`).join('');
const putinCards = TUSK_PUTIN_DATA.map(p => `
<div class="tusk-conn-card red">
<div class="tfc-cat">${p.icon} ${escHtml(p.rok)}</div>
<div class="tfc-title">${escHtml(p.title)}</div>
<div class="tusk-conn-desc">${escHtml(p.desc)}</div>
</div>`).join('');
const germanyCards = TUSK_GERMANY_DATA.map(g => `
<div class="tusk-conn-card yellow">
<div class="tfc-cat y">${g.icon} ${escHtml(g.rok)}</div>
<div class="tfc-title">${escHtml(g.title)}</div>
<div class="tusk-conn-desc y">${escHtml(g.desc)}</div>
</div>`).join('');
const timeline = TUSK_SCANDALS.map(s => `
<div class="tusk-tl-item">
<div class="tusk-tl-year">${escHtml(s.rok)}</div>
<div class="tusk-tl-title">${escHtml(s.title)}</div>
<div class="tusk-tl-desc">${escHtml(s.desc)}</div>
</div>`).join('');
const newsHtml = repNews.length > 0
? repNews.map(a => `<div class="tusk-news-item"><a href="${escHtml(a.link)}" target="_blank" rel="noopener">📺 ${escHtml(a.title)}</a></div>`).join('')
: '<div class="tusk-news-item" style="color:var(--muted)">Ładowanie nagłówków TV Republika...</div>';
return `
<div class="tusk-portrait">
<div class="tusk-portrait-header">
<img class="tusk-portrait-photo" src="img/tusk.jpg" alt="Donald Tusk">
<div class="tusk-portrait-intro">
<div class="tp-date">Przekaz Dnia · ${escHtml(today)}</div>
<h2>Donald Tusk — Bilans Zniszczeń</h2>
<div class="sub">Kompleksowy przegląd polityki Donalda Tuska: porażki gospodarcze, afery, powiązania z Putinem i Berlinem — w zestawieniu z osiągnięciami rządów Prawa i Sprawiedliwości (20152023). Porównanie oparte na faktach i dokumentach. 6 losowych tematów zmienia się każdego dnia.</div>
<div class="tusk-portrait-stats">
<div class="tp-stat"><div class="n">${TUSK_SCANDALS.length}</div><div class="l">Afer / skandali</div></div>
<div class="tp-stat"><div class="n">${TUSK_PUTIN_DATA.length}</div><div class="l">Powiązań z Putinem</div></div>
<div class="tp-stat"><div class="n">${TUSK_GERMANY_DATA.length}</div><div class="l">Powiązań z Niemcami</div></div>
<div class="tp-stat"><div class="n">${TUSK_FAIL_POOL.length}</div><div class="l">Udokumentowanych porażek</div></div>
</div>
</div>
</div>
<div class="tusk-section-head">🎲 Dziś na tapecie — ${escHtml(today.split(',')[0])}</div>
<div style="font-size:0.7rem;color:#fca5a5;margin-bottom:12px">◀ 6 losowych tematów z puli ${TUSK_FAIL_POOL.length} — jutro inne ▶</div>
<div class="tusk-fail-grid">${failCards}</div>
<div class="tusk-section-head">☭ Reset z Rosją — kompromitujące fakty 20072014</div>
<div class="reset-grid">${resetCards}</div>
<div class="tusk-section-head">🗺 Mapa powiązań — spotkania, Nord Stream, geopolityka</div>
<div class="map-legend">
<div class="map-legend-item"><div class="map-legend-dot" style="background:#ef4444"></div>TuskPutin</div>
<div class="map-legend-item"><div class="map-legend-dot" style="background:#f59e0b"></div>TuskMerkel</div>
<div class="map-legend-item"><div class="map-legend-dot" style="background:#a855f7"></div>Sikorski–Ławrow</div>
<div class="map-legend-item"><div class="map-legend-dot" style="background:#eab308"></div>Sikorski/PONiemcy</div>
<div class="map-legend-item"><div class="map-legend-dot" style="background:#3b82f6"></div>Nord Stream</div>
<div class="map-legend-item"><div style="width:24px;height:3px;background:#3b82f6;border-radius:2px;border:1px dashed #3b82f6"></div>Rurociąg</div>
</div>
<div id="tusk-map"></div>
<div style="font-size:0.7rem;color:var(--muted);margin-bottom:20px">Kliknij na punkt, aby zobaczyć szczegóły i zdjęcie</div>
<div class="tusk-section-head">🇷🇺 Powiązania z Putinem i Rosją — chronologia</div>
<div class="tusk-conn-grid">${putinCards}</div>
<div class="tusk-section-head yellow">🇩🇪 Powiązania z Niemcami i Berlinem — interesy ponad Polską</div>
<div class="tusk-conn-grid">${germanyCards}</div>
<div class="tusk-section-head blue">📋 Chronologia afer i skandali — cała kariera</div>
<div class="tusk-timeline">${timeline}</div>
<div class="tusk-news-strip">
<h4>📺 TV Republika — dzisiejsze doniesienia o rządzie Tuska</h4>
${newsHtml}
</div>
</div>`;
}
// ══════════════════════════════════════════════
// SEJM RP
// ══════════════════════════════════════════════
const SEJM_PARTY_COLORS = {
'PiS': '#1d4ed8',
'KO': '#f59e0b',
'PSL': '#16a34a',
'PSL-TD': '#16a34a',
'TD': '#22c55e',
'Lewica': '#dc2626',
'Razem': '#f43f5e',
'Konfederacja': '#f97316',
'Konfederacja KP': '#ea580c',
'Centrum': '#7c3aed',
'Polska2050': '#06b6d4',
'Polska2050-TD': '#0891b2',
'Demokracja': '#a78bfa',
'niez.': '#6b7280',
};
const SEJM_PARTY_ORDER = [
'PiS','Centrum','Konfederacja','Konfederacja KP','Polska2050','Polska2050-TD','PSL-TD','TD','KO','Demokracja','Lewica','Razem','niez.'
];
function normalizeClub(c) {
if (!c) return 'niez.';
c = c.trim();
if (c === 'PiS' || c.startsWith('PiS-')) return 'PiS';
if (c === 'KO' || c.startsWith('KO-')) return 'KO';
if (c.includes('Konfederacja') && (c.includes('KP') || c.includes('Korony'))) return 'Konfederacja KP';
if (c.includes('Konfederacja')) return 'Konfederacja';
if (c.includes('PSL') && c.includes('TD')) return 'PSL-TD';
if (c.includes('PSL')) return 'PSL-TD';
if (c === 'TD') return 'TD';
if (c.includes('Polska2050') && c.includes('TD')) return 'Polska2050-TD';
if (c.includes('Polska2050')) return 'Polska2050';
if (c.includes('Lewica') && !c.includes('Razem')) return 'Lewica';
if (c.includes('Razem')) return 'Razem';
if (c.includes('Centrum')) return 'Centrum';
if (c.includes('Demokracja')) return 'Demokracja';
return 'niez.';
}
function sejmPartyColor(club) {
return SEJM_PARTY_COLORS[normalizeClub(club)] || '#4b5563';
}
function genHemicycle(n) {
const seats = [];
const cx = 400, cy = 420;
const rStart = 90, rStep = 28;
const ROWS = 11;
const aMin = 5 * Math.PI / 180;
const aMax = 175 * Math.PI / 180;
const SPACING = 13.5;
let idx = 0;
for (let row = 0; row < ROWS && idx < n; row++) {
const r = rStart + row * rStep;
const arcLen = r * (aMax - aMin);
const ns = Math.min(Math.floor(arcLen / SPACING), n - idx);
const step = ns > 1 ? (aMax - aMin) / (ns - 1) : 0;
for (let i = 0; i < ns; i++) {
const angle = aMin + i * step;
seats.push({ x: cx + r * Math.cos(angle), y: cy - r * Math.sin(angle), idx: idx++ });
}
}
return seats;
}
const MINISTERS = [
{ name:'Donald Tusk', role:'Premier Rządu RP', party:'KO', img:'img/tusk.jpg',
ministry:'Kancelaria Prezesa Rady Ministrów',
desc:'Kieruje rządem i koordynuje prace Rady Ministrów. Wyznacza priorytety polityki zagranicznej, europejskiej i bezpieczeństwa państwa.' },
{ name:'Władysław Kosiniak-Kamysz', role:'Wicepremier · Minister Obrony Narodowej', party:'PSL', img:'img/kosiniakkamysz.jpg',
ministry:'Ministerstwo Obrony Narodowej',
desc:'Odpowiada za obronność i siły zbrojne RP. Nadzoruje modernizację Wojska Polskiego i realizację programu wydatków obronnych na poziomie 4% PKB.' },
{ name:'Krzysztof Gawkowski', role:'Wicepremier · Minister Cyfryzacji', party:'Lewica', img:'img/gawkowski.jpg',
ministry:'Ministerstwo Cyfryzacji',
desc:'Odpowiada za transformację cyfrową państwa, rozwój e-administracji, cyberbezpieczeństwo oraz politykę regulacyjną wobec platform cyfrowych i sztucznej inteligencji.' },
{ name:'Krzysztof Paszyk', role:'Wicepremier · Minister Rozwoju i Technologii', party:'PSL', img:'https://api.sejm.gov.pl/sejm/term10/MP/283/photo',
ministry:'Ministerstwo Rozwoju i Technologii',
desc:'Odpowiada za politykę przemysłową, handel, budownictwo i mieszkalnictwo. Nadzoruje programy wsparcia dla przedsiębiorców i rozbudowę infrastruktury.' },
{ name:'Radosław Sikorski', role:'Minister Spraw Zagranicznych', party:'KO', img:'img/sikorski.jpg',
ministry:'Ministerstwo Spraw Zagranicznych',
desc:'Kieruje polską dyplomacją. Odpowiada za relacje z UE, NATO i partnerami strategicznymi. Reprezentuje Polskę na forum międzynarodowym i nadzoruje sieć ambasad.' },
{ name:'Adam Bodnar', role:'Minister Sprawiedliwości · Prokurator Generalny', party:'bezp.', img:'img/bodnar.jpg',
ministry:'Ministerstwo Sprawiedliwości',
desc:'Odpowiada za wymiar sprawiedliwości, sądownictwo i więziennictwo. Jako Prokurator Generalny nadzoruje prokuraturę i prowadzi odbudowę praworządności.' },
{ name:'Marcin Kierwiński', role:'Minister Spraw Wewnętrznych i Administracji', party:'KO', img:'img/kierwinski.jpg',
ministry:'Ministerstwo Spraw Wewnętrznych i Administracji',
desc:'Odpowiada za bezpieczeństwo wewnętrzne, Policję, Straż Graniczną, PSP oraz administrację rządową. Koordynuje ochronę granicy RP.' },
{ name:'Andrzej Domański', role:'Minister Finansów', party:'KO', img:'https://api.sejm.gov.pl/sejm/term10/MP/68/photo',
ministry:'Ministerstwo Finansów',
desc:'Odpowiada za politykę fiskalną, budżet państwa, podatki i finanse publiczne. Nadzoruje służby celno-skarbowe i realizację planu konsolidacji finansów.' },
{ name:'Izabela Leszczyna', role:'Minister Zdrowia', party:'KO', img:'https://api.sejm.gov.pl/sejm/term10/MP/212/photo',
ministry:'Ministerstwo Zdrowia',
desc:'Odpowiada za system ochrony zdrowia, NFZ i politykę lekową. Realizuje reformę psychiatrii, zwiększenie finansowania zdrowia do 7% PKB i cyfryzację służby zdrowia.' },
{ name:'Barbara Nowacka', role:'Minister Edukacji Narodowej', party:'KO', img:'img/nowacka.jpg',
ministry:'Ministerstwo Edukacji Narodowej',
desc:'Odpowiada za system edukacji: szkoły, programy nauczania i wynagrodzenia nauczycieli. Nadzoruje kuratorów oświaty i Centralną Komisję Egzaminacyjną.' },
{ name:'Sławomir Nitras', role:'Minister Sportu i Turystyki', party:'KO', img:'img/nitras.jpg',
ministry:'Ministerstwo Sportu i Turystyki',
desc:'Odpowiada za politykę sportową państwa, finansowanie sportu wyczynowego i masowego oraz infrastrukturę sportową. Nadzoruje polskie przygotowania olimpijskie.' },
{ name:'Tomasz Siemoniak', role:'Koordynator Służb Specjalnych', party:'KO', img:'img/siemoniak.jpg',
ministry:'Koordynacja Służb Specjalnych',
desc:'Koordynuje pracę służb: ABW, AW, SKW, SWW, CBA. Odpowiada za bezpieczeństwo informacyjne i kontrwywiad. Nadzoruje reformę polskich służb specjalnych.' },
{ name:'Katarzyna Kotula', role:'Minister ds. Równości', party:'Lewica', img:'img/kotula.jpg',
ministry:'Ministerstwo ds. Równości',
desc:'Odpowiada za politykę równościową: przeciwdziałanie dyskryminacji, prawa kobiet i wdrażanie dyrektyw UE w zakresie równego traktowania.' },
{ name:'Agnieszka Dziemianowicz-Bąk', role:'Minister Rodziny, Pracy i Polityki Społecznej', party:'Lewica', img:'img/dziemianowicz.jpg',
ministry:'Ministerstwo Rodziny, Pracy i Polityki Społecznej',
desc:'Odpowiada za rynek pracy, pomoc społeczną, politykę rodzinną (świadczenie 800+) oraz dialog z pracodawcami i związkami zawodowymi.' },
{ name:'Dariusz Wieczorek', role:'Minister Nauki', party:'Lewica', img:'https://api.sejm.gov.pl/sejm/term10/MP/419/photo',
ministry:'Ministerstwo Nauki',
desc:'Odpowiada za szkolnictwo wyższe, badania naukowe, NCN, NCBiR i politykę innowacyjności. Nadzoruje finansowanie uczelni i internacjonalizację polskiej nauki.' },
{ name:'Marcin Kulasek', role:'Minister Klimatu i Środowiska', party:'Lewica', img:'https://api.sejm.gov.pl/sejm/term10/MP/201/photo',
ministry:'Ministerstwo Klimatu i Środowiska',
desc:'Odpowiada za politykę klimatyczną, transformację energetyczną, ochronę środowiska i gospodarkę odpadami. Koordynuje budowę OZE i cele klimatyczne UE.' },
{ name:'Krzysztof Hetman', role:'Minister Funduszy i Polityki Regionalnej', party:'PSL', img:'https://api.sejm.gov.pl/sejm/term10/MP/129/photo',
ministry:'Ministerstwo Funduszy i Polityki Regionalnej',
desc:'Odpowiada za zarządzanie funduszami UE (KPO, fundusze strukturalne) i politykę spójności. Nadzoruje dystrybucję miliardów euro z budżetu unijnego.' },
{ name:'Marek Sawicki', role:'Minister Rolnictwa i Rozwoju Wsi', party:'PSL', img:'https://api.sejm.gov.pl/sejm/term10/MP/326/photo',
ministry:'Ministerstwo Rolnictwa i Rozwoju Wsi',
desc:'Odpowiada za politykę rolną, dopłaty bezpośrednie, KRUS i relacje z rolnikami. Negocjuje warunki polskiego rolnictwa w ramach Wspólnej Polityki Rolnej UE.' },
{ name:'Dariusz Klimczak', role:'Minister Infrastruktury', party:'PSL', img:'https://api.sejm.gov.pl/sejm/term10/MP/162/photo',
ministry:'Ministerstwo Infrastruktury',
desc:'Odpowiada za transport drogowy, kolejowy, lotniczy i morski. Nadzoruje budowę autostrad, modernizację kolei i CPK — Centralny Port Komunikacyjny.' },
];
let _sejmMPs = null;
async function renderSejmPage() {
const container = document.getElementById('feed-container');
container.innerHTML = `<div class="sejm-page"><div class="sejm-hemicycle-wrap"><div class="sejm-loading">⏳ Ładowanie danych posłów z API Sejmu RP...</div></div></div>`;
if (!_sejmMPs) {
try {
const res = await fetch('https://api.sejm.gov.pl/sejm/term10/MP');
_sejmMPs = await res.json();
} catch(e) {
container.innerHTML = `<div class="sejm-page"><div class="sejm-hero"><div class="sejm-hero-title">⚠️ Błąd API Sejmu</div><div class="sejm-hero-sub">Nie udało się pobrać danych posłów. Sprawdź połączenie z internetem.</div></div></div>`;
return;
}
}
const mps = _sejmMPs;
const total = mps.length;
const normalized = mps.map(mp => ({...mp, _club: normalizeClub(mp.club)}));
const counts = {};
normalized.forEach(mp => { counts[mp._club] = (counts[mp._club] || 0) + 1; });
const orderMap = {};
SEJM_PARTY_ORDER.forEach((p, i) => orderMap[p] = i);
normalized.sort((a, b) => {
const oa = orderMap[a._club] ?? 99;
const ob = orderMap[b._club] ?? 99;
if (oa !== ob) return oa - ob;
return (a.lastName || '').localeCompare(b.lastName || '', 'pl');
});
const seats = genHemicycle(total);
const svgW = 800, svgH = 440;
const circleR = 5;
const circles = normalized.map((mp, i) => {
if (i >= seats.length) return '';
const {x, y} = seats[i];
const col = sejmPartyColor(mp.club);
return `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${circleR}" fill="${col}" stroke="rgba(0,0,0,0.4)" stroke-width="0.5" data-idx="${i}" style="cursor:pointer"/>`;
}).join('');
const presentParties = SEJM_PARTY_ORDER.filter(p => counts[p]);
const legend = presentParties.map(p => `
<div class="sejm-legend-item">
<div class="sejm-legend-dot" style="background:${SEJM_PARTY_COLORS[p] || '#4b5563'}"></div>
<span>${p}</span>
<span class="sejm-legend-count">(${counts[p] || 0})</span>
</div>`).join('');
const partyBadgeColor = {KO:'#92400e', PSL:'#14532d', Lewica:'#7f1d1d', 'bezp.':'#374151'};
const ministerCards = MINISTERS.map(m => `
<div class="minister-card">
<img class="minister-photo" src="${escHtml(m.img)}" alt="${escHtml(m.name)}" onerror="this.onerror=null;this.style.background='var(--border)'">
<div class="minister-info">
<div class="minister-name">${escHtml(m.name)}</div>
<div class="minister-role">${escHtml(m.role)}</div>
<div class="minister-ministry">${escHtml(m.ministry)}</div>
<div class="minister-desc">${escHtml(m.desc)}</div>
<span class="minister-party-badge" style="background:${partyBadgeColor[m.party]||'#374151'}">${escHtml(m.party)}</span>
</div>
</div>`).join('');
const coalitionCount = (counts['KO']||0)+(counts['PSL-TD']||0)+(counts['TD']||0)+(counts['Lewica']||0)+(counts['Razem']||0)+(counts['Polska2050']||0)+(counts['Polska2050-TD']||0);
container.innerHTML = `
<div class="sejm-page">
<div class="sejm-hero">
<div class="sejm-hero-date">X kadencja · od 13 listopada 2023</div>
<div class="sejm-hero-title">⚖️ Sejm Rzeczypospolitej Polskiej</div>
<div class="sejm-hero-sub">Sejm RP liczy 460 posłów wybieranych w wyborach proporcjonalnych na 4-letnią kadencję. Aktualnie w X kadencji zasiada <strong>${total}</strong> posłów reprezentujących ${presentParties.length} ugrupowań.</div>
<div class="sejm-stats">
<div class="sejm-stat"><div class="n">${total}</div><div class="l">Posłów</div></div>
<div class="sejm-stat"><div class="n">${presentParties.length}</div><div class="l">Ugrupowań</div></div>
<div class="sejm-stat"><div class="n">${counts['PiS']||0}</div><div class="l">PiS</div></div>
<div class="sejm-stat"><div class="n">${coalitionCount}</div><div class="l">Koalicja rządząca</div></div>
<div class="sejm-stat"><div class="n">${counts['Konfederacja']||0}</div><div class="l">Konfederacja</div></div>
</div>
</div>
<div class="sejm-section-title">🏛 Rozkład mandatów — X kadencja Sejmu RP</div>
<div class="sejm-hemicycle-wrap">
<svg id="sejm-hemi-svg" class="sejm-svg" viewBox="0 0 ${svgW} ${svgH}" width="${svgW}" height="${svgH}" xmlns="http://www.w3.org/2000/svg">
<rect width="${svgW}" height="${svgH}" fill="#1a1d27" rx="10"/>
<path d="M 38 420 A 362 362 0 0 1 762 420" fill="none" stroke="#2e334d" stroke-width="1.5" stroke-dasharray="5,5"/>
<text x="400" y="412" text-anchor="middle" font-size="11" fill="#4b5563" font-family="sans-serif">MÓWNICA</text>
${circles}
</svg>
<div class="sejm-legend">${legend}</div>
<div style="font-size:0.72rem;color:var(--muted);text-align:center;margin-top:6px">Najedź myszką na siedzenie, aby zobaczyć posła · Partie ułożone od prawej (PiS) do lewej (Razem)</div>
</div>
<div class="sejm-section-title">🏛 Rada Ministrów — Rząd Donalda Tuska (od 13 XII 2023)</div>
<div class="minister-grid">${ministerCards}</div>
</div>`;
const svg = document.getElementById('sejm-hemi-svg');
const tip = document.getElementById('sejm-tooltip');
if (!svg || !tip) return;
svg.addEventListener('mousemove', e => {
const el = e.target;
if (el.tagName !== 'circle') { tip.style.display = 'none'; return; }
const i = +el.dataset.idx;
const mp = normalized[i];
if (!mp) { tip.style.display = 'none'; return; }
el.setAttribute('r', circleR + 2);
document.getElementById('sejm-tip-img').src = `https://api.sejm.gov.pl/sejm/term10/MP/${mp.id}/photo`;
document.getElementById('sejm-tip-name').textContent = mp.firstLastName || (mp.firstName + ' ' + mp.lastName);
const clubEl = document.getElementById('sejm-tip-club');
clubEl.textContent = mp._club;
clubEl.style.background = sejmPartyColor(mp.club);
clubEl.style.color = '#fff';
document.getElementById('sejm-tip-dist').textContent = mp.districtName ? 'okr. ' + mp.districtName : '';
tip.style.display = 'block';
tip.style.left = Math.min(e.clientX + 14, window.innerWidth - 210) + 'px';
tip.style.top = Math.max(e.clientY - 80, 8) + 'px';
});
svg.addEventListener('mouseleave', () => {
tip.style.display = 'none';
svg.querySelectorAll('circle[data-idx]').forEach(c => c.setAttribute('r', circleR));
});
svg.addEventListener('mouseout', e => {
if (e.target.tagName === 'circle') e.target.setAttribute('r', circleR);
});
}
// ══════════════════════════════════════════════
// FILTER
// ══════════════════════════════════════════════
function filterBy(src) {
currentFilter = src;
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.toggle('active', btn.dataset.src === src);
});
renderFeed();
}
// ══════════════════════════════════════════════
// HELPERS
// ══════════════════════════════════════════════
function setDot(id, state) {
const el = document.getElementById(id);
if (!el) return;
el.className = 'status-dot ' + (state === 'ok' ? 'dot-ok' : state === 'err' ? 'dot-err' : 'dot-loading');
}
function setBtn(loading) {
const btn = document.getElementById('refresh-btn');
btn.classList.toggle('loading', loading);
btn.textContent = loading ? '↻ Ładowanie…' : '↻ Odśwież';
}
function stripHtml(html) {
const tmp = document.createElement('div');
tmp.innerHTML = html;
return (tmp.textContent || tmp.innerText || '').replace(/\s+/g, ' ').trim().slice(0, 320);
}
function extractImg(html) {
const m = html.match(/<img[^>]+src=["']([^"']+)["']/i);
return m ? m[1] : null;
}
function escHtml(str) {
if (!str) return '';
return String(str)
.replace(/&/g,'&amp;')
.replace(/</g,'&lt;')
.replace(/>/g,'&gt;')
.replace(/"/g,'&quot;');
}
function timeAgo(date) {
const diff = Math.round((Date.now() - date) / 60000);
if (diff < 1) return 'przed chwilą';
if (diff < 60) return `${diff} min temu`;
if (diff < 1440)return `${Math.round(diff/60)} godz. temu`;
return `${Math.round(diff/1440)} dni temu`;
}
// ══════════════════════════════════════════════
// RADIO STATUS
// ══════════════════════════════════════════════
function initRadio(audioId, statusId) {
const audio = document.getElementById(audioId);
const status = document.getElementById(statusId);
if (!audio || !status) return;
audio.addEventListener('playing', () => {
status.style.background = '#16a34a';
status.textContent = '▶ GRA';
});
audio.addEventListener('error', () => {
status.style.background = '#6b7280';
status.textContent = 'BŁĄD';
});
audio.addEventListener('waiting', () => {
status.style.background = '#d97706';
status.textContent = 'BUFOR...';
});
audio.addEventListener('pause', () => {
status.style.background = 'rgba(255,255,255,0.2)';
status.textContent = 'NA ŻYWO';
});
}
// ══════════════════════════════════════════════
// INIT
// ══════════════════════════════════════════════
loadAll();
initRadio('audio-maryja', 'rm-status');
initRadio('audio-republika', 'rr-status');
// Auto-refresh every 10 minutes
setInterval(loadAll, 10 * 60 * 1000);
// ══════════════════════════════════════════════
// POLITICIAN POPUP
// ══════════════════════════════════════════════
const POL_DATA = {
nawrocki: {
name: 'Karol Nawrocki',
role: 'Kandydat na Prezydenta RP',
img: 'img/nawrocki.jpg',
tag: '⭐ Kandydat Narodu',
desc: 'Karol Nawrocki to prawdziwy syn polskiej ziemi — historyk, patriota i dyrektor IPN, który całe życie poświęcił odkłamywaniu historii i obronie polskiej suwerenności. Jako niezależny kandydat na Prezydenta RP stanowi mur obronny przed planami Tuska i Brukseli. Nawrocki walczy o to, by Polska pozostała wolna, katolicka i suwerenna — nie podporządkowana dyktatowi unijnych biurokratów. Bóg · Honor · Ojczyzna!'
},
czarnek: {
name: 'Przemysław Czarnek',
role: 'Poseł PiS · b. Minister Edukacji i Nauki',
img: 'img/czarnek.jpg',
tag: '🛡 Obrońca polskiej szkoły',
desc: 'Przemysław Czarnek to jeden z najodważniejszych polityków prawicy — prawnik, profesor i człowiek głębokiej wiary. Jako minister edukacji bezlitośnie walczył z lewacką ideologizacją szkół, bronił polskich dzieci przed indoktrynacją LGBT i chronił tradycyjną rodzinę. Dziś w Sejmie jest głosem rozsądku przeciwko destrukcyjnej polityce rządu Tuska. Czarnek nie milczy — mówi prawdę wprost, nawet gdy media głównego nurtu go atakują.'
},
trump: {
name: 'Donald Trump',
role: 'Prezydent Stanów Zjednoczonych (47.)',
img: 'img/trump.jpg',
tag: '🇺🇸 Sojusznik Polski',
desc: 'Donald Trump to największy sojusznik wolnej Polski na arenie międzynarodowej. To on naciskał na zwiększenie wydatków na obronność w NATO, to on traktatem z PiS wzmacniał tarczę Patriot i obecność wojsk USA w Polsce. Trump walczy z globalistyczną elitą, otwartymi granicami i lewacką cenzurą — dokładnie tak jak polska prawica. Make America Great Again to ten sam duch, co Polska Wielki Projekt!'
},
kaczynski: {
name: 'Jarosław Kaczyński',
role: 'Prezes Prawa i Sprawiedliwości',
img: 'img/kaczynski.jpg',
tag: '🦅 Twórca polskiej prawicy',
desc: 'Jarosław Kaczyński to polityczny geniusz i moralny kręgosłup polskiej prawicy. To on wybudował nowoczesną Polskę — 500+, trzynasta i czternasta emerytura, bezpłatne leki dla seniorów, Polska Strefa Inwestycji. Przez 8 lat rządów PiS Polska rozwijała się szybciej niż kiedykolwiek. Dziś Kaczyński niezłomnie prowadzi opozycję, demaskując każdy bezprawny krok rządu Tuska i broniąc Konstytucji, którą Tusk łamie każdego dnia.'
},
blaszczak: {
name: 'Mariusz Błaszczak',
role: 'Wiceprezes PiS · Szef Klubu PiS · b. Minister Obrony',
img: 'img/blaszczak.jpg',
tag: '⚔️ Budowniczy polskiej armii',
desc: 'Mariusz Błaszczak jako minister obrony zbudował najsilniejszą armię lądową w Unii Europejskiej. To dzięki niemu Polska ma 300 tysięcy żołnierzy, czołgi K2 i Abrams, myśliwce F-35, systemy Patriot i Himars. W Sejmie jako szef klubu PiS jest prawą ręką Kaczyńskiego i żelazną pięścią opozycji — codziennie demaskuje kłamstwa i niekompetencję rządu Tuska, który roztrwania dorobek wojskowy Polski.'
},
ziobro: {
name: 'Zbigniew Ziobro',
role: 'Europoseł · b. Minister Sprawiedliwości',
img: 'img/ziobro.jpg',
tag: '⚖️ Strażnik praworządności',
desc: 'Zbigniew Ziobro to niezłomny obrońca polskiej praworządności i suwerenności sądownictwa. Jako minister sprawiedliwości walczył z korupcją i przestępczością zorganizowaną, reformując sądy pełne układów postkomunistycznych. Dziś jako europoseł stoi na straży polskich interesów w Brukseli i głośno sprzeciwia się dyktaturze Tuska, który bezprawnie przejął media i prokuratury. Ziobro nie boi się żadnych nacisków — mówi prawdę, choć kosztuje go to wolność polityczną.'
},
};
(function initPolPopup() {
const popup = document.createElement('div');
popup.id = 'pol-popup';
popup.innerHTML = `
<img class="pp-photo" id="pp-photo" src="" alt="">
<div class="pp-body">
<div class="pp-name" id="pp-name"></div>
<div class="pp-role" id="pp-role"></div>
<div class="pp-desc" id="pp-desc"></div>
<span class="pp-tag" id="pp-tag"></span>
</div>`;
document.body.appendChild(popup);
let hideTimer = null;
function showPopup(card, data) {
clearTimeout(hideTimer);
document.getElementById('pp-photo').src = data.img;
document.getElementById('pp-name').textContent = data.name;
document.getElementById('pp-role').textContent = data.role;
document.getElementById('pp-desc').textContent = data.desc;
document.getElementById('pp-tag').textContent = data.tag;
const rect = card.getBoundingClientRect();
const popW = 320;
const margin = 10;
let left = rect.left - popW - margin;
if (left < margin) left = rect.right + margin;
let top = rect.top;
const maxTop = window.innerHeight - popup.offsetHeight - margin;
top = Math.max(margin, Math.min(top, maxTop));
popup.style.left = left + 'px';
popup.style.top = top + 'px';
popup.classList.add('visible');
}
function hidePopup() {
hideTimer = setTimeout(() => popup.classList.remove('visible'), 120);
}
document.querySelectorAll('.politician-card[data-pol]').forEach(card => {
const key = card.dataset.pol;
const data = POL_DATA[key];
if (!data) return;
card.addEventListener('mouseenter', () => showPopup(card, data));
card.addEventListener('mouseleave', hidePopup);
});
})();
// ══════════════════════════════════════════════
// SMOLEŃSK TOOLTIP SYSTEM
// ══════════════════════════════════════════════
const SMOLENSK_MAP_DATA = {
warsaw: {
name: 'Lotnisko im. F. Chopina — Warszawa',
role: 'Punkt startowy delegacji · godz. ~07:27 UTC',
img: null,
tag: '✈ Start lotu',
tagColor: '#1e3a8a',
desc: 'Delegacja polska odleciała z Lotniska Okęcie w Warszawie rankiem 10 kwietnia 2010 r. Na pokładzie Tu-154M nr boczny 101 znajdowało się 96 osób: Prezydent Lech Kaczyński, Pierwsza Dama, dowódcy wszystkich rodzajów sił zbrojnych, parlamentarzyści i najwyżsi urzędnicy państwowi. Lecieli na uroczystości 70. rocznicy zbrodni katyńskiej. Planowe lądowanie: 08:30 UTC. Lot trwał ok. 62 minuty.'
},
smolensk: {
name: 'Lotnisko Siewierny — Smoleńsk',
role: 'Miejsce katastrofy · 10 IV 2010 · godz. 08:41 UTC',
img: 'img/smolensk_crash.jpg',
tag: '💥 Katastrofa',
tagColor: '#7f1d1d',
desc: 'Tu-154M rozbił się podczas podejścia do lądowania. Gęsta mgła — widzialność poniżej 400 m. Samolot zderzył się z wierzchołkami brzozy i rozpadł na polu ok. 1 km od pasa. Zginęły wszystkie 96 osób. Śledztwo MAK wskazało na błędy załogi; Komisja Macierewicza twierdzi, że doszło do zamachu z użyciem materiałów wybuchowych RDX/PETN.'
},
sopot: {
name: 'Molo w Sopocie — spotkanie Tuska z Putinem',
role: '1 września 2009 · 70. rocznica wybuchu II Wojny Światowej',
img: 'img/tusk_putin_sopot.jpg',
tag: '🤝 Tusk & Putin',
tagColor: '#7c3aed',
desc: 'Premier Donald Tusk i Premier Władimir Putin spotkali się na sopockim molo 1 września 2009 r. — w 70. rocznicę wybuchu II Wojny Światowej. Spacer po molu, uśmiechy i poufała atmosfera zaszokowały część opinii publicznej. W rok później Tusk z Putinem spotkał się ponownie — tym razem przy wraku Tu-154M w Smoleńsku. Krytycy wskazują, że obydwa spotkania symbolizują zbyt ciepłe relacje z Moskwą w przededniu i po katastrofie smoleńskiej.'
},
katyn: {
name: 'Las Katyński',
role: 'Miejsce zbrodni NKWD 1940 · ok. 22 km od Smoleńska',
img: null,
tag: '✝ Zbrodnia katyńska',
tagColor: '#374151',
desc: 'W 1940 r. NKWD zamordowało w Katyniu ok. 4 400 polskich oficerów (łącznie w całej operacji NKWD ok. 22 000 Polaków). Polska delegacja leciała właśnie na 70. rocznicę tej zbrodni. Katyń i Smoleńsk 2010 na zawsze splótł los polskich elit — najpierw wymordowanych przez Sowietów, potem tragicznie poległych jadąc uczcić ich pamięć.'
},
plane: {
name: 'Tu-154M "Bison" nr boczny 101 — Skład załogi',
role: 'Lot PLF 101 · Warszawa Okęcie → Smoleńsk Siewierny',
img: null,
tag: '✈ Załoga feralnego lotu',
tagColor: '#374151',
desc: 'Kapitan: ppłk Arkadiusz Protasiuk (36 lat, 3 500+ godz. nalotu). II Pilot: mjr Robert Grzywna. III Pilot: kpt. Artur Ziętek. Nawigator: mjr Bartłomiej Michalak. Mechanik pokładowy: chor. Andrzej Michalak. Dowódca pokładowy: płk Edmund Klich. Kontrola lotu Siewierny podawała nieprawidłowe dane o pozycji i warunki atmosferyczne — tak twierdzi komisja Macierewicza. MAK wskazuje na błędne decyzje załogi o kontynuowaniu podejścia poniżej minimów.'
}
};
const SMOLENSK_VICTIM_MAP = {};
SMOLENSK_VICTIMS.forEach(v => { SMOLENSK_VICTIM_MAP[String(v.lp)] = v; });
(function initSmolenskTooltip() {
const tip = document.createElement('div');
tip.id = 'sm-tooltip';
tip.innerHTML = `
<img class="st-photo" id="st-photo" src="" alt="">
<div class="st-photo-placeholder" id="st-placeholder">👤</div>
<div class="st-body">
<div class="st-name" id="st-name"></div>
<div class="st-role" id="st-role"></div>
<div class="st-desc" id="st-desc"></div>
<span class="st-tag" id="st-tag"></span>
</div>`;
document.body.appendChild(tip);
const elPhoto = document.getElementById('st-photo');
const elPlaceholder= document.getElementById('st-placeholder');
const elName = document.getElementById('st-name');
const elRole = document.getElementById('st-role');
const elDesc = document.getElementById('st-desc');
const elTag = document.getElementById('st-tag');
let hideTimer = null;
function showTip(anchor, data) {
clearTimeout(hideTimer);
if (data.img) {
elPhoto.src = data.img;
elPhoto.style.display = 'block';
elPlaceholder.style.display = 'none';
} else {
elPhoto.style.display = 'none';
elPlaceholder.style.display = 'flex';
}
elName.textContent = data.name;
elRole.textContent = data.role;
elDesc.textContent = data.desc;
if (data.tag) {
elTag.textContent = data.tag;
elTag.style.background = data.tagColor || '#374151';
elTag.style.color = '#fff';
elTag.style.display = 'inline-block';
} else {
elTag.style.display = 'none';
}
tip.classList.add('vis');
const rect = anchor.getBoundingClientRect();
const margin = 12;
const tipW = 340;
let left = rect.right + margin;
if (left + tipW > window.innerWidth - margin) left = rect.left - tipW - margin;
if (left < margin) left = margin;
tip.style.left = left + 'px';
const tipH = tip.offsetHeight;
let top = rect.top;
const maxTop = window.innerHeight - tipH - margin;
top = Math.max(margin, Math.min(top, maxTop));
tip.style.top = top + 'px';
}
function hideTip() {
hideTimer = setTimeout(() => tip.classList.remove('vis'), 150);
}
// Delegated hover: victim cards and table rows (data-sm = lp)
document.addEventListener('mouseover', function(e) {
const el = e.target.closest('[data-sm]');
if (el && !el.contains(e.relatedTarget)) {
const v = SMOLENSK_VICTIM_MAP[el.dataset.sm];
if (!v) return;
const tagMap = { president: ['👑 PREZYDENT RP', '#7f1d1d'], pis: ['🦅 PiS', '#1e3a8a'], mil: ['🎖 WOJSKO', '#374151'], sld: ['🔴 SLD', '#7c3aed'], other: ['', '#374151'] };
const [tag, tagColor] = tagMap[v.party] || ['', '#374151'];
showTip(el, { name: v.name, role: v.role, img: v.img || null, desc: v.desc, tag, tagColor });
}
});
document.addEventListener('mouseout', function(e) {
const el = e.target.closest('[data-sm]');
if (el && !el.contains(e.relatedTarget)) hideTip();
});
// Map markers (data-sm-map = key)
document.addEventListener('mouseover', function(e) {
const el = e.target.closest('[data-sm-map]');
if (el && !el.contains(e.relatedTarget)) {
const data = SMOLENSK_MAP_DATA[el.dataset.smMap];
if (data) showTip(el, data);
}
});
document.addEventListener('mouseout', function(e) {
const el = e.target.closest('[data-sm-map]');
if (el && !el.contains(e.relatedTarget)) hideTip();
});
// Tu-154 component markers (data-tu = key)
const TU_DATA = {
fuselage: { name:'Kadłub (fuselage) Tu-154M', role:'Główna struktura samolotu', tag:'🛩 Konstrukcja', tagColor:'#374151', img:null,
desc:'Aluminiowa konstrukcja kadłuba Tu-154M o długości 47,9 m. Grubość poszycia 1,2-2,0 mm aluminium. Komisja Macierewicza twierdzi, że na nagraniu CVR słyszalne są wybuchy wewnątrz kadłuba przed uderzeniem w ziemię. Wrak do dziś przetrzymywany jest na rosyjskim lotnisku w Smoleńsku.' },
left_wing: { name:'Lewe skrzydło', role:'💣 Domniemane miejsce ładunku nr 1 (wg komisji Macierewicza)', tag:'🔴 Rzekomy ładunek', tagColor:'#7f1d1d', img:null,
desc:'Komisja Macierewicza twierdzi, że na lewym skrzydle znajdował się ładunek wybuchowy klasy RDX/PETN, który eksplodował w trakcie lotu. Analiza spectrogramu nagrań CVR wykazuje anomalie akustyczne 8 sekund przed katastrofą. Niezależni biegli lotniczy kwestionują tę tezę — wskazują na zderzenie z drzewem jako przyczynę oderwania skrzydła.' },
right_wing: { name:'Prawe skrzydło', role:'Skrzydło wg oficjalnego raportu — bez uszkodzeń od wybuchu', tag:'✅ Bez domniemanego ładunku', tagColor:'#065f46', img:null,
desc:'Prawe skrzydło nie było przedmiotem tez o ładunkach wybuchowych. Raport MAK wskazuje, że samolot utracił stabilność po zderzeniu lewego skrzydła z drzewem i przeszedł w fazę lotu z przechyleniem — w wyniku czego rozbił się.' },
vstab: { name:'Statecznik pionowy (vertical stabilizer)', role:'Fiński element ogonowy · silnik środkowy S2', tag:'🛩 Silnik środkowy', tagColor:'#374151', img:null,
desc:'Pionowy statecznik Tu-154M o wysokości ok. 11 m. Przez kanał w stateczniku biegnie wlot środkowego silnika D-30KU (silnik nr 2). W T-tail design, na szczycie statecznika zamontowany jest poziomy statecznik. Statecznik służy jako kręgosłup całego układu ogonowego.' },
hstab_l: { name:'Poziomy statecznik lewy', role:'Układ sterowania wysokością', tag:'🛩 T-tail', tagColor:'#374151', img:null,
desc:'Tu-154 posiada T-tail (ogon w kształcie litery T) — poziome stateczniki zamontowane są na szczycie statecznika pionowego. To rozwiązanie poprawia aerodynamikę i zmniejsza zakłócenia od skrzydła. W T-tail istnieje ryzyko zjawiska "deep stall" przy ekstremalnych kątach natarcia.' },
hstab_r: { name:'Poziomy statecznik prawy', role:'Układ sterowania wysokością', tag:'🛩 T-tail', tagColor:'#374151', img:null,
desc:'Prawy statecznik poziomy Tu-154M. Lot PLF 101 zakończył się w momencie gdy przy ekstremalnie niskiej wysokości piloci próbowali podciągnąć samolot po zderzeniu z brzozą — stateczniki nie zdążyły wygenerować wystarczającego momentu.' },
engine_l: { name:'Silnik lewy (nr 1) — D-30KU-154', role:'Boczny silnik turbowentylatorowy, lewa strona', tag:'⚙️ Silnik nr 1', tagColor:'#374151', img:null,
desc:'Silnik Sołowiow D-30KU-154 — turbowentylator o ciągu startowym 104 kN. Tu-154M ma trzy identyczne silniki: dwa boczne (nr 1 i nr 3) i środkowy (nr 2) przez statecznik. Wszystkie trzy pracowały normalnie do momentu uderzenia — co potwierdza zarówno raport MAK jak i komisja Macierewicza.' },
engine_r: { name:'Silnik prawy (nr 3) — D-30KU-154', role:'Boczny silnik turbowentylatorowy, prawa strona', tag:'⚙️ Silnik nr 3', tagColor:'#374151', img:null,
desc:'Prawy silnik boczny (nr 3). Silniki D-30KU mogą pracować przy kącie natarcia do 20°. Prędkość w chwili uderzenia wynosiła ok. 260 km/h — silniki pracowały. Nie ma dowodów na awarie silników jako przyczynę katastrofy.' },
engine_c: { name:'Silnik środkowy (nr 2) — przez statecznik', role:'Centralny silnik turbowentylatorowy', tag:'⚙️ Silnik nr 2', tagColor:'#374151', img:null,
desc:'Środkowy silnik D-30KU przebiega przez kanał w stateczniku pionowym — charakterystyczna cecha Tu-154. Wlot powietrza na górze kadłuba, wylot gazów za statecznikiem. Ta konfiguracja redukuje hałas w kabinie pasażerów.' },
nose: { name:'Nos samolotu — kabina pilotów', role:'💣 Domniemane miejsce ładunku nr 2 (wg komisji)', tag:'🔴 Rzekomy ładunek', tagColor:'#7f1d1d', img:null,
desc:'Komisja Macierewicza wskazuje, że drugi ładunek wybuchowy mógł znajdować się w nosowej części samolotu — w pobliżu kabiny pilotów. Teza opiera się na analizie rozrzutu szczątków na polu katastrofy. MAK i KBWLLP wskazują na wypadek spowodowany zderzeniem z drzewem — bez dowodów na ładunek w nosie.' },
bomb1: { name:'💣 Domniemany ładunek nr 1 — lewe skrzydło', role:'Teza komisji Macierewicza — NIEUDOWODNIONA', tag:'🔴 Teza komisji', tagColor:'#7f1d1d', img:null,
desc:'Komisja twierdzi, że ładunek RDX/PETN umieszczony w korze lewego skrzydła eksplodował w locie, powodując jego oderwanie. Dowody: analiza spektrogramu CVR (dr hab. Nowaczyk), symulacje CFD (prof. Binienda). Kontrargument: niezależni biegli wskazują, że anomalie akustyczne odpowiadają zderzeniu z drzewem, nie eksplozji.' },
bomb2: { name:'💣 Domniemany ładunek nr 2 — sekcja nosowa', role:'Teza komisji Macierewicza — NIEUDOWODNIONA', tag:'🔴 Teza komisji', tagColor:'#7f1d1d', img:null,
desc:'Drugi domniemany ładunek miał znajdować się w nosowej części samolotu lub podłodze kabiny pilotów. Komisja wskazuje na anomalie w analizie rozrzutu szczątków — część elementów nosowych znaleziono daleko od głównego miejsca katastrofy. Niezależni eksperci wskazują, że jest to normalne przy katastrofach lotniczych tego typu.' },
birch: { name:'🌳 "Pancerna brzoza" — miejsce uderzenia', role:'Oficjalna przyczyna katastrofy wg MAK i KBWLLP', tag:'🟠 Zderzenie z drzewem', tagColor:'#92400e', img:null,
desc:'Brzozy na obrzeżach lotniska Siewierny (wys. ok. 5-6 m) zderzył się z lewym skrzydłem Tu-154M. Uderzenie ścięło ok. 4 m zewnętrznej części skrzydła. Samolot stracił stateczność i się rozbił. Komisja Macierewicza kwestionuje to ustalenie nazywając drzewo "pancerną brzozą" — twierdzi, że tak kruche drzewo nie mogłoby oderwać skrzydła samolotu bez wcześniejszego osłabienia przez wybuch.' }
};
document.addEventListener('mouseover', function(e) {
const el = e.target.closest('[data-tu]');
if (el && !el.contains(e.relatedTarget)) {
const data = TU_DATA[el.dataset.tu];
if (data) showTip(el, data);
}
});
document.addEventListener('mouseout', function(e) {
const el = e.target.closest('[data-tu]');
if (el && !el.contains(e.relatedTarget)) hideTip();
});
})();
// ══════════════════════════════════════════════
// SMOLEŃSK COUNTDOWN TIMER
// ══════════════════════════════════════════════
(function initCountdown() {
const CRASH = new Date('2010-04-10T08:41:00Z').getTime();
let rafId = null;
function update() {
const el = document.getElementById('sm-countdown');
if (!el) { rafId = null; return; }
const diff = Date.now() - CRASH;
const ms = diff % 1000;
const ts = Math.floor(diff / 1000);
const sec = ts % 60;
const tm = Math.floor(ts / 60);
const min = tm % 60;
const th = Math.floor(tm / 60);
const hrs = th % 24;
const td = Math.floor(th / 24);
const yrs = Math.floor(td / 365.2425);
const rem = td - Math.floor(yrs * 365.2425);
const mths = Math.floor(rem / 30.44);
const days = Math.floor(rem % 30.44);
el.innerHTML =
`<span class="cd-unit"><span class="cd-n">${yrs}</span><span class="cd-l">lat</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit"><span class="cd-n">${mths}</span><span class="cd-l">mies.</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit"><span class="cd-n">${days}</span><span class="cd-l">dni</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit"><span class="cd-n">${String(hrs).padStart(2,'0')}</span><span class="cd-l">godz.</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit"><span class="cd-n">${String(min).padStart(2,'0')}</span><span class="cd-l">min.</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit"><span class="cd-n">${String(sec).padStart(2,'0')}</span><span class="cd-l">sek.</span></span>` +
`<span class="cd-sep">·</span>` +
`<span class="cd-unit cd-ms"><span class="cd-n">${String(ms).padStart(3,'0')}</span><span class="cd-l">ms</span></span>`;
rafId = requestAnimationFrame(update);
}
// Start when Smolensk tab is shown; restart on tab switch
const origFilter = window.filterBy;
window.filterBy = function(src) {
origFilter(src);
if (src === 'smolensk') {
if (!rafId) update();
} else {
if (rafId) { cancelAnimationFrame(rafId); rafId = null; }
}
};
// In case smolensk is the initial tab
if (typeof currentFilter !== 'undefined' && currentFilter === 'smolensk') update();
})();
</script>
<!-- ══ TUSK NEWS TICKER (bottom) ══ -->
<div class="tusk-ticker-bar">
<div class="tusk-ticker-channel">
<img src="img/republika.jpg" alt="TV Republika" onerror="this.style.opacity='0.4'">
</div>
<div class="tusk-ticker-scroll">
<div class="tusk-ticker-inner" id="tusk-ticker-inner">
<span style="color:#475569;font-size:0.7rem;padding:0 20px">Pobieranie wiadomości…</span>
</div>
</div>
</div>
<script>
// ── DYNAMIC DATA FROM BACKEND ──────────────────────────────────────────────
// Converts /api/party/<slug> response to the tree format used by renderTree()
function apiToTree(data) {
const dt = data.desc_type || 'merit';
const L = data.leader || {};
const tree = {
name: L.name || '', role: L.role || '',
img: L.img || null,
married: L.married || false, children: L.children || 0, religious: L.religious || false,
sections: [],
};
tree[L.desc_type || dt] = L.description || '';
tree.sections = (data.sections || []).map(sec => ({
label: sec.label,
members: (sec.members || []).map(m => {
const node = {
name: m.name, role: m.role || '',
img: m.img || null, initials: m.initials || null, bg: m.bg || null,
married: m.married || false, children: m.children || 0, religious: m.religious || false,
};
node[m.desc_type || dt] = m.description || '';
return node;
}),
}));
return tree;
}
// Load party data from DB — overrides hardcoded KKP_TREE / KONFEDERACJA_TREE on success
fetch('/api/party/kkp')
.then(r => r.json())
.then(d => { KKP_TREE = apiToTree(d); if (currentFilter === 'kkp') renderFeed(); })
.catch(() => {});
fetch('/api/party/konfederacja')
.then(r => r.json())
.then(d => { KONFEDERACJA_TREE = apiToTree(d); if (currentFilter === 'konf') renderFeed(); })
.catch(() => {});
// ── SEAMLESS TICKER ENGINE ────────────────────────────────────────────────
const _tickerRAF = {};
function startSeamlessTicker(id, pxPerSec) {
const el = document.getElementById(id);
if (!el) return;
el.style.animation = 'none';
if (_tickerRAF[id]) cancelAnimationFrame(_tickerRAF[id]);
let pos = 0, last = null;
function tick(ts) {
if (last !== null) {
pos -= pxPerSec * (ts - last) / 1000;
const half = el.scrollWidth / 2;
if (half > 0 && pos <= -half) pos += half;
el.style.transform = `translateX(${pos}px)`;
}
last = ts;
_tickerRAF[id] = requestAnimationFrame(tick);
}
_tickerRAF[id] = requestAnimationFrame(tick);
}
// ── POLITICIAN TICKER (fetches from /api/politicians) ──────────────────────
(function initPolTicker() {
function buildItem(pol) {
const img = pol.img_path || pol.img || '';
const name = pol.name || '';
const quote = pol.quote || '';
return `<span class="pol-ticker-item">` +
`<img src="${img}" onerror="this.style.display='none'" alt="${escHtml(name)}">` +
`<span class="pol-ticker-text">` +
`<span class="pol-ticker-name">${escHtml(name)}</span>` +
`<span class="pol-ticker-quote">„${escHtml(quote)}"</span>` +
`</span></span>` +
`<span class="pol-ticker-sep">🦅</span>`;
}
function render(pols) {
const inner = document.getElementById('pol-ticker-inner');
if (!inner || !pols.length) return;
const html = pols.map(buildItem).join('');
inner.innerHTML = html + html;
startSeamlessTicker('pol-ticker-inner', 65);
}
fetch('/api/politicians?ticker=1')
.then(r => r.json())
.then(pols => { if (pols.length) render(pols); })
.catch(() => { startSeamlessTicker('pol-ticker-inner', 65); });
})();
// ── TUSK NEWS TICKER ──
(function initTuskTicker() {
function fmtDate(s) {
if (!s) return '';
const d = new Date(s);
if (isNaN(d)) return s.slice(0, 10);
const p = n => String(n).padStart(2, '0');
return `${d.getDate()}.${p(d.getMonth()+1)}.${d.getFullYear()} ${p(d.getHours())}:${p(d.getMinutes())}`;
}
function buildTicker(items) {
const inner = document.getElementById('tusk-ticker-inner');
if (!inner) return;
if (!items.length) {
inner.innerHTML = '<span style="color:#475569;font-size:0.9rem;padding:0 20px">Brak wiadomości</span>';
return;
}
const html = items.map(it =>
`<span class="tusk-ticker-news">` +
`<span class="tusk-tt-title">${it.title}</span>` +
`</span><span class="tusk-tt-sep" style="padding:0 20px;color:rgba(255,255,255,0.4);font-size:1.4rem">—</span>`
).join('');
inner.innerHTML = html + html;
startSeamlessTicker('tusk-ticker-inner', 110);
}
fetch('/api/feeds?groups=republika')
.then(r => r.json())
.then(data => {
const all = Object.values(data).flatMap(g => g.items || []);
const tusk = all.filter(it =>
/tusk/i.test((it.title || '') + ' ' + (it.summary || ''))
);
buildTicker(tusk.length ? tusk : all.slice(0, 20));
})
.catch(() => {
const inner = document.getElementById('tusk-ticker-inner');
if (inner) inner.innerHTML = '<span style="color:#475569;font-size:0.7rem;padding:0 20px">Błąd połączenia z TV Republika</span>';
});
})();
// ── SIDEBAR DYNAMIC POSITION ──────────────────────────────────────────────
(function initSidebarPos() {
const sidebar = document.querySelector('.sidebar');
const filters = document.querySelector('.filters');
if (!sidebar || !filters) return;
let raf = null;
const HEADER_H = 132;
function update() {
raf = null;
const bottom = filters.getBoundingClientRect().bottom;
const top = Math.max(HEADER_H, Math.round(bottom));
sidebar.style.top = top + 'px';
sidebar.style.height = 'calc(100vh - ' + top + 'px)';
}
function onScroll() { if (!raf) raf = requestAnimationFrame(update); }
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', update);
update();
})();
</script>
</body>
</html>