{% import "macros/post.html" as post_macros -%}
<!DOCTYPE html>
<html lang="{{ config.default_language | default(value="en") }}">
<head>
    <title>{% block title %}{{ config.title }}{% endblock title %}</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
    <meta name="robots" content="noodp"/>
    <style>html.theme-swapping{opacity:0!important}html.no-transitions,html.no-transitions *{transition:none!important}</style>
    <link rel="stylesheet" href="/style.css" id="theme-stylesheet">
    <script>
      (function() {
        var html = document.documentElement;
        html.classList.add('no-transitions');
        var saved = localStorage.getItem('theme');
        var preferLight = window.matchMedia('(prefers-color-scheme: light)').matches;
        if (saved === 'light' || (!saved && preferLight)) {
          html.setAttribute('data-theme', 'light');
        }
        var siteTheme = localStorage.getItem('site-theme');
        var defaultTheme = '{{ config.theme | default(value="zorto") }}';
        var styleLink = document.getElementById('theme-stylesheet');
        if (siteTheme && siteTheme !== defaultTheme) {
          styleLink.href = '/style-' + siteTheme + '.css';
          // Remove no-transitions only after the new stylesheet has loaded
          styleLink.onload = function() {
            requestAnimationFrame(function(){ html.classList.remove('no-transitions'); });
            styleLink.onload = null;
          };
          // Safety timeout in case onload doesn't fire (e.g. cached stylesheet)
          setTimeout(function() { html.classList.remove('no-transitions'); }, 500);
        }
      })();
    </script>
    {%- if config.markdown.highlight_code and config.markdown.highlight_theme == "css" %}
    <link rel="stylesheet" href="/syntax-dark.css">
    {%- endif %}
    {%- block open_graph %}
    {%- if page %}
        {%- set og_title = page.title ~ " | " ~ config.title %}
        {%- set og_desc = page.description | default(value="") %}
        {%- set og_url = page.permalink %}
    {%- elif section %}
        {%- set og_title = section.title | default(value=config.title) %}
        {%- set og_desc = section.description | default(value="") %}
        {%- set og_url = section.permalink %}
    {%- else %}
        {%- set og_title = config.title %}
        {%- set og_desc = "" %}
        {%- set og_url = config.base_url %}
    {%- endif %}
    <meta name="description" content="{{ og_desc }}">
    <meta property="og:title" content="{{ og_title }}">
    <meta property="og:description" content="{{ og_desc }}">
    <meta property="og:url" content="{{ og_url }}">
    {%- if config.extra.default_og_image %}
    <meta property="og:image" content="{{ get_url(path=config.extra.default_og_image) }}">
    {%- endif %}
    <meta name="twitter:card" content="summary_large_image">
    {%- endblock open_graph %}
    {%- if config.extra.favicon %}
    <link rel="icon" type="{{ config.extra.favicon_mimetype | default(value="image/png") }}" href="{{ config.extra.favicon }}">
    {%- endif %}
    {%- if config.generate_feed %}
    <link rel="alternate" type="application/atom+xml" title="{{ config.title }} Feed" href="/atom.xml">
    {%- endif %}
    {%- if config.compile_all_themes %}
    {%- for name in ["zorto", "dkdc", "default", "ember", "forest", "ocean", "rose", "slate"] %}
    {%- if name != config.theme | default(value="zorto") %}
    <link rel="prefetch" href="/style-{{ name }}.css" as="style">
    {%- endif %}
    {%- endfor %}
    {%- endif %}
    {%- block extra_head %}{% endblock extra_head %}
