{{- /* theme-toggle is enabled */}}
{{- if (not site.Params.disableThemeToggle) }}
{{- /* theme is light */}}
{{- if (eq site.Params.defaultTheme "light") }}
<script>
    if (localStorage.getItem("pref-theme") === "dark") {
        document.body.classList.add('dark');
    }

</script>
{{- /* theme is dark */}}
{{- else if (eq site.Params.defaultTheme "dark") }}
<script>
    if (localStorage.getItem("pref-theme") === "light") {
        document.body.classList.remove('dark')
    }

</script>
{{- else }}
{{- /* theme is auto */}}
<script>
    if (localStorage.getItem("pref-theme") === "dark") {
        document.body.classList.add('dark');
    } else if (localStorage.getItem("pref-theme") === "light") {
        document.body.classList.remove('dark')
    } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        document.body.classList.add('dark');
    }

</script>
{{- end }}
{{- /* theme-toggle is disabled and theme is auto */}}
{{- else if (and (ne site.Params.defaultTheme "light") (ne site.Params.defaultTheme "dark"))}}
<script>
    if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        document.body.classList.add('dark');
    }

</script>
{{- end }}

<a class="skip-link" href="#main-content" aria-label="Skip to main content">Skip to main content</a>
<div class="header-wrapper">
<header class="header">
    <nav class="nav">
        <div class="logo">
            {{- $label_text := (site.Params.label.text | default site.Title) }}
            {{- if site.Title }}
            <a href="{{ "" | absLangURL }}" accesskey="h" title="{{ $label_text }} (Alt + H)">
                {{- if site.Params.label.icon }}
                {{- $img := resources.Get site.Params.label.icon }}
                {{- if $img }}
                    {{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
                    {{- if hugo.IsExtended -}}
                        {{- $processableFormats = $processableFormats | append "webp" -}}
                    {{- end -}}
                    {{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
                    {{- if and (in $processableFormats $img.MediaType.SubType) (eq $prod true)}}
                        {{- if site.Params.label.iconHeight }}
                            {{- $img = $img.Resize (printf "x%d" site.Params.label.iconHeight) }}
                        {{ else }}
                            {{- $img = $img.Resize "x30" }}
                        {{- end }}
                    {{- end }}
                    <img src="{{ $img.RelPermalink }}" alt="{{ $label_text }} logo"
                        height="{{- site.Params.label.iconHeight | default "30" -}}">
                {{- else }}
                <img src="{{- site.Params.label.icon | relURL -}}" alt="{{ $label_text }} logo"
                    height="{{- site.Params.label.iconHeight | default "30" -}}">
                {{- end -}}
                {{- else if hasPrefix site.Params.label.iconSVG "<svg" }}
                    {{ site.Params.label.iconSVG | safeHTML }}
                {{- end -}}
                {{- $label_text -}}
            </a>
            {{- end }}
        </div>

        {{- $currentPage := . }}
        <ul id="menu">
            {{- range site.Menus.main }}
            {{- $menu_item_url := (cond (strings.HasSuffix .URL "/") .URL (printf "%s/" .URL) ) | absLangURL }}
            {{- $page_url:= $currentPage.Permalink | absLangURL }}
            {{- $is_search := strings.Contains .URL "search" }}
            <li>
                <a href="{{ .URL | absLangURL }}" title="{{ .Title | default .Name }} {{- cond $is_search (" (Alt + /)" | safeHTMLAttr) ("" | safeHTMLAttr ) }}"
                {{- cond $is_search (" accesskey=/" | safeHTMLAttr) ("" | safeHTMLAttr ) }}>
                    <span {{- if eq $menu_item_url $page_url }} class="active" {{- end }}>
                        {{- .Pre }}
                        {{- .Name -}}
                        {{ .Post -}}
                    </span>
                    {{- if (findRE "://" .URL) }}&nbsp;
                    <svg fill="none" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round"
                        stroke-linejoin="round" stroke-width="2.5" viewBox="0 0 24 24" height="12" width="12">
                        <path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
                        <path d="M15 3h6v6"></path>
                        <path d="M10 14L21 3"></path>
                    </svg>
                    {{- end }}
                </a>
            </li>
            {{- end }}
        </ul>

        <div class="logo-switches">
            {{/* SEARCH BUTTON */}}
            <button
                type="button"
                class="nav-search-trigger"
                data-search-trigger="nav"
                aria-haspopup="dialog"
                aria-controls="search-command-palette"
                aria-expanded="false"
                title="{{ cond (eq site.Language.Lang "zh") "搜索 (Cmd/Ctrl + K)" "Search (Cmd/Ctrl + K)" }}">
                <span class="nav-search-trigger__icon" aria-hidden="true">
                    <svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 24 24" fill="none"
                        stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <circle cx="11" cy="11" r="8"></circle>
                        <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
                    </svg>
                </span>
                <span class="nav-search-trigger__label">{{ cond (eq site.Language.Lang "zh") "搜索" "Search" }}</span>
                <span class="nav-search-trigger__keys" aria-hidden="true">
                    <kbd>⌘</kbd>
                    <kbd>K</kbd>
                </span>
            </button>

            {{- if (not site.Params.disableThemeToggle) }}
            <button id="theme-toggle" accesskey="t" title="(Alt + T)" aria-label="Toggle theme">
                <svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                    fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                    stroke-linejoin="round">
                    <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
                </svg>
                <svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                    fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                    stroke-linejoin="round">
                    <circle cx="12" cy="12" r="5"></circle>
                    <line x1="12" y1="1" x2="12" y2="3"></line>
                    <line x1="12" y1="21" x2="12" y2="23"></line>
                    <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
                    <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
                    <line x1="1" y1="12" x2="3" y2="12"></line>
                    <line x1="21" y1="12" x2="23" y2="12"></line>
                    <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
                    <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
                </svg>
            </button>
            {{- end }}

            {{/* LANGUAGE SELECTOR — bilingual pill, current language sealed in cinnabar */}}
            {{ if gt (len .Site.Languages) 1 }}
                {{ $currentLang := .Lang }}
                {{ $allTranslations := .Translations }}

                <ul class="lang-switch" role="group" aria-label="Language">
                    {{ range $anySiteLang := .Site.Home.AllTranslations }}
                        {{ $code := .Lang }}
                        {{ $glyph := cond (eq $code "zh") "中" (.Lang | upper) }}
                        {{ $aria := .Language.LanguageName | default (.Lang | upper) }}
                        {{ if eq $currentLang $code }}
                            <li class="lang-switch__item lang-switch__item--active lang-switch__item--{{ $code }}">
                                <span aria-current="true" aria-label="{{ $aria }}">{{ $glyph }}</span>
                            </li>
                        {{ else }}
                            {{ $translationLink := .RelPermalink }}
                            {{ range $translation := $allTranslations }}
                                {{ if eq $code $translation.Lang }}
                                    {{ $translationLink = $translation.RelPermalink }}
                                {{ end }}
                            {{ end }}
                            <li class="lang-switch__item lang-switch__item--{{ $code }}">
                                <a href="{{ $translationLink }}"
                                   title="{{ .Language.Params.languageAltTitle | default (.Language.LanguageName) | default (.Lang | upper) }}"
                                   aria-label="{{ $aria }}"
                                   hreflang="{{ $code }}"
                                   rel="alternate">{{ $glyph }}</a>
                            </li>
                        {{ end }}
                    {{ end }}
                </ul>
            {{ end }}

        </div>

        {{/* Hamburger Menu for Mobile */}}
        <button
            type="button"
            class="hamburger-menu"
            aria-label="Toggle menu"
            aria-expanded="false"
            onclick="toggleMenu()">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <line x1="3" y1="12" x2="21" y2="12"></line>
                <line x1="3" y1="6" x2="21" y2="6"></line>
                <line x1="3" y1="18" x2="21" y2="18"></line>
            </svg>
        </button>
    </nav>
</header>
</div>

<script>
function toggleMenu() {
    const menu = document.getElementById('menu');
    const hamburger = document.querySelector('.hamburger-menu');
    const isOpen = menu.classList.contains('mobile-open');

    if (isOpen) {
        menu.classList.remove('mobile-open');
        hamburger.setAttribute('aria-expanded', 'false');
    } else {
        menu.classList.add('mobile-open');
        hamburger.setAttribute('aria-expanded', 'true');
    }
}

// Close menu when clicking outside
document.addEventListener('click', function(event) {
    const menu = document.getElementById('menu');
    const hamburger = document.querySelector('.hamburger-menu');

    if (menu && hamburger && !menu.contains(event.target) && !hamburger.contains(event.target)) {
        menu.classList.remove('mobile-open');
        hamburger.setAttribute('aria-expanded', 'false');
    }
});

// Auto-hide navbar on scroll down, reveal on scroll up (Medium-style)
// 显示导航栏需要「累积向上滚动」超过 REVEAL_THRESHOLD，避免轻微上滑就弹出。
(function () {
    var headerWrapper = document.querySelector('.header-wrapper');
    if (!headerWrapper) return;

    // ── Publish the real sticky-header height as --header-height ──────────
    // Several stylesheets offset anchored navigation by the header height
    // (scroll-padding-top / scroll-margin-top for deep links, TOC jumps,
    // footnotes and the #latest-posts / #start-here anchors, plus the TOC
    // sidebar's sticky `top`). The variable was referenced but never set, so
    // those `calc(var(--header-height) …)` rules with no fallback evaluated
    // to an invalid length and were dropped — anchor jumps then landed
    // *behind* the sticky bar. Measure the header and expose the value (kept
    // in sync on resize / orientation change / font load) so every offset is
    // accurate and responsive. Cheap: reads offsetHeight only on these rare
    // events, never on scroll.
    var headerHeightRAF = 0;
    function setHeaderHeight() {
        var h = Math.round(headerWrapper.offsetHeight);
        if (h > 0) {
            document.documentElement.style.setProperty('--header-height', h + 'px');
        }
    }
    function scheduleHeaderHeight() {
        if (headerHeightRAF) return;
        headerHeightRAF = requestAnimationFrame(function () {
            headerHeightRAF = 0;
            setHeaderHeight();
        });
    }
    setHeaderHeight();
    window.addEventListener('resize', scheduleHeaderHeight, { passive: true });
    window.addEventListener('orientationchange', scheduleHeaderHeight, { passive: true });
    // Web fonts can change the bar's height after first paint.
    if (document.fonts && document.fonts.ready && typeof document.fonts.ready.then === 'function') {
        document.fonts.ready.then(setHeaderHeight).catch(function () {});
    }

    // The auto-hide slide is motion; honour prefers-reduced-motion by keeping
    // the header steady for those visitors. The scroll-elevation shadow is a
    // static depth cue (no movement) so it still runs for everyone.
    var allowHide = !(window.matchMedia &&
        window.matchMedia('(prefers-reduced-motion: reduce)').matches);

    var lastScrollY = window.scrollY || window.pageYOffset;
    var ticking = false;
    var TOP_THRESHOLD = 80;       // 接近顶部时无条件显示
    var REVEAL_THRESHOLD = 64;    // 需累积上滑这么多像素才浮现导航栏
    var ELEVATE_THRESHOLD = 8;    // 离开顶部这么多像素就抬升出阴影
    var upAccumulated = 0;        // 当前连续向上滚动的累计距离

    function show() {
        headerWrapper.classList.remove('nav-scroll-hidden');
        document.body.classList.remove('nav-hidden');
    }
    function hide() {
        headerWrapper.classList.add('nav-scroll-hidden');
        document.body.classList.add('nav-hidden');
    }

    function update() {
        var currentY = window.scrollY || window.pageYOffset;
        var delta = currentY - lastScrollY;
        var menu = document.getElementById('menu');
        var menuOpen = menu && menu.classList.contains('mobile-open');

        // Elevation: flush at the top, lifted (soft shadow) once scrolled.
        headerWrapper.classList.toggle('nav-scrolled', currentY > ELEVATE_THRESHOLD);

        if (allowHide && !menuOpen) {
            if (currentY <= TOP_THRESHOLD) {
                // 顶部区域始终显示
                upAccumulated = 0;
                show();
            } else if (delta > 0) {
                // 向下滚动：立即隐藏，并清空上滑累计
                upAccumulated = 0;
                hide();
            } else if (delta < 0) {
                // 向上滚动：累计，超过阈值才显示
                upAccumulated += -delta;
                if (upAccumulated >= REVEAL_THRESHOLD) {
                    show();
                }
            }
        }
        lastScrollY = currentY;
        ticking = false;
    }

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

    // Accessibility: never strand keyboard focus inside an off-screen
    // header. If anything in the bar gains focus (Tab / Shift+Tab) while
    // it's auto-hidden, slide it back into view immediately.
    headerWrapper.addEventListener('focusin', function () {
        upAccumulated = 0;
        show();
    });

    // Set the correct elevation state on first paint (e.g. when landing
    // mid-page via an anchor or a restored scroll position).
    update();
})();
</script>
