<!DOCTYPE html>
<html lang="pl" class="page">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
    <meta name="theme-color" content="#2563eb">
    <title>Chmura Rodzinna</title>
    <link rel="canonical" href="https://www.chmura.eu.org/">
    <link rel="icon" href="/favicon.ico" sizes="any">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="/winston.css">
    <style>
        /* bazowe (overriden przez chmura) */
        body { display: flex; flex-direction: column; min-height: 100vh; }
        .wrapper { width: 100%; max-width: 1400px; margin: 0 auto; padding: 0 1.5rem; }
        main { flex-grow: 1; width: 100%; }
            /* Chmura — modern photo gallery overrides PTG-owy post-list design */

        /* Reset width wrapper - PTG ma max-width: 1000px, my chcemy 1400px dla gridu */
        .wrapper { max-width: 1400px !important; }

        /* Body bg - jaśniejszy, mniej body.frame fioletowy border (PTG ma 18px solid #7b16ff) */
        body { background: #f8f9fa; }
        body.frame { border: none !important; }

        /* Header - sticky, cień */
        .header {
            background: #ffffff;
            padding: 1.25rem 0;
            margin-bottom: 2rem;
            box-shadow: 0 1px 3px rgba(0,0,0,0.05);
            position: sticky;
            top: 0;
            z-index: 50;
        }
        .header-brand { gap: 0.75rem; }
        .header-logo {
            font-size: 1.5rem !important;
            font-weight: 700;
            color: #2563eb !important;
            text-decoration: none;
            text-transform: none !important;
            letter-spacing: -0.02em;
        }
        .header-tagline { color: #6b7280 !important; font-size: 0.875rem; }

        /* Hamburger - ukryty (nie potrzebujemy mobile menu w galerii) */
        .hamburger-trigger, .menu-main, .menu-main-mobile { display: none !important; }

        /* Main - usunięcie padding-top PTG */
        main { padding-top: 0; }

        /* Footer - uproszczony */
        .footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 4rem;
            padding: 1.5rem 0;
            border-top: 1px solid #e5e7eb;
            background: #ffffff;
            color: #6b7280;
            font-size: 0.875rem;
        }
        .footer ul { display: flex; gap: 0.5rem; align-items: center; }
        .footer small { color: #6b7280; }
        .auth-toggle { font-size: 1.1rem; opacity: 0.6; }

        /* PHOTO GRID - masonry-like, 2/3/4/5 columns responsive */
        .photo-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
            gap: 1rem;
        }
        @media (min-width: 600px) { .photo-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.25rem; } }
        @media (min-width: 900px) { .photo-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.5rem; } }

        /* Photo card - kwadrat, hover effect, cień */
        .photo-card {
            position: relative;
            overflow: hidden;
            border-radius: 12px;
            background: #e5e7eb;
            aspect-ratio: 1 / 1;
            box-shadow: 0 1px 3px rgba(0,0,0,0.08);
            transition: transform 0.2s ease, box-shadow 0.2s ease;
        }
        .photo-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 24px rgba(0,0,0,0.12);
        }
        .photo-card img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
            transition: transform 0.3s ease;
        }
        .photo-card:hover img { transform: scale(1.04); }
        .photo-card .caption {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 1.5rem 0.75rem 0.5rem;
            background: linear-gradient(transparent, rgba(0,0,0,0.75));
            color: white;
            font-size: 0.875rem;
            line-height: 1.3;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.2s;
        }
        .photo-card:hover .caption { opacity: 1; }
        .photo-card .date {
            position: absolute;
            top: 0.5rem;
            right: 0.5rem;
            background: rgba(0,0,0,0.65);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            color: white;
            padding: 0.2rem 0.55rem;
            border-radius: 6px;
            font-size: 0.7rem;
            font-weight: 500;
            letter-spacing: 0.01em;
        }
        .photo-card .admin-controls {
            position: absolute;
            top: 0.5rem;
            left: 0.5rem;
            display: flex;
            gap: 0.25rem;
            opacity: 0;
            transition: opacity 0.2s;
        }
        .photo-card:hover .admin-controls { opacity: 1; }
        .photo-card .admin-controls button {
            background: rgba(0,0,0,0.65);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            color: white;
            border: none;
            border-radius: 6px;
            padding: 0.3rem 0.5rem;
            cursor: pointer;
            font-size: 0.8rem;
        }
        .photo-card .admin-controls button.danger { background: rgba(220,38,38,0.85); }

        /* UPLOAD ZONE - duża, atrakcyjna, z animowanym tłem */
        .upload-zone {
            position: relative;
            border: 2px dashed #d1d5db;
            border-radius: 16px;
            background: linear-gradient(135deg, #fafbff 0%, #f0f4ff 100%);
            padding: 3.5rem 2rem;
            text-align: center;
            cursor: pointer;
            margin-bottom: 2rem;
            transition: all 0.2s ease;
            overflow: hidden;
        }
        .upload-zone::before {
            content: '';
            position: absolute;
            inset: 0;
            background: radial-gradient(circle at 30% 50%, rgba(37,99,235,0.08) 0%, transparent 60%);
            pointer-events: none;
        }
        .upload-zone:hover, .upload-zone.dragover {
            border-color: #2563eb;
            background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
            transform: scale(1.005);
        }
        .upload-zone.dragover { animation: pulse 1.2s ease infinite; }
        @keyframes pulse {
            0%, 100% { box-shadow: 0 0 0 0 rgba(37,99,235,0.2); }
            50% { box-shadow: 0 0 0 12px rgba(37,99,235,0); }
        }
        .upload-zone input[type=file] { display: none; }
        .upload-zone .icon {
            width: 64px;
            height: 64px;
            margin: 0 auto 1rem;
            display: block;
            opacity: 0.7;
        }
        .upload-zone .title {
            font-size: 1.25rem;
            font-weight: 600;
            color: #1f2937;
            margin-bottom: 0.5rem;
            position: relative;
        }
        .upload-zone .hint {
            color: #6b7280;
            font-size: 0.875rem;
            position: relative;
        }

        /* UPLOAD PROGRESS */
        .upload-progress {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(31,41,55,0.95);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            color: white;
            padding: 1.5rem 2rem;
            border-radius: 12px;
            z-index: 1000;
            display: none;
            align-items: center;
            gap: 0.75rem;
            font-size: 0.95rem;
            box-shadow: 0 20px 50px rgba(0,0,0,0.3);
        }
        .upload-progress.active { display: flex; }
        .upload-progress .spinner {
            width: 20px;
            height: 20px;
            border: 2px solid rgba(255,255,255,0.3);
            border-top-color: white;
            border-radius: 50%;
            animation: spin 0.7s linear infinite;
        }
        @keyframes spin { to { transform: rotate(360deg); } }

        /* EMPTY STATE - kiedy brak zdjęć */
        .empty-state {
            text-align: center;
            padding: 4rem 2rem;
            color: #6b7280;
        }
        .empty-state .icon {
            width: 80px;
            height: 80px;
            margin: 0 auto 1.5rem;
            display: block;
            opacity: 0.4;
        }
        .empty-state .title {
            font-size: 1.125rem;
            font-weight: 500;
            color: #374151;
            margin-bottom: 0.5rem;
        }
        .empty-state .hint { font-size: 0.95rem; }

        /* LIGHTBOX - full-screen modal */
        .lightbox {
            position: fixed;
            inset: 0;
            background: rgba(0,0,0,0.95);
            display: none;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            flex-direction: column;
            padding: 2rem;
        }
        .lightbox.active { display: flex; }
        .lightbox img {
            max-width: 95vw;
            max-height: 80vh;
            object-fit: contain;
            border-radius: 8px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.5);
        }
        .lightbox .caption {
            color: white;
            padding: 1rem;
            text-align: center;
            max-width: 600px;
            font-size: 0.95rem;
            line-height: 1.4;
        }
        .lightbox .close {
            position: absolute;
            top: 1rem;
            right: 1rem;
            background: rgba(255,255,255,0.1);
            color: white;
            border: none;
            width: 44px;
            height: 44px;
            border-radius: 50%;
            font-size: 1.5rem;
            cursor: pointer;
            transition: background 0.2s;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .lightbox .close:hover { background: rgba(255,255,255,0.2); }
    </head>
<body>
    <div class="wrapper">
        <header class="header">
            <div class="header-brand">
                <a class="header-logo" href="/">Chmura Rodzinna</a><small class='header-tagline'>Galeria zdjęć</small>            </div>
        </header>

        <main>
            <div class='photo-grid'><p style='text-align:center; padding:3rem; color: var(--text-color)'>Galeria jest pusta.</p></div>        </main>

        <footer class="footer">
            <small>© 2026 Chmura Rodzinna</small>
            <ul><li><a class="auth-toggle" href='/admin/login' title='Zaloguj' aria-label='Zaloguj'>🔓</a></li></ul>
        </footer>
    </div>

    <div class="lightbox" id="lightbox">
        <button class="close" id="lightbox-close" aria-label="Zamknij">&times;</button>
        <img id="lightbox-img" alt="">
        <div class="caption" id="lightbox-caption"></div>
    </div>
    <script>
    (function(){
        'use strict';

        // SVG icons (inline żeby nie było dodatkowych requestów)
        const ICON_UPLOAD = '<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>';
        const ICON_CAMERA = '<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>';

        // === Lightbox ===
        const lb = document.getElementById('lightbox');
        const lbImg = document.getElementById('lightbox-img');
        const lbCap = document.getElementById('lightbox-caption');

        document.querySelectorAll('.photo-card').forEach(card => {
            card.addEventListener('click', (e) => {
                if (e.target.closest('.admin-controls')) return;
                const img = card.querySelector('img');
                if (!img) return;
                lbImg.src = img.src;
                lbImg.alt = img.alt;
                lbCap.textContent = card.dataset.caption || '';
                lb.classList.add('active');
            });
        });

        if (lb) {
            document.getElementById('lightbox-close').addEventListener('click', () => lb.classList.remove('active'));
            lb.addEventListener('click', (e) => { if (e.target === lb) lb.classList.remove('active'); });
            document.addEventListener('keydown', (e) => { if (e.key === 'Escape') lb.classList.remove('active'); });
        }

        // === Upload zone (admin only) ===
        const zone = document.getElementById('upload-zone');
        if (zone) {
            const input = document.getElementById('file-input');
            zone.innerHTML = ICON_UPLOAD +
                '<div class="title">Przeciągnij zdjęcia tutaj</div>' +
                '<div class="hint">lub kliknij, żeby wybrać pliki · JPG, PNG, WebP, HEIC</div>';
            zone.addEventListener('click', () => input.click());
            zone.addEventListener('dragover', (e) => { e.preventDefault(); zone.classList.add('dragover'); });
            zone.addEventListener('dragleave', () => zone.classList.remove('dragover'));
            zone.addEventListener('drop', (e) => { e.preventDefault(); zone.classList.remove('dragover'); upload(e.dataTransfer.files); });
            input.addEventListener('change', (e) => upload(e.target.files));

            // Progress indicator
            const progress = document.createElement('div');
            progress.className = 'upload-progress';
            progress.innerHTML = '<div class="spinner"></div><div class="msg">Wysyłanie...</div>';
            document.body.appendChild(progress);

            async function upload(files) {
                if (!files || !files.length) return;
                const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
                let ok = 0, fail = 0;
                progress.classList.add('active');
                for (const f of files) {
                    progress.querySelector('.msg').textContent = 'Konwersja ' + f.name + '...';
                    const webp = await convertToWebP(f);
                    if (!webp) { fail++; continue; }
                    progress.querySelector('.msg').textContent = 'Wysyłanie ' + webp.name + '...';
                    const fd = new FormData();
                    fd.append('file', webp, webp.name);
                    fd.append('_csrf', csrf);
                    const res = await fetch('/admin/upload', { method: 'POST', body: fd });
                    if (res.ok) ok++; else fail++;
                }
                progress.classList.remove('active');
                if (fail === 0) {
                    window.location.reload();
                } else {
                    alert('Dodano ' + ok + ' zdjęć, ' + fail + ' nie powiodło się.');
                    window.location.reload();
                }
            }

            async function convertToWebP(file) {
                return new Promise((resolve) => {
                    const img = new Image();
                    img.onload = () => {
                        try {
                            const canvas = document.createElement('canvas');
                            const max = 1600;
                            let w = img.width, h = img.height;
                            if (w > h && w > max) { h = h * max / w; w = max; }
                            else if (h > max) { w = w * max / h; h = max; }
                            canvas.width = w; canvas.height = h;
                            const ctx = canvas.getContext('2d');
                            ctx.drawImage(img, 0, 0, w, h);
                            canvas.toBlob((blob) => {
                                if (blob) {
                                    resolve(new File([blob], file.name.replace(/\.[^.]+$/, '.webp'), { type: 'image/webp' }));
                                } else {
                                    resolve(null);
                                }
                            }, 'image/webp', 0.82);
                        } catch (e) { resolve(null); }
                    };
                    img.onerror = () => resolve(null);
                    img.src = URL.createObjectURL(file);
                });
            }
        }

        // === Empty state (gdy brak zdjęć, a nie ma upload zone - gość) ===
        const grid = document.querySelector('.photo-grid');
        if (grid && !document.querySelector('.photo-card') && !document.getElementById('upload-zone')) {
            grid.outerHTML = '<div class="empty-state">' + ICON_CAMERA + '<div class="title">Galeria jest pusta</div><div class="hint">Wróć tu później, gdy admin doda zdjęcia.</div></div>';
        }

        // === Delete photo (admin) ===
        document.querySelectorAll('[data-del-id]').forEach(b => {
            b.addEventListener('click', async (e) => {
                e.stopPropagation();
                if (!confirm('Usunąć to zdjęcie?')) return;
                const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
                const fd = new FormData();
                fd.append('id', b.dataset.delId);
                fd.append('_csrf', csrf);
                const res = await fetch('/admin/api/delete', { method: 'POST', body: fd });
                if (res.ok) window.location.reload();
                else alert('Błąd usuwania');
            });
        });
    })();
    </script>
</body>
</html>
