<?php
/**
 * Dashboard Home — ECharts-powered overview
 */
$todayShift = getShiftForDate();
$db = getDB();

$totalUsers = (int)$db->query("SELECT COUNT(*) FROM users WHERE status = 'active'")->fetchColumn();
$pendingUsers = (int)$db->query("SELECT COUNT(*) FROM users WHERE status = 'pending'")->fetchColumn();
// Incident count resets at 07:00 each day
$shiftStart = date('H') >= 7 ? date('Y-m-d 07:00:00') : date('Y-m-d 07:00:00', strtotime('-1 day'));
$recentIncidents = (int)$db->query("SELECT COUNT(*) FROM incidents_cache WHERE received_at >= '{$shiftStart}'")->fetchColumn();
$otHoursMonth = $db->query("SELECT COALESCE(SUM(hours), 0) FROM ot_records WHERE shift_date >= DATE_FORMAT(NOW(), '%Y-%m-01')")->fetchColumn();

// 7-day incident trend
$trendData = [];
for ($i = 6; $i >= 0; $i--) {
    $date = date('Y-m-d', strtotime("-{$i} days"));
    $label = date('D', strtotime($date));
    $count = (int)$db->prepare("SELECT COUNT(*) FROM incidents_cache WHERE DATE(received_at) = :d")->execute([':d' => $date]) ? (int)$db->query("SELECT COUNT(*) FROM incidents_cache WHERE DATE(received_at) = '{$date}'")->fetchColumn() : 0;
    $trendData[] = ['label' => $label, 'date' => date('M j', strtotime($date)), 'count' => $count];
}

// Recent incidents
$incidents = $db->query("SELECT * FROM incidents_cache ORDER BY received_at DESC LIMIT 8")->fetchAll();

// Today's hourly breakdown
$hourlyToday = [];
for ($h = 0; $h < 24; $h++) $hourlyToday[$h] = 0;
$todayRows = $db->query("SELECT received_at FROM incidents_cache WHERE received_at >= '{$shiftStart}'")->fetchAll();
foreach ($todayRows as $r) { $hr = (int)date('G', strtotime($r['received_at'])); $hourlyToday[$hr]++; }

// Yesterday hourly for comparison
$yesterdayStart = date('Y-m-d 07:00:00', strtotime($shiftStart . ' -1 day'));
$yesterdayEnd = $shiftStart;
$hourlyYesterday = [];
for ($h = 0; $h < 24; $h++) $hourlyYesterday[$h] = 0;
$yRows = $db->query("SELECT received_at FROM incidents_cache WHERE received_at >= '{$yesterdayStart}' AND received_at < '{$yesterdayEnd}'")->fetchAll();
foreach ($yRows as $r) { $hr = (int)date('G', strtotime($r['received_at'])); $hourlyYesterday[$hr]++; }

// Call types today
$callTypes = [];
foreach ($todayRows as $r) { /* need type */ }
$callTypeRows = $db->query("SELECT incident_type, COUNT(*) as cnt FROM incidents_cache WHERE received_at >= '{$shiftStart}' GROUP BY incident_type ORDER BY cnt DESC LIMIT 8")->fetchAll();

// 7-day heatmap
$heatmapData = [];
for ($d = 0; $d < 7; $d++) {
    for ($h = 0; $h < 24; $h++) $heatmapData[] = [$h, $d, 0];
}
$heatRows = $db->query("SELECT received_at FROM incidents_cache WHERE received_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchAll();
foreach ($heatRows as $r) {
    $dow = (int)date('w', strtotime($r['received_at']));
    $hr = (int)date('G', strtotime($r['received_at']));
    foreach ($heatmapData as &$cell) { if ($cell[0] === $hr && $cell[1] === $dow) { $cell[2]++; break; } }
    unset($cell);
}

// Yesterday total for comparison
$yesterdayTotal = count($yRows);
?>

<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

<div class="page-header">
    <h1>Dashboard</h1>
    <div class="stat-card" style="border-top-color:var(--accent); padding:10px 18px; min-width:auto;">
        <span class="stat-value" style="font-size:22px;"><?= $recentIncidents ?></span>
        <span class="stat-label">Incidents <span style="font-size:9px;background:var(--accent-light);color:var(--accent);padding:1px 6px;border-radius:8px;font-weight:600;margin-left:4px;">Today</span></span>
    </div>
</div>

<!-- Hero Story Carousel -->
<div class="story-carousel" id="storyCarousel">
    <div class="story-slides" id="storySlides">
        <div class="story-slide active" style="background:#0B2240;">
            <div class="story-content">
                <span class="story-source-badge">Loading</span>
                <h2 class="story-title">Loading stories...</h2>
            </div>
        </div>
    </div>
    <div class="story-progress"><div class="story-progress-bar" id="storyProgressBar"></div></div>
    <div class="story-dots" id="storyDots"></div>
    <button class="story-nav story-prev" id="storyPrev" aria-label="Previous">&#8249;</button>
    <button class="story-nav story-next" id="storyNext" aria-label="Next">&#8250;</button>
</div>

<style>
.story-carousel {
    position: relative;
    width: 100%;
    height: 320px;
    border-radius: var(--ios-radius);
    overflow: hidden;
    margin-bottom: 24px;
    background: var(--primary);
    box-shadow: 0 4px 20px rgba(11,34,64,0.15);
}

.story-slides { position: relative; width: 100%; height: 100%; }

.story-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 2s ease-in-out;
    background-size: cover;
    background-position: center;
    cursor: pointer;
}
.story-slide.active { opacity: 1; z-index: 2; }
.story-slide.prev { opacity: 0; z-index: 1; }

.story-slide::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        0deg,
        rgba(11, 34, 64, 0.92) 0%,
        rgba(11, 34, 64, 0.6) 35%,
        rgba(11, 34, 64, 0.15) 65%,
        rgba(11, 34, 64, 0.05) 100%
    );
}

.story-content {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 32px 40px;
    z-index: 3;
    color: #fff;
}

.story-source-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    margin-bottom: 10px;
    backdrop-filter: blur(8px);
}
.story-source-badge[data-cat="news"] { background: rgba(27,108,176,0.6); }
.story-source-badge[data-cat="sports"] { background: rgba(140,198,63,0.6); }
.story-source-badge[data-cat="events"] { background: rgba(0,166,160,0.6); }
.story-source-badge[data-cat="fire"] { background: rgba(220,38,38,0.6); }
.story-source-badge[data-cat="weather"] { background: rgba(255,152,0,0.8); }

.story-title {
    font-size: 24px;
    font-weight: 800;
    line-height: 1.25;
    color: #fff;
    text-shadow: 0 1px 4px rgba(0,0,0,0.3);
    max-width: 700px;
    letter-spacing: -0.3px;
}

.story-subtitle {
    font-size: 14px;
    color: rgba(255,255,255,0.65);
    margin-top: 6px;
    max-width: 600px;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.story-time {
    font-size: 11px;
    color: rgba(255,255,255,0.4);
    margin-top: 8px;
}

.story-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: rgba(255,255,255,0.1);
    z-index: 5;
}
.story-progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--accent), var(--highlight));
    transition: width 0.3s linear;
}

.story-dots {
    position: absolute;
    bottom: 14px;
    right: 40px;
    display: flex;
    gap: 6px;
    z-index: 5;
}
.story-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255,255,255,0.3);
    cursor: pointer;
    transition: all 0.3s;
}
.story-dot.active {
    background: #fff;
    width: 24px;
    border-radius: 4px;
}