</head>
<body>
<nav class="navbar" aria-label="Main navigation">
    <div class="navbar__inner">
        <a href="/" class="navbar__logo">
            {%- if config.extra.logo_image %}
            <img src="{{ config.extra.logo_image }}" alt="" class="navbar__logo-img">
            {%- endif %}
            <span class="logo-name">{{ config.extra.logo_text | default(value=config.title) }}</span>
            {%- if config.extra.logo_tld %}<span class="logo-tld">{{ config.extra.logo_tld }}</span>{%- endif %}
        </a>
        <input type="checkbox" id="nav-toggle" class="navbar__toggle-input">
        <div class="navbar__menu">
        {%- if config.extra.menu_items %}
        {%- if page %}
            {%- set current_path = page.permalink %}
        {%- elif section %}
            {%- set current_path = section.permalink %}
        {%- else %}
            {%- set current_path = config.base_url %}
        {%- endif %}
        <ul class="navbar__links">
        {%- for item in config.extra.menu_items %}
            {%- set item_url = item.url | replace(from="$BASE_URL", to="") %}
            {%- set full_item_url = config.base_url ~ item_url %}
            {%- set is_active = current_path is starting_with(full_item_url) and item_url != "/" %}
            <li{% if is_active %} class="active"{% endif %}><a href="{{ item_url }}" aria-current="{% if is_active %}page{% endif %}"{% if item.external | default(value=false) %} target="_blank" rel="noopener"{% endif %}>{{ item.name }}{% if item.external | default(value=false) %}<svg class="external-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>{% endif %}</a></li>
        {%- endfor %}
        </ul>
        {%- endif %}
        {%- if config.extra.menu_items_right %}
        <div class="navbar__right-items">
        {%- for item in config.extra.menu_items_right %}
            {%- set item_url = item.url | replace(from="$BASE_URL", to=config.base_url) %}
            <a href="{{ item_url }}" class="navbar__right-btn"{% if item.external | default(value=false) %} target="_blank" rel="noopener"{% endif %}>{{ item.name }}</a>
        {%- endfor %}
        {%- if config.compile_all_themes %}
        <div class="theme-switcher" id="theme-switcher">
            <button class="theme-switcher__btn navbar__right-btn" aria-label="Themes" title="Switch theme">
                <span>Themes</span>
                <svg class="theme-switcher__chevron" xmlns="http://www.w3.org/2000/svg" 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>
            </button>
            <div class="theme-switcher__menu" id="theme-switcher-menu" hidden>
                <button class="theme-switcher__option" data-theme-name="zorto">zorto</button>
                <button class="theme-switcher__option" data-theme-name="dkdc">dkdc</button>
                <button class="theme-switcher__option" data-theme-name="default">default</button>
                <button class="theme-switcher__option" data-theme-name="ember">ember</button>
                <button class="theme-switcher__option" data-theme-name="forest">forest</button>
                <button class="theme-switcher__option" data-theme-name="ocean">ocean</button>
                <button class="theme-switcher__option" data-theme-name="rose">rose</button>
                <button class="theme-switcher__option" data-theme-name="slate">slate</button>
                <button class="theme-switcher__option" data-theme-name="midnight">midnight</button>
                <button class="theme-switcher__option" data-theme-name="sunset">sunset</button>
                <button class="theme-switcher__option" data-theme-name="mint">mint</button>
                <button class="theme-switcher__option" data-theme-name="plum">plum</button>
                <button class="theme-switcher__option" data-theme-name="sand">sand</button>
                <button class="theme-switcher__option" data-theme-name="arctic">arctic</button>
                <button class="theme-switcher__option" data-theme-name="lime">lime</button>
                <button class="theme-switcher__option" data-theme-name="charcoal">charcoal</button>
            </div>
        </div>
        {%- endif %}
        </div>
        {%- endif %}
        </div>
        <label for="nav-toggle" class="navbar__hamburger" role="button" aria-label="Toggle menu" aria-expanded="false">
            <span></span><span></span><span></span>
        </label>
        {%- if config.generate_search %}
        <button class="search-toggle navbar__icon-link" aria-label="Search" title="Search (Ctrl+K)">
            <svg xmlns="http://www.w3.org/2000/svg" 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"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
        </button>
        {%- endif %}
        {%- if config.extra.social_links %}
        {%- for link in config.extra.social_links %}
        <a href="{{ link.url }}" class="navbar__icon-link" aria-label="{{ link.name }}" title="{{ link.name }}" target="_blank" rel="noopener">
            {%- if link.icon == "github" %}
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/></svg>
            {%- elif link.icon == "linkedin" %}
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
            {%- endif %}
        </a>
        {%- endfor %}
        {%- endif %}
        <button class="theme-toggle" aria-label="Toggle light/dark" title="Toggle light/dark">
            <svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" 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"/></svg>
            <svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" 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"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
        </button>
    </div>
