{% extends 'partials/base.html.twig' %}

{% block nav %}
<a class="story-escape" href="{{ page.parent().url }}" onclick="if(history.length > 1){ history.back(); return false; }">← Back</a>
<span class="story-nav-title" id="story-nav-title" aria-hidden="true">{{ page.title }}</span>
{% endblock %}

{% block content %}
{% set hero = null %}
{% if page.header.hero_image and page.media[page.header.hero_image] is defined %}
    {% set hero = page.media[page.header.hero_image] %}
{% endif %}

{% set date_str = page.date|date('d M Y') %}
{% if page.header.end_date and page.header.end_date != page.date|date('Y-m-d') %}
    {% set sd = page.date|date('d') %}
    {% set sm = page.date|date('M') %}
    {% set sy = page.date|date('Y') %}
    {% set ed = page.header.end_date|date('d') %}
    {% set em = page.header.end_date|date('M') %}
    {% set ey = page.header.end_date|date('Y') %}
    {% if sy == ey and sm == em %}
        {% set date_str = sd ~ ' – ' ~ ed ~ ' ' ~ em ~ ' ' ~ ey %}
    {% elseif sy == ey %}
        {% set date_str = sd ~ ' ' ~ sm ~ ' – ' ~ ed ~ ' ' ~ em ~ ' ' ~ ey %}
    {% else %}
        {% set date_str = sd ~ ' ' ~ sm ~ ' ' ~ sy ~ ' – ' ~ ed ~ ' ' ~ em ~ ' ' ~ ey %}
    {% endif %}
{% endif %}

{% set location = page.header.location_name ?? '' %}

<div class="story-hero" id="story-hero">
    <div class="story-hero__img-wrap">
        {% if hero %}
        <img src="{{ hero.url }}" alt="{{ page.header.hero_alt ?? page.title }}" class="story-hero__img" loading="eager">
        {% else %}
        <div class="story-hero__img-placeholder"></div>
        {% endif %}
    </div>
    <div class="story-hero__overlay" id="story-overlay" aria-hidden="true"></div>
    <div class="story-hero__content">
        <h1 class="story-hero__title">{{ page.title }}</h1>
        <p class="story-hero__meta">
            <time datetime="{{ page.date|date('Y-m-d') }}">{{ date_str }}</time>
            {% if location %} · {{ location }}{% endif %}
        </p>
    </div>
    <div class="story-hero__scroll-cue" id="story-scroll-cue" aria-hidden="true">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="6 9 12 15 18 9"/>
        </svg>
    </div>
    <div class="story-hero__spacer"></div>
</div>

<div class="story-body">
    {{ page.content|raw }}

    <footer class="story-footer">
        <a href="{{ page.parent().url }}" onclick="if(history.length > 1){ history.back(); return false; }">← Back</a>
    </footer>
</div>

<button class="story-totop" id="story-totop" aria-label="Back to top">↑ Top</button>

<script src="https://cdn.jsdelivr.net/npm/scrollama@3/build/scrollama.min.js"></script>
<script>
/* ── Hero scroll effect ──────────────────────────────────── */
(function () {
    var overlay  = document.getElementById('story-overlay');
    var cue      = document.getElementById('story-scroll-cue');
    var hidden   = false;
    var ticking  = false;
    if (!overlay) return;

    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

    function update() {
        var scrollY  = window.scrollY;
        var vh       = window.innerHeight;
        var heroEnd  = vh * 1.4; // img-wrap (100vh) + spacer (40vh)
        var mid      = heroEnd * 0.5; // peak darkness at 70vh
        var opacity  = scrollY <= mid
            ? (scrollY / mid) * 0.65
            : Math.max(0, (1 - (scrollY - mid) / (heroEnd - mid)) * 0.65);
        overlay.style.background = 'rgba(0,0,0,' + opacity.toFixed(3) + ')';
        overlay.style.display = (opacity < 0.002) ? 'none' : '';
        if (!hidden && window.scrollY > 80) {
            cue.classList.add('is-hidden');
            hidden = true;
        }
        ticking = false;
    }

    window.addEventListener('scroll', function () {
        if (!ticking) { requestAnimationFrame(update); ticking = true; }
    }, { passive: true });
    update();
})();

/* ── Story title in nav (cross-fades as hero content exits viewport top) ── */
(function () {
    var navTitle    = document.getElementById('story-nav-title');
    var heroContent = document.querySelector('.story-hero__content');
    if (!navTitle || !heroContent) return;
    var hasBeenVisible = false;
    var ticking        = false;

    function update() {
        var rect   = heroContent.getBoundingClientRect();
        var inView = rect.bottom > 0 && rect.top < window.innerHeight;
        if (inView) hasBeenVisible = true;

        if (hasBeenVisible) {
            var opacity;
            if (rect.bottom <= 0) {
                opacity = 1;                                    // fully above viewport
            } else if (rect.top <= 0) {
                opacity = 1 - rect.bottom / rect.height;       // partially exiting top
            } else {
                opacity = 0;                                    // fully in viewport
            }
            navTitle.style.opacity = opacity.toFixed(3);
        }
        ticking = false;
    }

    window.addEventListener('scroll', function () {
        if (!ticking) { requestAnimationFrame(update); ticking = true; }
    }, { passive: true });
    update();
})();