.story-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    background: rgba(255,255,255,0.1);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(255,255,255,0.15);
    color: #fff;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    font-size: 20px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s;
}
.story-carousel:hover .story-nav { opacity: 1; }
.story-nav:hover { background: rgba(255,255,255,0.2); }
.story-prev { left: 12px; }
.story-next { right: 12px; }

@media (max-width: 768px) {
    .story-carousel { height: 260px; }
    .story-content { padding: 20px 24px; }
    .story-title { font-size: 18px; }
    .story-nav { display: none; }
}
</style>

<!-- ROW 1: Incident Activity + Weather -->
<div style="display:grid; grid-template-columns:3fr 2fr; gap:20px; margin-bottom:20px;">
    <div class="card">
        <div class="card-header">
            <h2 class="card-title">Incident Activity — Today vs Yesterday</h2>
        </div>
        <div id="homeActivityChart" style="height:240px;"></div>
    </div>
    <div class="card" id="homeWeatherCard">
        <div class="card-header"><h2 class="card-title">Weather</h2></div>
        <div id="homeWeatherDetail" style="min-height:200px;">
            <div class="skeleton skeleton-card" style="height:200px;"></div>
        </div>
    </div>
</div>

<!-- ROW 3: Call Types + Heatmap -->
<div style="display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-bottom:20px;">
    <div class="card">
        <div class="card-header"><h2 class="card-title">Call Types Today</h2></div>
        <div id="homeCallTypes" style="height:260px;"></div>
    </div>
    <div class="card">
        <div class="card-header"><h2 class="card-title">7-Day Activity Heatmap</h2></div>
        <div id="homeHeatmap" style="height:260px;"></div>
    </div>
</div>

<!-- ROW 4: Recent Incidents (clickable) -->
<div class="card">
    <div class="card-header">
        <h2 class="card-title">Recent Incidents</h2>
        <a href="dashboard.php?page=incidents" class="btn btn-sm btn-secondary">View All</a>
    </div>
    <?php if (empty($incidents)): ?>
        <div class="empty-state" style="padding:24px;">
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="var(--ios-green)" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
            <h3>No Active Incidents</h3>
            <p>All clear — no incidents reported in the last 24 hours.</p>
        </div>
    <?php else: ?>
        <div class="table-wrapper">
            <table>
                <thead><tr><th>Priority</th><th>Type</th><th>Address</th><th>Units</th><th>Time</th></tr></thead>
                <tbody>
                <?php foreach ($incidents as $inc):
                    $incJson = htmlspecialchars(json_encode([
                        'id'       => $inc['incident_id'] ?? '',
                        'type'     => $inc['incident_type'] ?? 'Unknown',
                        'address'  => $inc['address'] ?? '',
                        'city'     => $inc['city'] ?? 'Cincinnati',
                        'units'    => $inc['units_assigned'] ?? '',
                        'priority' => $inc['priority'] ?? '3',
                        'status'   => $inc['status'] ?? 'active',
                        'lat'      => $inc['latitude'] ?? null,
                        'lng'      => $inc['longitude'] ?? null,
                        'time'     => $inc['received_at'] ?? '',
                        'raw'      => null,
                    ]), ENT_QUOTES);
                ?>
                    <tr class="incident-clickable" data-incident='<?= $incJson ?>' onclick="openIncidentDetail(this)" style="cursor:pointer;">
                        <td><?php $p = $inc['priority'] ?? '3'; ?><span class="badge <?= $p == '1' ? 'badge-red' : ($p == '2' ? 'badge-orange' : 'badge-gray') ?>">P<?= htmlspecialchars($p) ?></span></td>
                        <td><strong><?= htmlspecialchars($inc['incident_type'] ?? 'Unknown') ?></strong></td>
                        <td><?= htmlspecialchars($inc['address'] ?? '') ?></td>
                        <td><?php foreach (array_filter(explode(',', $inc['units_assigned'] ?? '')) as $u): ?><span class="unit-badge"><?= htmlspecialchars(trim($u)) ?></span><?php endforeach; ?></td>
                        <td style="white-space:nowrap; color:var(--ios-secondary); font-size:13px;"><?= date('g:i A', strtotime($inc['received_at'])) ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    <?php endif; ?>
</div>

<!-- Incident Detail Modal -->
<div class="modal-overlay" id="incidentDetailModal">
    <div class="modal" style="max-width:720px; padding:0; overflow:hidden;">
        <div id="incDetailHeader" style="background:linear-gradient(135deg,#0B2240,#1B6CB0); padding:20px 24px; color:#fff;">
            <div style="display:flex; justify-content:space-between; align-items:flex-start;">
                <div>
                    <div style="display:flex; align-items:center; gap:8px; margin-bottom:6px;">
                        <span id="incDetailPriority" class="badge" style="font-size:12px;"></span>
                        <span id="incDetailStatus" style="font-size:11px; opacity:0.7; text-transform:uppercase; letter-spacing:0.5px;"></span>
                    </div>
                    <h2 id="incDetailType" style="font-size:20px; font-weight:800; margin-bottom:4px;"></h2>
                    <p id="incDetailAddress" style="font-size:14px; color:rgba(255,255,255,0.7);"></p>
                </div>
                <button onclick="closeModal('incidentDetailModal')" style="background:rgba(255,255,255,0.1); border:none; color:#fff; width:32px; height:32px; border-radius:50%; font-size:18px; cursor:pointer;">&times;</button>
            </div>
        </div>

        <div style="display:grid; grid-template-columns:1fr 1fr; border-bottom:1px solid var(--ios-border);">
            <div style="padding:14px 24px; border-right:1px solid var(--ios-border);">
                <div style="font-size:10px; text-transform:uppercase; letter-spacing:0.8px; color:var(--ios-tertiary); font-weight:600; margin-bottom:4px;">Units Assigned</div>
                <div id="incDetailUnits" style="display:flex; flex-wrap:wrap; gap:4px;"></div>
            </div>
            <div style="padding:14px 24px;">
                <div style="font-size:10px; text-transform:uppercase; letter-spacing:0.8px; color:var(--ios-tertiary); font-weight:600; margin-bottom:4px;">Time Received</div>
                <div id="incDetailTime" style="font-size:15px; font-weight:700; color:var(--primary);"></div>
                <div id="incDetailId" style="font-size:11px; color:var(--ios-tertiary); margin-top:2px;"></div>
            </div>
        </div>

        <div id="incDetailStreetView" style="height:300px; background:var(--primary); position:relative;">
            <div id="incDetailStreetViewLoading" style="position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:rgba(255,255,255,0.4); font-size:13px;">
                Loading Street View...
            </div>
        </div>

        <div style="padding:12px 24px; background:var(--ios-bg); display:flex; gap:8px; justify-content:flex-end;">
            <a id="incDetailMapsLink" href="#" target="_blank" class="btn btn-sm btn-secondary" style="text-decoration:none;">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-2px;"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
                Open in Google Maps
            </a>
            <button onclick="closeModal('incidentDetailModal')" class="btn btn-sm btn-primary">Close</button>
        </div>
    </div>
</div>