</nav>
<main class="main">
    {% block content %}{% endblock content %}
</main>
<footer class="footer">
    <div class="footer__inner">
        {%- if config.extra.copyright_html %}
        <div class="copyright">{{ config.extra.copyright_html | safe }}</div>
        {%- else %}
        <div class="copyright">
            <span>&copy; {{ now() | date(format="%Y") }} {{ config.extra.author | default(value="") }}</span>
        </div>
        {%- endif %}
    </div>
</footer>
<script>
(function() {
  const toggle = document.querySelector('.theme-toggle');
  const html = document.documentElement;
  function getPreferredTheme() {
    const saved = localStorage.getItem('theme');
    if (saved) return saved;
    return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
  }
  function setTheme(theme) {
    if (theme === 'light') {
      html.setAttribute('data-theme', 'light');
    } else {
      html.removeAttribute('data-theme');
    }
    localStorage.setItem('theme', theme);
  }
  setTheme(getPreferredTheme());
  toggle.style.display = 'flex';
  toggle.addEventListener('click', () => {
    const current = html.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
    setTheme(current === 'light' ? 'dark' : 'light');
  });
  window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => {
    if (!localStorage.getItem('theme')) {
      setTheme(e.matches ? 'light' : 'dark');
    }
  });
})();
</script>
{%- if config.compile_all_themes %}
<script>
(function() {
  var switcher = document.getElementById('theme-switcher');
  if (!switcher) return;
  var btn = switcher.querySelector('.theme-switcher__btn');
  var menu = document.getElementById('theme-switcher-menu');
  var styleLink = document.getElementById('theme-stylesheet');
  var defaultTheme = '{{ config.theme | default(value="zorto") }}';
  var currentSiteTheme = localStorage.getItem('site-theme') || defaultTheme;

  function applySiteTheme(name) {
    var href = (name === defaultTheme) ? '/style.css' : '/style-' + name + '.css';
    if (styleLink.getAttribute('href') !== href) {
      document.documentElement.classList.add('theme-swapping');
      styleLink.onload = function() {
        document.documentElement.classList.remove('theme-swapping');
        styleLink.onload = null;
      };
      styleLink.href = href;
      setTimeout(function() { document.documentElement.classList.remove('theme-swapping'); }, 2000);
    }
    localStorage.setItem('site-theme', name);
    currentSiteTheme = name;
    // Re-apply light/dark preference
    var mode = localStorage.getItem('theme');
    if (mode === 'light') {
      document.documentElement.setAttribute('data-theme', 'light');
    } else {
      document.documentElement.removeAttribute('data-theme');
    }
    // Update active state
    menu.querySelectorAll('.theme-switcher__option').forEach(function(o) {
      o.classList.toggle('active', o.getAttribute('data-theme-name') === name);
    });
  }

  // Mark initial active theme (don't re-apply on load — head script already handled it)
  menu.querySelectorAll('.theme-switcher__option').forEach(function(o) {
    o.classList.toggle('active', o.getAttribute('data-theme-name') === currentSiteTheme);
  });

  btn.addEventListener('click', function() { menu.toggleAttribute('hidden'); });
  menu.querySelectorAll('.theme-switcher__option').forEach(function(opt) {
    opt.addEventListener('click', function() {
      applySiteTheme(this.getAttribute('data-theme-name'));
      menu.setAttribute('hidden', '');
    });
  });
  document.addEventListener('click', function(e) {
    if (!switcher.contains(e.target)) menu.setAttribute('hidden', '');
  });
})();
</script>
{%- endif %}
<script>
(function() {
  var clipSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
  var checkSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>';
  document.querySelectorAll('pre').forEach(function(pre) {
    var wrapper = document.createElement('div');
    wrapper.className = 'code-block-wrapper';
    pre.parentNode.insertBefore(wrapper, pre);
    wrapper.appendChild(pre);
    var btn = document.createElement('button');
    btn.className = 'copy-button';
    btn.innerHTML = clipSvg;
    btn.setAttribute('aria-label', 'Copy code');
    btn.addEventListener('click', function() {
      navigator.clipboard.writeText(pre.textContent).then(function() {
        btn.innerHTML = checkSvg;
        setTimeout(function() { btn.innerHTML = clipSvg; }, 1500);
      });
    });
    wrapper.appendChild(btn);
  });
})();
</script>
{%- if config.extra.enable_md_fab %}
{%- set_global fab_path = "/" %}
{%- if page %}{% set_global fab_path = page.path %}
{%- elif section %}{% set_global fab_path = section.path %}{% endif %}
{%- set_global fab_excluded = false %}
{%- if config.extra.md_fab_exclude %}
  {%- for exc in config.extra.md_fab_exclude %}
    {%- if fab_path == exc %}{% set_global fab_excluded = true %}{% endif %}
  {%- endfor %}
{%- endif %}
{%- if not fab_excluded %}
<div class="md-fab" id="md-fab">
  <button class="md-fab__toggle" aria-label="Markdown" title="Markdown">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 208 128" fill="currentColor"><rect width="198" height="118" x="5" y="5" rx="10" fill="none" stroke="currentColor" stroke-width="10"/><path d="M30 98V30h20l20 25 20-25h20v68H90V59L70 84 50 59v39zm125 0l-30-33h20V30h20v35h20z"/></svg>
  </button>
  <div class="md-fab__menu" hidden>
    <button class="md-fab__item" data-action="copy-url">Copy this page's .md link</button>
    <button class="md-fab__item" data-action="copy-content">Copy this page as Markdown</button>
  </div>