/* ── Back to top button ─────────────────────────────────── */
(function () {
    var btn       = document.getElementById('story-totop');
    if (!btn) return;
    var threshold = window.innerHeight * 0.8;
    var shown     = false;
    btn.addEventListener('click', function () {
        window.scrollTo({ top: 0, behavior: 'smooth' });
    });
    window.addEventListener('scroll', function () {
        var shouldShow = window.scrollY > threshold;
        if (shouldShow !== shown) {
            shown = shouldShow;
            btn.classList.toggle('is-visible', shown);
        }
    }, { passive: true });
})();

/* ── ChapterBreak scroll-reveal ─────────────────────────── */
(function () {
    var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    var panels  = document.querySelectorAll('.chapter-break__panel');
    if (!panels.length) return;
    if (reduced) { panels.forEach(function (p) { p.classList.add('is-revealed'); }); return; }
    var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
            if (e.isIntersecting) { e.target.classList.add('is-revealed'); io.unobserve(e.target); }
        });
    }, { threshold: 0.25 });
    panels.forEach(function (p) { io.observe(p); });
})();

/* ── PullQuote scroll-reveal ─────────────────────────────── */
(function () {
    var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    var quotes  = document.querySelectorAll('.pull-quote');
    if (!quotes.length) return;
    if (reduced) { quotes.forEach(function (q) { q.classList.add('is-revealed'); }); return; }
    var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
            if (e.isIntersecting) { e.target.classList.add('is-revealed'); io.unobserve(e.target); }
        });
    }, { threshold: 0.2 });
    quotes.forEach(function (q) { io.observe(q); });
})();

/* ── SnapGallery dot indicator ───────────────────────────── */
(function () {
    document.querySelectorAll('.pgallery').forEach(function (gallery) {
        var slides = gallery.querySelectorAll('.pgallery__slide');
        var dots   = gallery.querySelectorAll('.pgallery__dot');
        if (!slides.length || !dots.length) return;
        var io = new IntersectionObserver(function (entries) {
            entries.forEach(function (e) {
                if (e.isIntersecting) {
                    var idx = parseInt(e.target.dataset.index, 10);
                    dots.forEach(function (d) { d.classList.remove('is-active'); });
                    if (dots[idx]) dots[idx].classList.add('is-active');
                }
            });
        }, { threshold: 0.5, root: gallery.querySelector('.pgallery__frame') });
        slides.forEach(function (s) { io.observe(s); });
    });
})();

/* ── ScrollySection (Scrollama) ──────────────────────────── */
(function () {
    var reduced  = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    var sections = document.querySelectorAll('.scrolly');
    if (!sections.length || typeof scrollama === 'undefined') return;

    var panOffsets = ['50% 40%', '50% 50%', '50% 60%', '50% 45%', '50% 55%'];

    sections.forEach(function (section) {
        var img         = section.querySelector('.scrolly__img');
        var overlay     = section.querySelector('.scrolly__img-overlay');
        var contentEl   = section.querySelector('.scrolly__steps-content');
        var stepsWrap   = section.querySelector('.scrolly__steps');
        if (!img || !contentEl || !stepsWrap) return;

        /* Split slot content on <hr> into individual step divs */
        var nodes  = Array.from(contentEl.childNodes);
        var groups = [];
        var curr   = [];
        nodes.forEach(function (n) {
            if (n.nodeName === 'HR') { if (curr.length) groups.push(curr); curr = []; }
            else curr.push(n);
        });
        if (curr.length) groups.push(curr);
        if (!groups.length) groups.push(nodes);

        groups.forEach(function (group) {
            var step  = document.createElement('div');
            step.className = 'scrolly-step';
            var inner = document.createElement('div');
            inner.className = 'scrolly-step__inner';
            group.forEach(function (n) { inner.appendChild(n.cloneNode(true)); });
            step.appendChild(inner);
            stepsWrap.appendChild(step);
        });

        if (reduced) {
            section.querySelectorAll('.scrolly-step').forEach(function (s) { s.classList.add('is-active'); });
            return;
        }

        /* Initial blur */
        img.style.filter    = 'blur(8px)';
        img.style.transform = 'scale(1.04)';
        img.style.transition = 'filter 0.7s cubic-bezier(.16,1,.3,1), transform 0.7s cubic-bezier(.16,1,.3,1), object-position 1.2s cubic-bezier(.16,1,.3,1)';

        new IntersectionObserver(function (entries, obs) {
            if (entries[0].isIntersecting) {
                img.style.filter    = 'blur(0)';
                img.style.transform = 'scale(1)';
                obs.disconnect();
            }
        }, { threshold: 0.1 }).observe(section);

        scrollama()
            .setup({ step: Array.from(section.querySelectorAll('.scrolly-step')), offset: 0.55 })
            .onStepEnter(function (d) {
                d.element.classList.add('is-active');
                img.style.objectPosition = panOffsets[d.index % panOffsets.length];
                if (overlay) overlay.style.background = 'rgba(0,0,0,' + (0.05 + (d.index % 3) * 0.05) + ')';
            })
            .onStepExit(function (d) {
                if (d.direction === 'up') d.element.classList.remove('is-active');
            });
    });
})();
</script>
{% endblock %}