<style>
.incident-clickable:hover { background: var(--accent-light) !important; }
.incident-clickable:hover td { color: var(--primary); }
</style>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const navy = '#0B2240', blue = '#1B6CB0', teal = '#00A6A0', green = '#8CC63F', blueLight = '#5BA4D9';
    const hourLabels = Array.from({length:24},(_,i)=>i===0?'12a':i<12?i+'a':i===12?'12p':(i-12)+'p');

    // Animated count-up
    document.querySelectorAll('[data-countup]').forEach(el => {
        const target = parseFloat(el.dataset.countup);
        const dur = 1200, start = performance.now();
        const tick = (now) => { const p = Math.min((now-start)/dur,1); el.textContent = Math.round(target*(1-Math.pow(1-p,3))); if(p<1) requestAnimationFrame(tick); };
        requestAnimationFrame(tick);
    });

    // River stat (header already shows it; stat card removed)
    const riverStatEl = document.getElementById('riverStatVal');
    if (riverStatEl) window.portalAPI('river.php').then(d => { if(d&&!d.error) riverStatEl.textContent = d.level.toFixed(1); });

    // Weather detail card
    window.portalAPI('weather.php?action=forecast').then(async fc => {
        const cur = await window.portalAPI('weather.php');
        const el = document.getElementById('homeWeatherDetail');
        if (!cur || !fc) { el.innerHTML='<p style="color:var(--ios-secondary);">Unavailable</p>'; return; }
        const sunrise = new Date(cur.sunrise*1000).toLocaleTimeString('en-US',{hour:'numeric',minute:'2-digit'});
        const sunset = new Date(cur.sunset*1000).toLocaleTimeString('en-US',{hour:'numeric',minute:'2-digit'});
        el.innerHTML = `
            <div style="display:flex;align-items:center;gap:14px;margin-bottom:14px;">
                <img src="https://openweathermap.org/img/wn/${cur.icon}@2x.png" width="56" height="56">
                <div><div style="font-size:32px;font-weight:800;">${Math.round(cur.temp)}&deg;F</div><div style="font-size:13px;color:var(--ios-secondary);text-transform:capitalize;">${cur.conditions}</div></div>
            </div>
            <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:14px;">
                <div style="padding:6px;background:var(--ios-bg);border-radius:6px;text-align:center;"><div style="font-size:10px;color:var(--ios-secondary);">Feels</div><div style="font-weight:700;font-size:13px;">${Math.round(cur.feels_like)}&deg;</div></div>
                <div style="padding:6px;background:var(--ios-bg);border-radius:6px;text-align:center;"><div style="font-size:10px;color:var(--ios-secondary);">Wind</div><div style="font-weight:700;font-size:13px;">${Math.round(cur.wind_speed)}mph</div></div>
                <div style="padding:6px;background:var(--ios-bg);border-radius:6px;text-align:center;"><div style="font-size:10px;color:var(--ios-secondary);">Humidity</div><div style="font-weight:700;font-size:13px;">${cur.humidity}%</div></div>
            </div>
            <div style="display:flex;gap:6px;flex-wrap:wrap;">
                ${(fc.forecast||[]).slice(0,5).map((d,i)=>`<div style="flex:1;text-align:center;padding:6px;background:var(--ios-bg);border-radius:6px;min-width:55px;"><div style="font-size:10px;color:var(--ios-secondary);">${i===0?'Today':d.day_name}</div><img src="https://openweathermap.org/img/wn/${d.icon}.png" width="28" height="28"><div style="font-weight:700;font-size:12px;">${d.high}&deg;</div><div style="font-size:10px;color:var(--ios-tertiary);">${d.low}&deg;</div></div>`).join('')}
            </div>`;
    });

    // ─── CHART 1: Today vs Yesterday activity ────────────
    const actChart = echarts.init(document.getElementById('homeActivityChart'));
    actChart.setOption({
        tooltip:{trigger:'axis',backgroundColor:navy,textStyle:{color:'#fff'}},
        legend:{data:['Today','Yesterday'],textStyle:{color:'#5A6A7E',fontSize:11},top:0},
        grid:{top:30,right:10,bottom:24,left:36},
        xAxis:{type:'category',data:hourLabels,axisLabel:{color:'#5A6A7E',fontSize:10},axisLine:{lineStyle:{color:'#D8DEE6'}}},
        yAxis:{type:'value',minInterval:1,splitLine:{lineStyle:{color:'#F0F2F5'}},axisLabel:{color:'#5A6A7E',fontSize:10}},
        series:[
            {name:'Today',type:'line',data:<?= json_encode(array_values($hourlyToday)) ?>,smooth:true,symbol:'none',lineStyle:{width:3,color:blue},
             areaStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:'rgba(27,108,176,0.3)'},{offset:1,color:'rgba(27,108,176,0.02)'}])},
             animationDuration:1500},
            {name:'Yesterday',type:'line',data:<?= json_encode(array_values($hourlyYesterday)) ?>,smooth:true,symbol:'none',lineStyle:{width:2,color:'#D8DEE6',type:'dashed'},animationDuration:1500}
        ]
    });

    // ─── CHART 2: Call Types Today ───────────────────────
    const ctChart = echarts.init(document.getElementById('homeCallTypes'));
    const ctNames = <?= json_encode(array_reverse(array_column($callTypeRows, 'incident_type'))) ?>;
    const ctVals = <?= json_encode(array_reverse(array_map(fn($r)=>(int)$r['cnt'], $callTypeRows))) ?>;
    ctChart.setOption({
        tooltip:{trigger:'axis',axisPointer:{type:'shadow'},backgroundColor:navy,textStyle:{color:'#fff'}},
        grid:{top:4,right:40,bottom:4,left:8,containLabel:true},
        xAxis:{type:'value',show:false},
        yAxis:{type:'category',data:ctNames,axisLabel:{color:navy,fontSize:10,width:180,overflow:'truncate'},axisLine:{show:false},axisTick:{show:false}},
        series:[{type:'bar',data:ctVals,barWidth:16,itemStyle:{borderRadius:[0,6,6,0],color:new echarts.graphic.LinearGradient(0,0,1,0,[{offset:0,color:navy},{offset:1,color:blue}])},label:{show:true,position:'right',color:navy,fontWeight:700,fontSize:11},animationDelay:idx=>idx*80}]
    });

    // ─── CHART 3: 7-Day Heatmap ─────────────────────────
    const hmChart = echarts.init(document.getElementById('homeHeatmap'));
    const hmData = <?= json_encode($heatmapData) ?>;
    hmChart.setOption({
        tooltip:{position:'top',formatter:function(p){const days=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];return days[p.data[1]]+' '+hourLabels[p.data[0]]+': <b>'+p.data[2]+'</b>';}},
        grid:{left:48,right:12,top:4,bottom:32},
        xAxis:{type:'category',data:hourLabels,splitArea:{show:true},axisLabel:{color:'#5A6A7E',fontSize:9}},
        yAxis:{type:'category',data:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],splitArea:{show:true},axisLabel:{color:'#5A6A7E',fontSize:10}},
        visualMap:{min:0,max:Math.max(...hmData.map(d=>d[2]),1),calculable:false,orient:'horizontal',left:'center',bottom:0,inRange:{color:['#E8EDF3',blueLight,blue,navy]},textStyle:{color:'#5A6A7E',fontSize:10},itemWidth:10,itemHeight:60},
        series:[{type:'heatmap',data:hmData,itemStyle:{borderRadius:3},emphasis:{itemStyle:{shadowBlur:8,shadowColor:'rgba(0,0,0,0.2)'}}}]
    });

    // Responsive
    window.addEventListener('resize', () => { actChart.resize(); ctChart.resize(); hmChart.resize(); });

    // ─── Incident Detail Modal ────────────────────────────
    const mapsKey = window.CFD_PORTAL.mapsKey;
    let streetViewPano = null;

    window.openIncidentDetail = function(row) {
        const inc = JSON.parse(row.dataset.incident);

        document.getElementById('incDetailType').textContent = inc.type;
        document.getElementById('incDetailAddress').textContent = inc.address + (inc.city ? ', ' + inc.city : '');
        document.getElementById('incDetailId').textContent = 'ID: ' + inc.id;
        document.getElementById('incDetailStatus').textContent = inc.status;

        const prioEl = document.getElementById('incDetailPriority');
        prioEl.textContent = 'Priority ' + inc.priority;
        prioEl.className = 'badge ' + (inc.priority == '1' ? 'badge-red' : (inc.priority == '2' ? 'badge-orange' : 'badge-gray'));

        const unitsEl = document.getElementById('incDetailUnits');
        const units = (inc.units || '').split(',').filter(u => u.trim());
        unitsEl.innerHTML = units.length > 0
            ? units.map(u => `<span class="unit-badge">${u.trim()}</span>`).join('')
            : '<span style="color:var(--ios-tertiary); font-size:13px;">No units assigned</span>';

        const timeEl = document.getElementById('incDetailTime');
        if (inc.time) {
            const d = new Date(inc.time);
            timeEl.textContent = d.toLocaleTimeString('en-US', {hour:'numeric', minute:'2-digit'}) + ' — ' +
                d.toLocaleDateString('en-US', {weekday:'short', month:'short', day:'numeric'});
        } else {
            timeEl.textContent = 'Unknown';
        }

        // Google Maps link
        const addr = encodeURIComponent(inc.address + ', Cincinnati, OH');
        document.getElementById('incDetailMapsLink').href = `https://www.google.com/maps/search/?api=1&query=${addr}`;

        // Load Street View
        const svEl = document.getElementById('incDetailStreetView');
        const loadingEl = document.getElementById('incDetailStreetViewLoading');
        loadingEl.style.display = 'flex';
        loadingEl.textContent = 'Loading Street View...';

        openModal('incidentDetailModal');

        if (inc.lat && inc.lng && inc.lat != 0) {
            loadStreetView(parseFloat(inc.lat), parseFloat(inc.lng), svEl, loadingEl);
        } else {
            geocodeAndLoadStreetView(inc.address + ', Cincinnati, OH', svEl, loadingEl);
        }
    };

    function loadStreetView(lat, lng, container, loadingEl) {
        if (!mapsKey) {
            loadingEl.textContent = 'Maps API key not configured';
            return;
        }

        if (!window.google || !google.maps) {
            const script = document.createElement('script');
            script.src = `https://maps.googleapis.com/maps/api/js?key=${mapsKey}&callback=_svReady`;
            script.async = true;
            window._svPendingLat = lat;
            window._svPendingLng = lng;
            window._svContainer = container;
            window._svLoading = loadingEl;
            window._svReady = function() {
                loadStreetView(window._svPendingLat, window._svPendingLng, window._svContainer, window._svLoading);
            };
            document.head.appendChild(script);
            return;
        }

        loadingEl.style.display = 'none';

        const svService = new google.maps.StreetViewService();
        svService.getPanorama({ location: { lat, lng }, radius: 100 }, function(data, status) {
            if (status === google.maps.StreetViewStatus.OK) {
                if (streetViewPano) {
                    streetViewPano.setPosition(data.location.latLng);
                } else {
                    streetViewPano = new google.maps.StreetViewPanorama(container, {
                        position: data.location.latLng,
                        pov: { heading: 0, pitch: 0 },
                        zoom: 1,
                        addressControl: false,
                        showRoadLabels: true,
                    });
                }
            } else {
                loadingEl.style.display = 'flex';
                loadingEl.innerHTML = `<div style="text-align:center;">
                    <div style="margin-bottom:8px;">Street View not available</div>
                    <img src="https://maps.googleapis.com/maps/api/staticmap?center=${lat},${lng}&zoom=17&size=600x300&maptype=hybrid&markers=color:red|${lat},${lng}&key=${mapsKey}" style="width:100%;max-width:500px;border-radius:8px;">
                </div>`;
            }
        });
    }

    function geocodeAndLoadStreetView(address, container, loadingEl) {
        if (!mapsKey) {
            loadingEl.textContent = 'Maps API key not configured';
            return;
        }

        fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${mapsKey}`)
            .then(r => r.json())
            .then(data => {
                if (data.results && data.results.length > 0) {
                    const loc = data.results[0].geometry.location;
                    loadStreetView(loc.lat, loc.lng, container, loadingEl);
                } else {
                    loadingEl.textContent = 'Address not found';
                }
            })
            .catch(() => {
                loadingEl.textContent = 'Geocoding failed';
            });
    }

    // ─── Story Carousel ─────────────────────────────────
    const carousel = document.getElementById('storyCarousel');
    const slidesContainer = document.getElementById('storySlides');
    const dotsContainer = document.getElementById('storyDots');
    const progressBar = document.getElementById('storyProgressBar');
    let storyData = [];
    let currentStory = 0;
    let storyTimer = null;
    let progressTimer = null;
    let paused = false;
    const STORY_DURATION = 10000;

    async function loadStories() {
        const data = await window.portalAPI('stories.php');
        if (!data || !data.stories || data.stories.length === 0) return;
        storyData = data.stories;
        renderStories();
        startAutoplay();
    }

    function renderStories() {
        slidesContainer.innerHTML = storyData.map((s, i) => `
            <div class="story-slide ${i === 0 ? 'active' : ''}" style="background-image:url('${s.image}')" onclick="if('${s.url}')window.open('${s.url}','_blank')">
                <div class="story-content">
                    <span class="story-source-badge" data-cat="${s.category}">${escHtml(s.source)}</span>
                    <h2 class="story-title">${escHtml(s.title)}</h2>
                    ${s.subtitle ? `<p class="story-subtitle">${escHtml(s.subtitle)}</p>` : ''}
                    ${s.time ? `<div class="story-time">${timeAgoStr(s.time)}</div>` : ''}
                </div>
            </div>
        `).join('');

        dotsContainer.innerHTML = storyData.map((_, i) =>
            `<div class="story-dot ${i === 0 ? 'active' : ''}" onclick="goToStory(${i})"></div>`
        ).join('');
    }

    function goToStory(index) {
        if (index === currentStory) return;
        const slides = slidesContainer.querySelectorAll('.story-slide');
        const dots = dotsContainer.querySelectorAll('.story-dot');

        slides[currentStory]?.classList.remove('active');
        slides[currentStory]?.classList.add('prev');
        dots[currentStory]?.classList.remove('active');

        currentStory = index;
        slides[currentStory]?.classList.add('active');
        slides[currentStory]?.classList.remove('prev');
        dots[currentStory]?.classList.add('active');

        setTimeout(() => {
            slidesContainer.querySelectorAll('.prev').forEach(s => s.classList.remove('prev'));
        }, 2200);

        resetProgress();
    }

    function nextStory() { goToStory((currentStory + 1) % storyData.length); }
    function prevStory() { goToStory((currentStory - 1 + storyData.length) % storyData.length); }

    function startAutoplay() {
        resetProgress();
        storyTimer = setInterval(() => { if (!paused) nextStory(); }, STORY_DURATION);
    }

    function resetProgress() {
        progressBar.style.transition = 'none';
        progressBar.style.width = '0%';
        requestAnimationFrame(() => {
            requestAnimationFrame(() => {
                progressBar.style.transition = `width ${STORY_DURATION}ms linear`;
                progressBar.style.width = '100%';
            });
        });
    }

    carousel.addEventListener('mouseenter', () => { paused = true; progressBar.style.animationPlayState = 'paused'; });
    carousel.addEventListener('mouseleave', () => { paused = false; });

    document.getElementById('storyNext')?.addEventListener('click', (e) => { e.stopPropagation(); nextStory(); });
    document.getElementById('storyPrev')?.addEventListener('click', (e) => { e.stopPropagation(); prevStory(); });

    function timeAgoStr(dateStr) {
        if (!dateStr) return '';
        const diff = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);
        if (diff < 3600) return Math.floor(diff / 60) + ' min ago';
        if (diff < 86400) return Math.floor(diff / 3600) + 'h ago';
        return Math.floor(diff / 86400) + 'd ago';
    }

    window.goToStory = goToStory;
    loadStories();

    // ─── Slide Panel ────────────────────────────────────
    const panel = document.getElementById('slidePanel');
    const panelBody = document.getElementById('slidePanelBody');
    const tabs = document.querySelectorAll('.slide-tab');
    let panelOpen = false;
    let activeTab = null;

    tabs.forEach(tab => {
        tab.addEventListener('click', () => {
            const target = tab.dataset.panel;
            if (panelOpen && activeTab === target) {
                closePanel();
            } else {
                openPanel(target);
                tabs.forEach(t => t.classList.remove('active'));
                tab.classList.add('active');
            }
        });
    });

    document.getElementById('slidePanelClose').addEventListener('click', closePanel);

    function openPanel(tab) {
        panel.classList.add('open');
        panelOpen = true;
        activeTab = tab;
        const titles = { 'events': 'Cincinnati Events', 'cfd-today': 'CFD Today', 'council': 'City Council', 'saints': 'New Orleans Saints', 'personal': 'Off Duty' };
        document.getElementById('slidePanelTitle').textContent = titles[tab] || tab;
        loadPanelContent(tab);
    }

    function closePanel() {
        panel.classList.remove('open');
        panelOpen = false;
        activeTab = null;
        tabs.forEach(t => t.classList.remove('active'));
    }

    async function loadPanelContent(tab) {
        panelBody.innerHTML = '<div style="text-align:center;padding:40px;color:var(--ios-secondary);">Loading...</div>';

        if (tab === 'events') {
            const data = await window.portalAPI('events.php');
            if (!data || !data.events || data.events.length === 0) {
                panelBody.innerHTML = '<div style="text-align:center;padding:40px;color:var(--ios-secondary);">No upcoming events found.</div>';
                return;
            }
            panelBody.innerHTML = data.events.map(e => {
                const dateStr = e.date ? new Date(e.date + 'T12:00:00').toLocaleDateString('en-US', {weekday:'short', month:'short', day:'numeric'}) : '';
                const timeStr = e.time ? new Date('2026-01-01T' + e.time).toLocaleTimeString('en-US', {hour:'numeric', minute:'2-digit'}) : '';
                return `
                <a href="${e.url}" target="_blank" class="slide-panel-item" style="text-decoration:none;color:inherit;">
                    ${e.image ? `<img src="${e.image}" style="width:100%;height:100px;object-fit:cover;border-radius:8px;margin-bottom:8px;">` : ''}
                    <div style="font-weight:700;font-size:14px;color:var(--primary);line-height:1.3;">${escHtml(e.name)}</div>
                    <div style="font-size:12px;color:var(--ios-secondary);margin-top:4px;">
                        <span>${dateStr}</span>${timeStr ? ` &middot; <span>${timeStr}</span>` : ''}
                    </div>
                    ${e.venue ? `<div style="font-size:11px;color:var(--ios-tertiary);margin-top:2px;">${escHtml(e.venue)}</div>` : ''}
                    ${e.type ? `<span style="display:inline-block;margin-top:6px;padding:2px 8px;background:var(--accent-light);color:var(--accent);border-radius:10px;font-size:10px;font-weight:600;">${escHtml(e.type)}</span>` : ''}
                </a>`;
            }).join('');
        }

        if (tab === 'cfd-today') {
            const data = await window.portalAPI('calendar-today.php');
            if (!data || !data.events || data.events.length === 0) {
                panelBody.innerHTML = `<div style="text-align:center;padding:40px;color:var(--ios-secondary);">
                    <div style="font-size:14px;font-weight:600;margin-bottom:4px;">${data?.date || 'Today'}</div>
                    No events scheduled today.
                </div>`;
                return;
            }
            panelBody.innerHTML = `
                <div style="padding:0 0 12px;font-size:13px;font-weight:600;color:var(--primary);border-bottom:1px solid var(--ios-border);margin-bottom:12px;">${data.date}</div>
            ` + data.events.map(e => `
                <div class="slide-panel-item">
                    <div style="display:flex;align-items:flex-start;gap:10px;">
                        <div style="min-width:56px;text-align:center;padding:6px 0;">
                            <div style="font-size:12px;font-weight:700;color:var(--accent);">${escHtml(e.time || 'All Day')}</div>
                            ${e.end_time ? `<div style="font-size:10px;color:var(--ios-tertiary);">to ${escHtml(e.end_time)}</div>` : ''}
                        </div>
                        <div style="flex:1;border-left:3px solid var(--accent);padding-left:10px;">
                            <div style="font-weight:600;font-size:13px;color:var(--primary);">${escHtml(e.summary)}</div>
                            ${e.location ? `<div style="font-size:11px;color:var(--ios-secondary);margin-top:2px;">${escHtml(e.location)}</div>` : ''}
                        </div>
                    </div>
                </div>
            `).join('');
        }

        if (tab === 'council') {
            const data = await window.portalAPI('council.php');
            if (!data || !data.meetings || data.meetings.length === 0) {
                panelBody.innerHTML = '<div style="text-align:center;padding:40px;color:var(--ios-secondary);">No council meetings found.</div>';
                return;
            }

            const today = new Date().toISOString().slice(0, 10);
            const upcoming = data.meetings.filter(m => m.date >= today);
            const recent = data.meetings.filter(m => m.date < today);

            const colorMap = {
                'public-safety': '#00A6A0',
                'full-council': '#0B2240',
                'budget': '#1B6CB0',
                'housing': '#8CC63F',
                'climate': '#5B8C3E',
                'other': '#6B7280'
            };

            function relativeDate(dateStr) {
                const d = new Date(dateStr + 'T12:00:00');
                const now = new Date();
                const diffDays = Math.round((d - now) / 86400000);
                if (diffDays === 0) return 'Today';
                if (diffDays === 1) return 'Tomorrow';
                if (diffDays === -1) return 'Yesterday';
                if (diffDays > 1 && diffDays <= 6) return d.toLocaleDateString('en-US', {weekday:'long'});
                if (diffDays < -1 && diffDays >= -6) return Math.abs(diffDays) + ' days ago';
                return d.toLocaleDateString('en-US', {weekday:'short', month:'short', day:'numeric'});
            }

            function renderMeeting(m) {
                const color = colorMap[m.category] || colorMap.other;
                const isPubSafety = m.category === 'public-safety';
                const statusColors = { 'Scheduled': '#00A6A0', 'Completed': '#6B7280', 'Past': '#9CA3AF' };
                return `
                <div class="council-meeting ${m.category}" data-id="${m.id}" data-guid="${m.guid}" style="border-left-color:${color};">
                    <div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
                        <div style="font-weight:700;font-size:13px;color:var(--primary);flex:1;">${escHtml(m.name)}</div>
                        ${isPubSafety ? '<svg width="14" height="14" viewBox="0 0 24 24" fill="#00A6A0" style="flex-shrink:0;"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></svg>' : ''}
                    </div>
                    <div style="font-size:12px;color:var(--ios-secondary);margin-bottom:4px;">
                        ${relativeDate(m.date)} &middot; ${escHtml(m.time)}
                    </div>
                    ${m.location ? `<div style="font-size:11px;color:var(--ios-tertiary);margin-bottom:6px;">${escHtml(m.location)}</div>` : ''}
                    <div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap;">
                        <span style="display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:600;background:${statusColors[m.status] || '#9CA3AF'}20;color:${statusColors[m.status] || '#9CA3AF'};">${m.status}</span>
                        ${m.agendaUrl ? '<span style="font-size:10px;color:var(--accent);font-weight:600;">Agenda Available</span>' : ''}
                    </div>
                    <div class="council-agenda-expand" style="display:none;margin-top:12px;padding-top:12px;border-top:1px solid var(--ios-border);"></div>
                </div>`;
            }

            let html = '';
            if (upcoming.length) {
                html += '<div class="council-section-label">Upcoming</div>';
                html += upcoming.map(renderMeeting).join('');
            }
            if (recent.length) {
                html += '<div class="council-section-label" style="margin-top:16px;">Recent</div>';
                html += recent.map(renderMeeting).join('');
            }
            panelBody.innerHTML = html;

            // Click handler for meeting drill-down
            panelBody.querySelectorAll('.council-meeting').forEach(el => {
                el.addEventListener('click', async function() {
                    const id = this.dataset.id;
                    const guid = this.dataset.guid;
                    const expandEl = this.querySelector('.council-agenda-expand');
                    if (!id || !guid) return;

                    if (expandEl.style.display !== 'none') {
                        expandEl.style.display = 'none';
                        return;
                    }

                    expandEl.style.display = 'block';
                    expandEl.innerHTML = '<div style="font-size:12px;color:var(--ios-secondary);">Loading agenda...</div>';

                    const agendaData = await window.portalAPI('council.php?action=agenda&id=' + id + '&guid=' + guid);
                    if (!agendaData || !agendaData.items || agendaData.items.length === 0) {
                        expandEl.innerHTML = '<div style="font-size:12px;color:var(--ios-tertiary);font-style:italic;">Agenda not yet posted</div>';
                        return;
                    }

                    const typeColors = {
                        'Ordinance': { bg: '#1B6CB020', fg: '#1B6CB0' },
                        'Resolution': { bg: '#00A6A020', fg: '#00A6A0' },
                        'Motion': { bg: '#8CC63F20', fg: '#5B8C3E' },
                        'Report': { bg: '#0B224020', fg: '#0B2240' },
                        'Presentation': { bg: '#0B224020', fg: '#0B2240' },
                        'Communication': { bg: '#6B728020', fg: '#6B7280' },
                    };

                    expandEl.innerHTML = agendaData.items.map(item => {
                        const tc = typeColors[item.type] || { bg: '#6B728020', fg: '#6B7280' };
                        return `
                        <div class="council-agenda-item" ${item.fireRelevant ? 'style="background:#00A6A008;margin:0 -12px;padding-left:12px;padding-right:12px;border-left:2px solid #00A6A0;"' : ''}>
                            <div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
                                <span style="padding:1px 6px;border-radius:8px;font-size:9px;font-weight:700;background:${tc.bg};color:${tc.fg};text-transform:uppercase;">${escHtml(item.type)}</span>
                                ${item.fileNumber ? `<span style="font-size:10px;color:var(--ios-tertiary);">#${escHtml(item.fileNumber)}</span>` : ''}
                                ${item.fireRelevant ? '<svg width="12" height="12" viewBox="0 0 24 24" fill="#00A6A0"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></svg>' : ''}
                            </div>
                            <div style="font-size:11px;color:var(--primary);line-height:1.4;">${escHtml(item.description.length > 200 ? item.description.substring(0, 200) + '...' : item.description)}</div>
                        </div>`;
                    }).join('');
                });
            });
        }

        if (tab === 'saints') {
            const data = await window.portalAPI('saints.php');
            if (!data || !data.team) {
                panelBody.innerHTML = '<div style="text-align:center;padding:40px;color:var(--ios-secondary);">Unable to load Saints data.</div>';
                return;
            }

            const gold = '#d3bc8d';
            const black = '#101820';

            // Team header
            let html = `
            <div style="text-align:center;padding:0 0 16px;border-bottom:2px solid ${gold};">
                <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/New_Orleans_Saints_logo.svg/1280px-New_Orleans_Saints_logo.svg.png" style="width:64px;height:64px;object-fit:contain;margin-bottom:8px;">
                <div style="font-size:18px;font-weight:800;color:${black};">${escHtml(data.team.name)}</div>
                <div style="font-size:14px;color:${gold};font-weight:700;margin-top:2px;">${escHtml(data.team.record)}</div>
                <div style="font-size:12px;color:var(--ios-secondary);margin-top:2px;">${escHtml(data.team.standing)}</div>
            </div>`;

            // Section tabs
            html += `
            <div class="saints-section-tabs" style="display:flex;gap:0;margin:12px -20px 0;border-bottom:1px solid var(--ios-border);padding:0 20px;">
                <button class="saints-sec-tab active" data-sec="news" style="flex:1;padding:8px 4px;border:none;background:none;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;color:${black};border-bottom:2px solid ${gold};cursor:pointer;">News</button>
                <button class="saints-sec-tab" data-sec="schedule" style="flex:1;padding:8px 4px;border:none;background:none;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;color:var(--ios-tertiary);border-bottom:2px solid transparent;cursor:pointer;">Schedule</button>
                <button class="saints-sec-tab" data-sec="roster" style="flex:1;padding:8px 4px;border:none;background:none;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;color:var(--ios-tertiary);border-bottom:2px solid transparent;cursor:pointer;">Roster</button>
                <button class="saints-sec-tab" data-sec="stats" style="flex:1;padding:8px 4px;border:none;background:none;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;color:var(--ios-tertiary);border-bottom:2px solid transparent;cursor:pointer;">Stats</button>
            </div>`;

            // News section
            html += `<div class="saints-section" data-sec="news">`;
            if (data.news && data.news.length) {
                html += data.news.map(n => {
                    const ago = n.date ? timeAgo(n.date) : '';
                    return `
                    <a href="${n.url || '#'}" target="_blank" style="display:block;text-decoration:none;color:inherit;padding:12px 0;border-bottom:1px solid var(--ios-border);">
                        ${n.image ? `<img src="${n.image}" style="width:100%;height:120px;object-fit:cover;border-radius:8px;margin-bottom:8px;">` : ''}
                        <div style="font-weight:700;font-size:13px;color:${black};line-height:1.35;">${escHtml(n.headline)}</div>
                        <div style="font-size:11px;color:var(--ios-secondary);margin-top:4px;line-height:1.4;">${escHtml((n.description || '').substring(0, 120))}${(n.description || '').length > 120 ? '...' : ''}</div>
                        <div style="font-size:10px;color:var(--ios-tertiary);margin-top:4px;">${ago}</div>
                    </a>`;
                }).join('');
            } else {
                html += '<div style="padding:20px 0;text-align:center;color:var(--ios-secondary);">No news available</div>';
            }
            html += '</div>';

            // Schedule section
            html += `<div class="saints-section" data-sec="schedule" style="display:none;">`;
            if (data.games && data.games.length) {
                html += data.games.map(g => {
                    const wonClass = g.won === true ? gold : g.won === false ? '#dc2626' : 'var(--ios-tertiary)';
                    const result = g.won === true ? 'W' : g.won === false ? 'L' : '';
                    const scoreText = g.saintsScore ? `${g.saintsScore}-${g.opponentScore}` : g.status;
                    return `
                    <div style="display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--ios-border);">
                        <div style="width:36px;height:36px;flex-shrink:0;">
                            ${g.opponentLogo ? `<img src="${g.opponentLogo}" style="width:36px;height:36px;object-fit:contain;">` : `<div style="width:36px;height:36px;background:#f3f4f6;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:#6b7280;">${escHtml(g.opponentAbbr)}</div>`}
                        </div>
                        <div style="flex:1;">
                            <div style="font-weight:600;font-size:13px;color:${black};">${g.home ? 'vs' : '@'} ${escHtml(g.opponent)}</div>
                            <div style="font-size:11px;color:var(--ios-tertiary);">${escHtml(g.week)} &middot; ${escHtml(g.date)}</div>
                        </div>
                        <div style="text-align:right;">
                            ${result ? `<span style="font-weight:800;font-size:13px;color:${wonClass};">${result}</span>` : ''}
                            <div style="font-size:12px;font-weight:600;color:${black};">${escHtml(scoreText)}</div>
                        </div>
                    </div>`;
                }).join('');
            } else {
                html += '<div style="padding:20px 0;text-align:center;color:var(--ios-secondary);">Schedule not yet available</div>';
            }
            html += '</div>';

            // Roster section
            html += `<div class="saints-section" data-sec="roster" style="display:none;">`;
            if (data.roster && data.roster.length) {
                const groups = {};
                data.roster.forEach(p => {
                    const g = p.posGroup || 'Other';
                    if (!groups[g]) groups[g] = [];
                    groups[g].push(p);
                });
                const groupOrder = ['offense', 'defense', 'specialTeams'];
                const groupLabels = { offense: 'Offense', defense: 'Defense', specialTeams: 'Special Teams' };
                groupOrder.forEach(gk => {
                    const players = groups[gk];
                    if (!players || !players.length) return;
                    html += `<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;color:${gold};padding:12px 0 6px;">${groupLabels[gk] || gk}</div>`;
                    players.slice(0, 15).forEach(p => {
                        html += `
                        <div style="display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid rgba(0,0,0,0.04);">
                            <div style="width:36px;height:36px;border-radius:50%;overflow:hidden;background:#f3f4f6;flex-shrink:0;">
                                ${p.headshot ? `<img src="${p.headshot}" style="width:100%;height:100%;object-fit:cover;">` : ''}
                            </div>
                            <div style="flex:1;">
                                <div style="font-weight:600;font-size:13px;color:${black};">${p.jersey ? '#' + p.jersey + ' ' : ''}${escHtml(p.name)}</div>
                                <div style="font-size:11px;color:var(--ios-tertiary);">${escHtml(p.position)}${p.experience ? ' &middot; ' + p.experience + ' yr' + (p.experience > 1 ? 's' : '') : ''}</div>
                            </div>
                        </div>`;
                    });
                });
            } else {
                html += '<div style="padding:20px 0;text-align:center;color:var(--ios-secondary);">Roster not yet available</div>';
            }
            html += '</div>';

            // Stats section
            html += `<div class="saints-section" data-sec="stats" style="display:none;">`;
            if (data.stats && Object.keys(data.stats).length) {
                Object.entries(data.stats).forEach(([cat, statList]) => {
                    html += `<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;color:${gold};padding:12px 0 6px;">${escHtml(cat)}</div>`;
                    statList.forEach(s => {
                        html += `
                        <div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(0,0,0,0.04);">
                            <span style="font-size:12px;color:var(--ios-secondary);">${escHtml(s.name)}</span>
                            <span style="font-size:13px;font-weight:700;color:${black};">${escHtml(s.value)}</span>
                        </div>`;
                    });
                });
            } else {
                html += '<div style="padding:20px 0;text-align:center;color:var(--ios-secondary);">Stats not yet available</div>';
            }
            html += '</div>';

            panelBody.innerHTML = html;

            // Section tab switching
            panelBody.querySelectorAll('.saints-sec-tab').forEach(btn => {
                btn.addEventListener('click', function() {
                    const sec = this.dataset.sec;
                    panelBody.querySelectorAll('.saints-sec-tab').forEach(b => {
                        b.classList.remove('active');
                        b.style.color = 'var(--ios-tertiary)';
                        b.style.borderBottomColor = 'transparent';
                    });
                    this.classList.add('active');
                    this.style.color = '${black}';
                    this.style.borderBottomColor = '${gold}';
                    panelBody.querySelectorAll('.saints-section').forEach(s => s.style.display = 'none');
                    const target = panelBody.querySelector(`.saints-section[data-sec="${sec}"]`);
                    if (target) target.style.display = 'block';
                });
            });
        }

        if (tab === 'personal') {
            const data = await window.portalAPI('personal.php');
            if (!data || !data.feeds) {
                panelBody.innerHTML = '<div style="text-align:center;padding:40px;color:var(--ios-secondary);">Unable to load feed.</div>';
                return;
            }

            const catMeta = {
                hiking:  { label: 'Hiking',       emoji: '🥾', color: '#16a34a', bg: '#16a34a15' },
                bikes:   { label: 'Sport Bikes',   emoji: '🏍️', color: '#dc2626', bg: '#dc262615' },
                trikes:  { label: '3-Wheelers',    emoji: '🛞', color: '#f59e0b', bg: '#f59e0b15' },
                wutang:  { label: 'Wu-Tang Clan',  emoji: '🐝', color: '#eab308', bg: '#eab30815' },
            };

            let allPosts = [];
            Object.entries(data.feeds).forEach(([cat, posts]) => {
                posts.forEach(p => allPosts.push(p));
            });

            let activeFilter = 'all';

            function renderPersonal(filter) {
                let posts = filter === 'all'
                    ? allPosts.sort(() => Math.random() - 0.5)
                    : allPosts.filter(p => p.category === filter);

                // Wu-Tang quote banner
                let html = '';
                if (data.wuQuote) {
                    html += `
                    <div style="background:linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);border-radius:10px;padding:14px 16px;margin-bottom:14px;position:relative;overflow:hidden;">
                        <div style="position:absolute;right:10px;top:50%;transform:translateY(-50%);font-size:40px;opacity:0.15;">🐝</div>
                        <div style="font-size:12px;color:#eab308;font-style:italic;line-height:1.4;position:relative;z-index:1;">"${escHtml(data.wuQuote.text)}"</div>
                        <div style="font-size:10px;color:#d3bc8d;margin-top:6px;font-weight:700;position:relative;z-index:1;">— ${escHtml(data.wuQuote.author)}</div>
                    </div>`;
                }

                // Filter pills
                html += `<div class="personal-filters" style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px;">`;
                html += `<button class="pf-pill ${filter === 'all' ? 'active' : ''}" data-cat="all" style="padding:4px 12px;border-radius:20px;border:1px solid var(--ios-border);background:${filter === 'all' ? 'var(--primary)' : 'transparent'};color:${filter === 'all' ? '#fff' : 'var(--ios-secondary)'};font-size:11px;font-weight:600;cursor:pointer;">All</button>`;
                Object.entries(catMeta).forEach(([key, m]) => {
                    const isActive = filter === key;
                    html += `<button class="pf-pill ${isActive ? 'active' : ''}" data-cat="${key}" style="padding:4px 12px;border-radius:20px;border:1px solid ${isActive ? m.color : 'var(--ios-border)'};background:${isActive ? m.bg : 'transparent'};color:${isActive ? m.color : 'var(--ios-secondary)'};font-size:11px;font-weight:600;cursor:pointer;">${m.emoji} ${m.label}</button>`;
                });
                html += `</div>`;

                // Posts
                const displayed = posts.slice(0, 20);
                if (!displayed.length) {
                    html += '<div style="text-align:center;padding:20px;color:var(--ios-tertiary);">No posts in this category yet.</div>';
                }

                displayed.forEach(p => {
                    const m = catMeta[p.category] || catMeta.hiking;
                    const ago = timeAgo(p.created);
                    const scoreStr = p.score > 999 ? (p.score / 1000).toFixed(1) + 'k' : p.score;

                    html += `
                    <a href="${p.url || '#'}" target="_blank" style="display:block;text-decoration:none;color:inherit;padding:12px 0;border-bottom:1px solid var(--ios-border);">
                        ${p.hasImage && p.image ? `<img src="${escHtml(p.image)}" style="width:100%;height:140px;object-fit:cover;border-radius:10px;margin-bottom:8px;" onerror="this.style.display='none'" loading="lazy">` : ''}
                        <div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
                            <span style="padding:2px 8px;border-radius:12px;font-size:9px;font-weight:700;background:${m.bg};color:${m.color};text-transform:uppercase;">${m.emoji} ${m.label}</span>
                            ${p.source === 'nps' ? '<span style="padding:2px 6px;border-radius:8px;font-size:9px;font-weight:600;background:#065f4615;color:#065f46;">NPS</span>' : ''}
                        </div>
                        <div style="font-weight:700;font-size:13px;color:var(--primary);line-height:1.35;margin-bottom:4px;">${escHtml(p.title)}</div>
                        ${p.selftext ? `<div style="font-size:11px;color:var(--ios-secondary);line-height:1.4;margin-bottom:4px;">${escHtml(p.selftext.substring(0, 100))}${p.selftext.length > 100 ? '...' : ''}</div>` : ''}
                        <div style="display:flex;align-items:center;gap:10px;font-size:10px;color:var(--ios-tertiary);">
                            ${p.score ? `<span>▲ ${scoreStr}</span>` : ''}
                            ${p.comments ? `<span>💬 ${p.comments}</span>` : ''}
                            <span>r/${escHtml(p.subreddit)}</span>
                            <span>${ago}</span>
                        </div>
                    </a>`;
                });

                panelBody.querySelector('.personal-content').innerHTML = html;

                // Rebind filter pills
                panelBody.querySelectorAll('.pf-pill').forEach(btn => {
                    btn.addEventListener('click', (e) => {
                        e.preventDefault();
                        renderPersonal(btn.dataset.cat);
                    });
                });
            }

            panelBody.innerHTML = '<div class="personal-content"></div>';
            renderPersonal('all');
        }
    }

    function timeAgo(dateStr) {
        const d = new Date(dateStr);
        const now = new Date();
        const diffMs = now - d;
        const mins = Math.floor(diffMs / 60000);
        if (mins < 60) return mins + 'm ago';
        const hrs = Math.floor(mins / 60);
        if (hrs < 24) return hrs + 'h ago';
        const days = Math.floor(hrs / 24);
        if (days === 1) return 'Yesterday';
        if (days < 7) return days + 'd ago';
        return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    }

    function escHtml(s) {
        const d = document.createElement('div');
        d.textContent = s || '';
        return d.innerHTML;
    }
});
</script>