</div>
<script>
(function(){
  var fab=document.getElementById('md-fab');if(!fab)return;
  var toggle=fab.querySelector('.md-fab__toggle'),menu=fab.querySelector('.md-fab__menu');
  var p=window.location.pathname.replace(/\/$/,'');
  var mdUrl=window.location.origin+(p||'/index')+'.md';
  function flash(){toggle.classList.add('md-fab--copied');setTimeout(function(){toggle.classList.remove('md-fab--copied');},1500);menu.setAttribute('hidden','');}
  toggle.addEventListener('click',function(){menu.toggleAttribute('hidden');});
  fab.querySelector('[data-action="copy-url"]').addEventListener('click',function(){navigator.clipboard.writeText(mdUrl).then(flash);});
  fab.querySelector('[data-action="copy-content"]').addEventListener('click',function(){fetch(mdUrl).then(function(r){return r.text();}).then(function(t){navigator.clipboard.writeText(t).then(flash);});});
  document.addEventListener('click',function(e){if(!fab.contains(e.target))menu.setAttribute('hidden','');});
})();
</script>
{%- endif %}
{%- endif %}
{%- if config.generate_search %}
<div class="search-modal" id="search-modal" hidden>
  <div class="search-modal__backdrop"></div>
  <div class="search-modal__dialog">
    <div class="search-modal__header">
      <svg class="search-modal__icon" xmlns="http://www.w3.org/2000/svg" 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"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
      <input type="text" class="search-modal__input" id="search-input" placeholder="Search..." autocomplete="off" autofocus>
      <kbd class="search-modal__kbd">Esc</kbd>
    </div>
    <div class="search-modal__status" id="search-status"></div>
    <div class="search-modal__results" id="search-results"></div>
  </div>