<!-- Slide Panel (right edge) -->
<div class="slide-panel-tabs" id="slidePanelTabs">
    <button class="slide-tab" data-panel="events" title="Cincinnati Events">
        <img src="https://s1.ticketm.net/en-us/img/static/mobile/23/app-t.png" width="22" height="22" alt="Events" style="object-fit:contain;">
        <span>Events</span>
    </button>
    <button class="slide-tab" data-panel="cfd-today" title="CFD Today">
        <img src="assets/img/cfd-logo.png" width="22" height="22" alt="CFD" style="object-fit:contain;">
        <span>CFD Today</span>
    </button>
    <button class="slide-tab" data-panel="council" title="City Council">
        <img src="https://pbs.twimg.com/profile_images/1995478574745161729/OHk14M5z.jpg" width="22" height="22" alt="Council" style="object-fit:cover;border-radius:50%;">
        <span>Council</span>
    </button>
    <button class="slide-tab saints-tab" data-panel="saints" title="New Orleans Saints">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/New_Orleans_Saints_logo.svg/1280px-New_Orleans_Saints_logo.svg.png" width="22" height="22" alt="Saints" style="object-fit:contain;">
        <span>Saints</span>
    </button>
    <button class="slide-tab" data-panel="personal" title="Personal Feed">
        <img src="https://www.fireengineering.com/wp-content/uploads/2023/09/FrankMcKinley.jpg" width="22" height="22" alt="Personal" style="object-fit:cover;border-radius:50%;">
        <span>Personal</span>
    </button>
</div>

<div class="slide-panel" id="slidePanel">
    <div class="slide-panel-header">
        <h3 id="slidePanelTitle"></h3>
        <button id="slidePanelClose" style="background:none;border:none;color:var(--ios-secondary);font-size:20px;cursor:pointer;padding:4px;">&times;</button>
    </div>
    <div class="slide-panel-body" id="slidePanelBody"></div>
</div>

<style>
.slide-panel-tabs {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 80;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.slide-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 12px 10px;
    background: var(--primary);
    color: rgba(255,255,255,0.7);
    border: none;
    cursor: pointer;
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    transition: all 0.2s;
    border-radius: 8px 0 0 8px;
    width: 56px;
}
.slide-tab:hover { background: var(--cfd-navy-light); color: #fff; }
.slide-tab.active { background: var(--accent); color: #fff; }

.slide-panel {
    position: fixed;
    right: -380px;
    top: var(--top-offset);
    bottom: var(--footer-height);
    width: 360px;
    background: var(--ios-card);
    border-left: 1px solid var(--ios-border);
    box-shadow: -8px 0 30px rgba(11,34,64,0.1);
    z-index: 85;
    transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.slide-panel.open { right: 0; }

.slide-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--ios-border);
    flex-shrink: 0;
}
.slide-panel-header h3 {
    font-size: 16px;
    font-weight: 700;
    color: var(--primary);
}

.slide-panel-body {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
}

.slide-panel-item {
    display: block;
    padding: 12px 0;
    border-bottom: 1px solid var(--ios-border);
}
.slide-panel-item:last-child { border-bottom: none; }
.slide-panel-item:hover { background: var(--ios-bg); margin: 0 -20px; padding-left: 20px; padding-right: 20px; border-radius: 0; }

.council-section-label { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:var(--ios-tertiary); padding:8px 0 4px; }
.council-meeting { padding:12px 0; border-bottom:1px solid var(--ios-border); cursor:pointer; border-left:3px solid transparent; padding-left:12px; margin-left:-8px; transition:all 0.2s; border-radius:4px; }
.council-meeting:hover { background:var(--ios-bg); }
.council-agenda-item { padding:8px 0; border-bottom:1px solid rgba(0,0,0,0.05); }
.council-agenda-item:last-child { border-bottom:none; }

@media (max-width: 768px) {
    .slide-panel-tabs { display: none; }
    .slide-panel { display: none; }
}
</style>