</div>
<script>
(function() {
  var modal = document.getElementById('search-modal');
  if (!modal) return;
  var input = document.getElementById('search-input');
  var resultsEl = document.getElementById('search-results');
  var statusEl = document.getElementById('search-status');
  var backdrop = modal.querySelector('.search-modal__backdrop');
  var db = null;
  var SQL = null;
  var dbLoading = false;
  var dbReady = false;
  var debounceTimer = null;
  var selectedIdx = -1;

  function openModal() {
    modal.removeAttribute('hidden');
    input.value = '';
    resultsEl.innerHTML = '';
    statusEl.textContent = '';
    selectedIdx = -1;
    setTimeout(function() { input.focus(); }, 50);
    if (!dbReady && !dbLoading) {
      statusEl.textContent = 'Loading search index...';
      initDB().then(function() { statusEl.textContent = ''; });
    }
  }

  function closeModal() {
    modal.setAttribute('hidden', '');
    input.value = '';
    resultsEl.innerHTML = '';
    statusEl.textContent = '';
    selectedIdx = -1;
  }

  function getResultLinks() {
    return resultsEl.querySelectorAll('.search-modal__result');
  }

  function updateSelection() {
    var links = getResultLinks();
    links.forEach(function(el, i) {
      el.classList.toggle('search-modal__result--selected', i === selectedIdx);
    });
    if (selectedIdx >= 0 && links[selectedIdx]) {
      links[selectedIdx].scrollIntoView({ block: 'nearest' });
    }
  }

  // Open on button click
  var toggleBtn = document.querySelector('.search-toggle');
  if (toggleBtn) toggleBtn.addEventListener('click', openModal);

  // Keyboard shortcuts
  document.addEventListener('keydown', function(e) {
    if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
      e.preventDefault();
      if (modal.hasAttribute('hidden')) openModal(); else closeModal();
      return;
    }
    if (modal.hasAttribute('hidden')) return;
    if (e.key === 'Escape') {
      closeModal();
      return;
    }
    var links = getResultLinks();
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (links.length > 0) {
        selectedIdx = (selectedIdx + 1) % links.length;
        updateSelection();
      }
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (links.length > 0) {
        selectedIdx = selectedIdx <= 0 ? links.length - 1 : selectedIdx - 1;
        updateSelection();
      }
    } else if (e.key === 'Enter') {
      if (selectedIdx >= 0 && links[selectedIdx]) {
        e.preventDefault();
        links[selectedIdx].click();
      }
    }
  });

  // Close on backdrop click
  backdrop.addEventListener('click', closeModal);

  async function initDB() {
    if (db) return db;
    if (dbLoading) return null;
    dbLoading = true;
    try {
      if (!SQL) {
        var sqlPromise = window.initSqlJs || null;
        if (!sqlPromise) {
          await new Promise(function(resolve, reject) {
            var script = document.createElement('script');
            script.src = 'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.12.0/sql-wasm.js';
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
          });
        }
        SQL = await initSqlJs({ locateFile: function(file) { return 'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.12.0/' + file; } });
      }
      var response = await fetch('/search.db');
      var buf = await response.arrayBuffer();
      db = new SQL.Database(new Uint8Array(buf));
      dbReady = true;
      return db;
    } catch(err) {
      console.error('Search init failed:', err);
      statusEl.textContent = '';
      resultsEl.innerHTML = '<div class="search-modal__empty">Failed to load search index.</div>';
      return null;
    } finally {
      dbLoading = false;
    }
  }

  async function doSearch(query) {
    if (!query || query.length < 3) {
      resultsEl.innerHTML = '';
      statusEl.textContent = '';
      selectedIdx = -1;
      return;
    }
    var database = await initDB();
    if (!database) return;
    try {
      var term = query.trim().toLowerCase().replace(/%/g, '\\%').replace(/_/g, '\\_');
      var stmt = database.prepare(
        "SELECT title, url, description, content, " +
        "CASE WHEN title_lower = ?1 THEN 100 " +
        "     WHEN title_lower LIKE ?1 || '%' ESCAPE '\\' THEN 80 " +
        "     WHEN title_lower LIKE '%' || ?1 || '%' ESCAPE '\\' THEN 60 " +
        "     ELSE 0 END + " +
        "CASE WHEN description_lower LIKE '%' || ?1 || '%' ESCAPE '\\' THEN 20 ELSE 0 END + " +
        "CASE WHEN content_lower LIKE '%' || ?1 || '%' ESCAPE '\\' THEN 10 ELSE 0 END as score " +
        "FROM pages " +
        "WHERE title_lower LIKE '%' || ?1 || '%' ESCAPE '\\' " +
        "   OR description_lower LIKE '%' || ?1 || '%' ESCAPE '\\' " +
        "   OR content_lower LIKE '%' || ?1 || '%' ESCAPE '\\' " +
        "ORDER BY score DESC LIMIT 10"
      );
      stmt.bind([term]);
      var html = '';
      var count = 0;
      var re = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
      while (stmt.step()) {
        var row = stmt.getAsObject();
        count++;
        // Build snippet: prefer description, fall back to content around first match
        var snippet = '';
        var desc = row.description || '';
        var content = row.content || '';
        if (desc) {
          snippet = escapeHtml(desc);
        } else if (content) {
          var lower = content.toLowerCase();
          var pos = lower.indexOf(term);
          if (pos >= 0) {
            var start = Math.max(0, pos - 40);
            var raw = content.substring(start, start + 120);
            snippet = (start > 0 ? '...' : '') + escapeHtml(raw.trim()) + (start + 120 < content.length ? '...' : '');
          } else {
            snippet = escapeHtml(content.substring(0, 120).trim()) + (content.length > 120 ? '...' : '');
          }
        }
        // Highlight matching terms in title and snippet
        var titleHtml = escapeHtml(row.title).replace(re, '<mark>$1</mark>');
        snippet = snippet.replace(re, '<mark>$1</mark>');
        html += '<a class="search-modal__result" href="' + row.url + '">' +
          '<div class="search-modal__result-title">' + titleHtml + '</div>' +
          '<div class="search-modal__result-url">' + escapeHtml(row.url) + '</div>' +
          '<div class="search-modal__result-snippet">' + snippet + '</div>' +
          '</a>';
      }
      stmt.free();
      selectedIdx = -1;
      if (count === 0) {
        statusEl.textContent = '';
        resultsEl.innerHTML = '<div class="search-modal__empty">No results found.</div>';
      } else {
        statusEl.textContent = count + ' result' + (count === 1 ? '' : 's');
        resultsEl.innerHTML = html;
      }
    } catch(err) {
      console.error('Search query failed:', err);
      statusEl.textContent = '';
      resultsEl.innerHTML = '<div class="search-modal__empty">Search failed.</div>';
    }
  }

  function escapeHtml(s) {
    var d = document.createElement('div');
    d.appendChild(document.createTextNode(s));
    return d.innerHTML;
  }

  input.addEventListener('input', function() {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(function() { doSearch(input.value); }, 100);
  });
})();
</script>
{%- endif %}
{%- block extra_body %}{% endblock extra_body %}
<script>
// For default theme (no stylesheet swap), remove no-transitions now.
// For non-default themes, the head script's onload/timeout handles it.
if (!document.documentElement.classList.contains('no-transitions') ||
    !localStorage.getItem('site-theme') ||
    localStorage.getItem('site-theme') === '{{ config.theme | default(value="zorto") }}') {
  requestAnimationFrame(function(){ document.documentElement.classList.remove('no-transitions'); });
}
</script>
</body>
</html>
