<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org" 
      th:replace="~{modules/layout :: html(title = null, content = ~{::content}, head = ~{::head})}">
  <th:block th:fragment="head">
    <link rel="stylesheet" th:href="@{/assets/css/index.css}" />
    <!-- Iconify 图标库（社交图标 Iconify 模式） -->
    <script th:src="@{/assets/js/iconify.min.js}" defer></script>
    <script th:src="@{/assets/js/lightbox.js}" defer></script>
    
    <script>

      (function() {
        var scrollY = window.pageYOffset || document.documentElement.scrollTop;
        var windowHeight = window.innerHeight;
        if (scrollY > 0) {
          var style = document.createElement('style');
          var progress = Math.min(scrollY / windowHeight, 1);
          style.textContent = '.hero-background{opacity:' + (1 - progress) + '!important}.hero-background-img{filter:blur(' + (progress * 20) + 'px)!important}';
          document.head.appendChild(style);
        }
      })();
    </script>
    <script th:if="${theme.config.home != null and theme.config.home.weatherConfig != null and theme.config.home.weatherConfig.showWeatherClock}" th:inline="javascript">
      window.WEATHER_CONFIG = {
        apiKey: /*[[${theme.config.home.weatherConfig.seniverseKey}]]*/ '',
        showTime: true,
        showWeather: true,
        showTemperature: true,
        showCity: true
      };
    </script>
    <script th:if="${theme.config.home != null and theme.config.home.weatherConfig != null and theme.config.home.weatherConfig.showWeatherClock}" th:src="@{/assets/js/weather-clock.js}" defer></script>
  </th:block>
  <th:block th:fragment="content">
    <main class="main">
      <div class="hero-background" th:if="${theme.config.home == null || theme.config.home.backgroundConfig == null || theme.config.home.backgroundConfig.showHeroBackground == null || theme.config.home.backgroundConfig.showHeroBackground}"
           th:with="hasApi = ${theme.config.home != null and theme.config.home.backgroundConfig != null and theme.config.home.backgroundConfig.heroBackgroundApi != null and not #strings.isEmpty(theme.config.home.backgroundConfig.heroBackgroundApi)}">
        <th:block th:if="${hasApi}">
          <img class="hero-background-img hero-bg-api-img" 
               alt="" 
               th:data-api="${theme.config.home.backgroundConfig.heroBackgroundApi}"
               th:data-api-mobile="${theme.config.home.backgroundConfig.heroBackgroundApiMobile}" />
        </th:block>
        <th:block th:unless="${hasApi}">
          <th:block th:with="legacyBg = ${(theme.config.home != null and theme.config.home.backgroundConfig != null and theme.config.home.backgroundConfig.heroBackground != null and not #strings.isEmpty(theme.config.home.backgroundConfig.heroBackground)) ? theme.config.home.backgroundConfig.heroBackground : ''},
                             lightBg = ${(theme.config.home != null and theme.config.home.backgroundConfig != null and theme.config.home.backgroundConfig.heroBackgroundLight != null and not #strings.isEmpty(theme.config.home.backgroundConfig.heroBackgroundLight)) ? theme.config.home.backgroundConfig.heroBackgroundLight : (!#strings.isEmpty(legacyBg) ? legacyBg : '/themes/theme-Serenity/assets/public/lightbg.webp')},
                             darkBg = ${(theme.config.home != null and theme.config.home.backgroundConfig != null and theme.config.home.backgroundConfig.heroBackgroundDark != null and not #strings.isEmpty(theme.config.home.backgroundConfig.heroBackgroundDark)) ? theme.config.home.backgroundConfig.heroBackgroundDark : (!#strings.isEmpty(legacyBg) ? legacyBg : '/themes/theme-Serenity/assets/public/darkbg.webp')}">
            <img class="hero-background-img hero-bg-theme-img"
                 alt=""
                 th:attr="data-light=${lightBg},data-dark=${darkBg},data-default-light=@{/assets/public/lightbg.webp},data-default-dark=@{/assets/public/darkbg.webp}" />
            <video class="hero-background-img hero-bg-theme-video"
                   style="display:none"
                   autoplay
                   loop
                   muted
                   playsinline
                   preload="metadata"
                   disablepictureinpicture></video>
          </th:block>
        </th:block>
        <script th:unless="${hasApi}">
          (function() {
            var root = document.documentElement;
            var img = document.querySelector('.hero-bg-theme-img');
            var video = document.querySelector('.hero-bg-theme-video');
            if (!img || !video) return;

            function isVideoUrl(url) {
              if (!url) return false;
              var pure = String(url).split('?')[0].split('#')[0].toLowerCase();
              return pure.endsWith('.mp4') || pure.endsWith('.webm');
            }

            function currentTheme() {
              return root.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
            }

            function themeUrl(theme) {
              var selected = theme === 'light' ? img.getAttribute('data-light') : img.getAttribute('data-dark');
              var fallback = defaultUrl(theme);
              return selected || fallback || '';
            }

            function defaultUrl(theme) {
              return theme === 'light' ? img.getAttribute('data-default-light') : img.getAttribute('data-default-dark');
            }

            function resetVideo() {
              if (!video.getAttribute('src')) return;
              video.pause();
              video.removeAttribute('src');
              video.removeAttribute('data-current-src');
              try { video.load(); } catch (e) {}
            }

            function useImage(url) {
              if (img.getAttribute('src') !== url) {
                img.setAttribute('src', url);
              }
              img.style.display = 'block';
              video.style.display = 'none';
              resetVideo();
            }

            function useVideo(url) {
              if (video.getAttribute('data-current-src') !== url) {
                video.setAttribute('src', url);
                video.setAttribute('data-current-src', url);
                try { video.load(); } catch (e) {}
              }
              video.style.display = 'block';
              img.style.display = 'none';
            }

            function applyThemeBackground() {
              var theme = currentTheme();
              var url = themeUrl(theme);
              if (!url) return;
              if (isVideoUrl(url)) {
                useVideo(url);
              } else {
                useImage(url);
              }
            }

            img.addEventListener('load', function() {
              img.classList.add('loaded');
            });

            img.addEventListener('error', function() {
              var fallback = defaultUrl(currentTheme());
              if (fallback && img.getAttribute('src') !== fallback) {
                img.setAttribute('src', fallback);
              }
            });

            video.addEventListener('loadeddata', function() {
              video.classList.add('loaded');
            });

            video.addEventListener('error', function() {
              useImage(defaultUrl(currentTheme()));
            });

            applyThemeBackground();

            if (window.__homeThemeBgObserver && typeof window.__homeThemeBgObserver.disconnect === 'function') {
              window.__homeThemeBgObserver.disconnect();
            }
            window.__homeThemeBgObserver = new MutationObserver(function(mutations) {
              for (var i = 0; i < mutations.length; i++) {
                if (mutations[i].attributeName === 'data-theme') {
                  applyThemeBackground();
                  break;
                }
              }
            });
            window.__homeThemeBgObserver.observe(root, { attributes: true, attributeFilter: ['data-theme'] });
          })();
        </script>
      </div>
      
      <!-- 首页背景 API 脚本 -->
      <script th:if="${theme.config.home != null && theme.config.home.backgroundConfig != null && !#strings.isEmpty(theme.config.home.backgroundConfig.heroBackgroundApi)}" th:inline="javascript">
        (function() {
          var img = document.querySelector('.hero-bg-api-img');
          if (!img) return;
          
          var api = img.getAttribute('data-api');
          var apiMobile = img.getAttribute('data-api-mobile');
          var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
          var currentApi = isMobile && apiMobile ? apiMobile : api;
          
          var STORAGE_KEY = 'serenity_home_wallpaper_url';
          var sessionKey = 'serenity_home_wallpaper_session';
          
          // 检查是否有缓存
          var cachedUrl = localStorage.getItem(STORAGE_KEY);
          var currentSession = sessionStorage.getItem(sessionKey);

          var finalUrl = (cachedUrl && currentSession) ? cachedUrl : currentApi;
          
          img.src = finalUrl;
          img.decoding = 'async';
          img.loading = 'eager';
          
          img.onload = function() {
            img.classList.add('loaded');

            if (!cachedUrl && img.src && img.src.startsWith('http')) {
              localStorage.setItem(STORAGE_KEY, img.src);
              sessionStorage.setItem(sessionKey, 'true');
            }
          };
          
          img.onerror = function() {

            if (finalUrl !== currentApi) {
              img.src = currentApi;
            }
          };
        })();
      </script>
      
      <section class="hero">
        <div class="container">
          <div class="hero-profile">
            <div class="hero-avatar-wrapper">
              <div class="hero-avatar"
                   th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.avatarGlowColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.avatarGlowColor) ? '--avatar-glow:' + theme.config.hero.colorConfig.avatarGlowColor : ''}">
              <img th:src="${site.logo ?: '/themes/theme-Serenity/assets/public/ics6.webp'}" 
                   th:alt="${site.title}" alt="Avatar" />
            </div>
              <!-- 天气时钟 - 头像下方 -->
              <div class="hero-weather-bar" th:if="${theme.config.home != null && theme.config.home.weatherConfig != null && theme.config.home.weatherConfig.showWeatherClock}"
                   th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.weatherColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.weatherColor) ? '--weather-color:' + theme.config.hero.colorConfig.weatherColor : ''}">
                <span class="weather-item">
                  <span class="weather-text" id="heroTime">--:--</span>
                </span>
                <span class="weather-item">
                  <span class="weather-text" id="heroCity">定位中</span>
                </span>
                <span class="weather-item">
                  <span class="weather-text" id="heroWeather">--</span>
                </span>
                <span class="weather-item">
                  <span class="weather-text" id="heroTemp">--°</span>
                </span>
              </div>
            </div>
            
            <div class="hero-info">
              <h1 class="hero-name" th:if="${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.enableTypewriter == true}"
                  th:classappend="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? ' hero-name-custom' : ''}"
                  th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? 'background:' + theme.config.hero.colorConfig.nameColor + ';-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent' : ''}">
                <span class="typewriter-text" th:attr="data-text=${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.name != null ? theme.config.hero.profileInfo.name : site.title},data-backspace=${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.enableTypewriterBackspace == true ? 'true' : 'false'}">Serenity</span>
                <span class="typewriter-cursor"
                      th:classappend="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? ' typewriter-cursor-custom' : ''}"
                      th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? 'background:' + theme.config.hero.colorConfig.nameColor : ''}"></span>
              </h1>
              <h1 class="hero-name" th:if="${theme.config.hero == null or theme.config.hero.profileInfo == null or theme.config.hero.profileInfo.enableTypewriter != true}" th:text="${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.name != null ? theme.config.hero.profileInfo.name : site.title}"
                  th:classappend="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? ' hero-name-custom' : ''}"
                  th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.nameColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.nameColor) ? 'background:' + theme.config.hero.colorConfig.nameColor + ';-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent' : ''}">Serenity</h1>
              
              <p class="hero-tagline" th:text="${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.tagline != null ? theme.config.hero.profileInfo.tagline : site.subtitle}"
                 th:classappend="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.taglineColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.taglineColor) ? ' hero-tagline-custom' : ''}"
                 th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.taglineColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.taglineColor) ? (#strings.contains(theme.config.hero.colorConfig.taglineColor, 'gradient') ? 'background:' + theme.config.hero.colorConfig.taglineColor + ';-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent' : 'color:' + theme.config.hero.colorConfig.taglineColor) : ''}">一个热爱技术与生活的开发者</p>
              <p class="hero-bio" th:text="${theme.config.hero != null and theme.config.hero.profileInfo != null and theme.config.hero.profileInfo.bio != null ? theme.config.hero.profileInfo.bio : '专注于前端开发，热爱开源，喜欢分享技术与生活。'}"
                 th:classappend="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.bioColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.bioColor) ? ' hero-bio-custom' : ''}"
                 th:style="${theme.config.hero != null and theme.config.hero.colorConfig != null and theme.config.hero.colorConfig.bioColor != null and !#strings.isEmpty(theme.config.hero.colorConfig.bioColor) ? (#strings.contains(theme.config.hero.colorConfig.bioColor, 'gradient') ? 'background:' + theme.config.hero.colorConfig.bioColor + ';-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent' : 'color:' + theme.config.hero.colorConfig.bioColor) : ''}">专注于前端开发，热爱开源，喜欢分享技术与生活。</p>
              
              <div class="hero-social" th:if="${theme.config.social != null && theme.config.social.links != null}">
                <th:block th:each="link : ${theme.config.social.links}">
                  <a th:if="${link.url != null && !#strings.isEmpty(link.url)}" 
                     th:href="${link.icon == 'email' && (link.iconifyIcon == null || #strings.isEmpty(link.iconifyIcon)) ? 'mailto:' + link.url : link.url}"
                     th:title="${link.name}"
                     class="social-link" 
                     target="_blank" 
                     rel="noopener">
                    <!-- Iconify 图标（优先） -->
                    <span th:if="${link.iconifyIcon != null && !#strings.isEmpty(link.iconifyIcon)}" class="iconify" th:attr="data-icon=${link.iconifyIcon}" data-width="20" data-height="20"></span>
                    <!-- 内置图标（fallback） -->
                    <th:block th:if="${link.iconifyIcon == null || #strings.isEmpty(link.iconifyIcon)}">
                      <svg th:if="${link.icon == 'github'}" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
                      <svg th:if="${link.icon == 'twitter'}" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
                      <svg th:if="${link.icon == 'email'}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
                      <svg th:if="${link.icon == 'weibo'}" viewBox="0 0 24 24" fill="currentColor"><path d="M9.31 14.69c-1.48.46-2.77-.16-2.88-1.38-.11-1.22.96-2.59 2.44-3.05 1.48-.46 2.77.16 2.88 1.38.11 1.22-.96 2.59-2.44 3.05zm5.73-3.95c-.25-.07-.42-.12-.29-.44.29-.7.32-1.3.01-1.73-.58-.81-2.17-.77-4.01-.02 0 0-.58.25-.43-.2.28-.9.24-1.65-.19-2.08-.98-.98-3.58.04-5.82 2.28C2.7 10.15 2 11.82 2 13.31c0 2.82 3.61 4.53 7.14 4.53 4.63 0 7.71-2.69 7.71-4.82 0-1.29-1.08-2.02-1.81-2.28zM8.68 17.19c-2.83.28-5.27-1-5.45-2.86-.18-1.86 1.97-3.57 4.8-3.85 2.83-.28 5.27 1 5.45 2.86.18 1.86-1.97 3.57-4.8 3.85z"/><path d="M18.24 7.67c-.82-.82-1.99-1.19-3.13-1.05-.31.04-.52.33-.48.64.04.31.33.52.64.48.82-.1 1.66.17 2.25.76.59.59.86 1.43.76 2.25-.04.31.17.6.48.64h.08c.28 0 .52-.21.56-.48.14-1.14-.23-2.31-1.05-3.13l-.11-.11zm1.46-1.46c-1.58-1.58-3.85-2.29-6.06-1.92-.31.05-.53.34-.48.65.05.31.34.53.65.48 1.93-.32 3.91.3 5.29 1.68 1.38 1.38 2 3.36 1.68 5.29-.05.31.17.6.48.65h.08c.28 0 .52-.21.57-.48.37-2.21-.34-4.48-1.92-6.06l-.29-.29z"/></svg>
                      <svg th:if="${link.icon == 'bilibili'}" viewBox="0 0 24 24" fill="currentColor"><path d="M17.813 4.653h.854c1.51.054 2.769.578 3.773 1.574 1.004.995 1.524 2.249 1.56 3.76v7.36c-.036 1.51-.556 2.769-1.56 3.773s-2.262 1.524-3.773 1.56H5.333c-1.51-.036-2.769-.556-3.773-1.56S.036 18.858 0 17.347v-7.36c.036-1.511.556-2.765 1.56-3.76 1.004-.996 2.262-1.52 3.773-1.574h.774l-1.174-1.12a1.234 1.234 0 0 1-.373-.906c0-.356.124-.658.373-.907l.027-.027c.267-.249.573-.373.92-.373.347 0 .653.124.92.373L9.653 4.44c.071.071.134.142.187.213h4.267a.836.836 0 0 1 .16-.213l2.853-2.747c.267-.249.573-.373.92-.373.347 0 .662.151.929.4.267.249.391.551.391.907 0 .355-.124.657-.373.906zM5.333 7.24c-.746.018-1.373.276-1.88.773-.506.498-.769 1.13-.786 1.894v7.52c.017.764.28 1.395.786 1.893.507.498 1.134.756 1.88.773h13.334c.746-.017 1.373-.275 1.88-.773.506-.498.769-1.129.786-1.893v-7.52c-.017-.765-.28-1.396-.786-1.894-.507-.497-1.134-.755-1.88-.773zM8 11.107c.373 0 .684.124.933.373.25.249.383.569.4.96v1.173c-.017.391-.15.711-.4.96-.249.25-.56.374-.933.374s-.684-.125-.933-.374c-.25-.249-.383-.569-.4-.96V12.44c0-.373.129-.689.386-.947.258-.257.574-.386.947-.386zm8 0c.373 0 .684.124.933.373.25.249.383.569.4.96v1.173c-.017.391-.15.711-.4.96-.249.25-.56.374-.933.374s-.684-.125-.933-.374c-.25-.249-.383-.569-.4-.96V12.44c.017-.391.15-.711.4-.96.249-.249.56-.373.933-.373Z"/></svg>
                      <svg th:if="${link.icon == 'zhihu'}" viewBox="0 0 24 24" fill="currentColor"><path d="M5.721 0C4.12 0 2.82 1.3 2.82 2.9v18.2C2.82 22.7 4.12 24 5.721 24h12.558c1.601 0 2.901-1.3 2.901-2.9V2.9C21.18 1.3 19.88 0 18.279 0H5.72zM8.48 5.079h2.364v9.172H8.48V5.08zm.04 10.672h2.324l2.244 3.862 2.684-3.862h-2.684l-1.64 2.324-1.928-2.324zm5.32-10.672h1.6c1.6 0 2.4.8 2.4 2.4v6.772h-1.6V7.479c0-.8-.4-1.2-1.2-1.2h-1.2v7.972h-1.6V5.08h1.6z"/></svg>
                      <svg th:if="${link.icon == 'telegram'}" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.894 8.221l-1.97 9.28c-.145.658-.537.818-1.084.508l-3-2.21-1.446 1.394c-.14.18-.357.295-.6.295-.002 0-.003 0-.005 0l.213-3.054 5.56-5.022c.24-.213-.054-.334-.373-.121l-6.869 4.326-2.96-.924c-.64-.203-.658-.64.135-.954l11.566-4.458c.538-.196 1.006.128.832.941z"/></svg>
                      <svg th:if="${link.icon == 'discord'}" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>
                    </th:block>
                  </a>
                </th:block>
                <div th:if="${theme.config.social != null && theme.config.social.sponsorConfig != null && theme.config.social.sponsorConfig.enableSponsor && theme.config.social.sponsorConfig.sponsorQrCode != null && !#strings.isEmpty(theme.config.social.sponsorConfig.sponsorQrCode)}" 
                     class="social-link sponsor-link" 
                     title="赞助支持">
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
                  </svg>
                  <div class="sponsor-qrcode">
                    <div class="sponsor-qrcode-img">
                      <img th:src="${theme.config.social.sponsorConfig.sponsorQrCode}" alt="赞助二维码" />
                    </div>
                    <div class="sponsor-qrcode-content">
                      <h4 class="sponsor-qrcode-title" th:text="${theme.config.social.sponsorConfig.sponsorTitle ?: '赞赏支持'}">赞赏支持</h4>
                      <p class="sponsor-qrcode-text" th:text="${theme.config.social.sponsorConfig.sponsorText ?: '感谢你的支持 ❤️'}">感谢你的支持 ❤️</p>
                    </div>
                  </div>
                </div>
                <a th:if="${theme.config.social == null || theme.config.social.rssConfig == null || theme.config.social.rssConfig.showRss == null || theme.config.social.rssConfig.showRss}" 
                   th:href="@{/rss.xml}" 
                   class="social-link" 
                   title="RSS">
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>
                </a>
              </div>
            </div>
          </div>
        </div>

        <div class="theme-decor" th:if="${theme.config.home == null || theme.config.home.decorConfig == null || theme.config.home.decorConfig.showThemeDecor == null || theme.config.home.decorConfig.showThemeDecor}">
          <img th:src="${theme.config.home != null && theme.config.home.decorConfig != null && theme.config.home.decorConfig.customDecorLight != null && !#strings.isEmpty(theme.config.home.decorConfig.customDecorLight) ? theme.config.home.decorConfig.customDecorLight : '/themes/theme-Serenity/assets/public/light.webp'}" alt="" class="theme-decor-light" />
          <img th:src="${theme.config.home != null && theme.config.home.decorConfig != null && theme.config.home.decorConfig.customDecorDark != null && !#strings.isEmpty(theme.config.home.decorConfig.customDecorDark) ? theme.config.home.decorConfig.customDecorDark : '/themes/theme-Serenity/assets/public/dark.webp'}" alt="" class="theme-decor-dark" />
        </div>

        <div class="hero-scroll">
          <svg class="scroll-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="6 9 12 15 18 9"></polyline>
          </svg>
        </div>
      </section>

      <section class="compass-zone" th:if="${theme.config.compass != null and theme.config.compass.compassConfig != null and theme.config.compass.compassConfig.enabled}"
               th:with="customIcons=${theme.config.basic != null ? theme.config.basic.customNavIcons : null}">
        <div class="container">
          <div class="hero-compass">
            <h2 class="compass-title" data-aos="fade-up" th:text="${theme.config.compass.compassConfig.title ?: '风向标'}">风向标</h2>
            <p class="compass-subtitle" data-aos="fade-up" data-aos-delay="100" th:text="${theme.config.compass.compassConfig.subtitle ?: '快速导航到你想去的地方'}">快速导航到你想去的地方</p>
            <div class="compass-grid">
              <!--/* 遍历主菜单（含子菜单），根据风向标开关过滤，图标和文字与导航菜单同步 */-->
              <th:block th:each="menuItem, iterStat : ${menuFinder.getPrimary().menuItems}">
                <!--/* 一级菜单项：内置模板路径匹配 */-->
                <th:block th:with="mHref=${menuItem.status.href}">
                  <a th:if="${
                    (#strings.contains(mHref, '/archives') and theme.config.compass.compassConfig.showArchives) or
                    (#strings.contains(mHref, '/tags') and theme.config.compass.compassConfig.showTags) or
                    (#strings.contains(mHref, '/categories') and theme.config.compass.compassConfig.showCategories) or
                    (#strings.contains(mHref, '/about') and theme.config.compass.compassConfig.showAbout) or
                    (#strings.contains(mHref, '/moments') and theme.config.compass.compassConfig.showMoments) or
                    (#strings.contains(mHref, '/links') and theme.config.compass.compassConfig.showLinks) or
                    (#strings.contains(mHref, '/guestbook') and theme.config.compass.compassConfig.showGuestbook) or
                    (#strings.contains(mHref, '/projects') and theme.config.compass.compassConfig.showProjects) or
                    (#strings.contains(mHref, '/photos') and theme.config.compass.compassConfig.showPhotos) or
                    (#strings.contains(mHref, '/friends-circle') and theme.config.compass.compassConfig.showFriendsCircle) or
                    (#strings.contains(mHref, '/wishes') and (theme.config.compass.compassConfig.showWishes ?: true)) or
                    (#strings.contains(mHref, '/equipments') and (theme.config.compass.compassConfig.showEquipments ?: true))
                  }"
                     th:href="@{${mHref}}"
                     th:target="${menuItem.spec.target?.value}"
                     class="compass-item" data-aos="fade-up"
                     th:attr="data-aos-delay=${iterStat.index * 100}">
                    <th:block th:replace="~{modules/nav-icon :: icon(href=${mHref}, item=${menuItem})}" />
                    <span th:text="${menuItem.status.displayName}">菜单</span>
                  </a>
                  <!--/* 一级菜单项：自定义页面图标匹配（不在内置12个路径中时） */-->
                  <th:block th:if="${
                    !#strings.contains(mHref, '/archives') and !#strings.contains(mHref, '/tags') and
                    !#strings.contains(mHref, '/categories') and !#strings.contains(mHref, '/about') and
                    !#strings.contains(mHref, '/moments') and !#strings.contains(mHref, '/links') and
                    !#strings.contains(mHref, '/guestbook') and !#strings.contains(mHref, '/projects') and
                    !#strings.contains(mHref, '/photos') and !#strings.contains(mHref, '/friends-circle') and
                    !#strings.contains(mHref, '/wishes') and !#strings.contains(mHref, '/equipments')
                  }">
                    <th:block th:if="${customIcons != null}" th:each="ci : ${customIcons}">
                      <a th:if="${ci.slug != null and !#strings.isEmpty(ci.slug) and #strings.contains(mHref, '/' + ci.slug) and (ci.showInCompass == null or ci.showInCompass)}"
                         th:href="@{${mHref}}"
                         th:target="${menuItem.spec.target?.value}"
                         class="compass-item" data-aos="fade-up"
                         th:attr="data-aos-delay=${iterStat.index * 100}">
                        <th:block th:replace="~{modules/nav-icon :: icon(href=${mHref}, item=${menuItem})}" />
                        <span th:text="${menuItem.status.displayName}">菜单</span>
                      </a>
                    </th:block>
                  </th:block>
                </th:block>
                <!--/* 二级子菜单展开 */-->
                <th:block th:if="${not #lists.isEmpty(menuItem.children)}"
                          th:each="childMenu, childStat : ${menuItem.children}"
                          th:with="cHref=${childMenu.status.href}">
                  <a th:if="${
                    (#strings.contains(cHref, '/archives') and theme.config.compass.compassConfig.showArchives) or
                    (#strings.contains(cHref, '/tags') and theme.config.compass.compassConfig.showTags) or
                    (#strings.contains(cHref, '/categories') and theme.config.compass.compassConfig.showCategories) or
                    (#strings.contains(cHref, '/about') and theme.config.compass.compassConfig.showAbout) or
                    (#strings.contains(cHref, '/moments') and theme.config.compass.compassConfig.showMoments) or
                    (#strings.contains(cHref, '/links') and theme.config.compass.compassConfig.showLinks) or
                    (#strings.contains(cHref, '/guestbook') and theme.config.compass.compassConfig.showGuestbook) or
                    (#strings.contains(cHref, '/projects') and theme.config.compass.compassConfig.showProjects) or
                    (#strings.contains(cHref, '/photos') and theme.config.compass.compassConfig.showPhotos) or
                    (#strings.contains(cHref, '/friends-circle') and theme.config.compass.compassConfig.showFriendsCircle) or
                    (#strings.contains(cHref, '/wishes') and (theme.config.compass.compassConfig.showWishes ?: true)) or
                    (#strings.contains(cHref, '/equipments') and (theme.config.compass.compassConfig.showEquipments ?: true))
                  }"
                     th:href="@{${cHref}}"
                     th:target="${childMenu.spec.target?.value}"
                     class="compass-item" data-aos="fade-up"
                     th:attr="data-aos-delay=${(iterStat.index * 100) + ((childStat.index + 1) * 50)}">
                    <th:block th:replace="~{modules/nav-icon :: icon(href=${cHref}, item=${childMenu})}" />
                    <span th:text="${childMenu.status.displayName}">子菜单</span>
                  </a>
                  <!--/* 二级子菜单：自定义页面图标匹配 */-->
                  <th:block th:if="${
                    !#strings.contains(cHref, '/archives') and !#strings.contains(cHref, '/tags') and
                    !#strings.contains(cHref, '/categories') and !#strings.contains(cHref, '/about') and
                    !#strings.contains(cHref, '/moments') and !#strings.contains(cHref, '/links') and
                    !#strings.contains(cHref, '/guestbook') and !#strings.contains(cHref, '/projects') and
                    !#strings.contains(cHref, '/photos') and !#strings.contains(cHref, '/friends-circle') and
                    !#strings.contains(cHref, '/wishes') and !#strings.contains(cHref, '/equipments')
                  }">
                    <th:block th:if="${customIcons != null}" th:each="ci : ${customIcons}">
                      <a th:if="${ci.slug != null and !#strings.isEmpty(ci.slug) and #strings.contains(cHref, '/' + ci.slug) and (ci.showInCompass == null or ci.showInCompass)}"
                         th:href="@{${cHref}}"
                         th:target="${childMenu.spec.target?.value}"
                         class="compass-item" data-aos="fade-up"
                         th:attr="data-aos-delay=${(iterStat.index * 100) + ((childStat.index + 1) * 50)}">
                        <th:block th:replace="~{modules/nav-icon :: icon(href=${cHref}, item=${childMenu})}" />
                        <span th:text="${childMenu.status.displayName}">子菜单</span>
                      </a>
                    </th:block>
                  </th:block>
                </th:block>
              </th:block>
            </div>
          </div>
        </div>
      </section>

      <section class="feed-zone" th:with="showRecentPosts = ${theme.config.home == null || theme.config.home.recentPostsConfig == null || theme.config.home.recentPostsConfig.showRecentPosts == null || theme.config.home.recentPostsConfig.showRecentPosts}, showActivity = ${theme.config.home == null || theme.config.home.activityConfig == null || theme.config.home.activityConfig.showActivity == null || theme.config.home.activityConfig.showActivity}">
        <div class="container">
          <div class="feed-layout" th:classappend="${showRecentPosts && showActivity ? '' : 'feed-layout-single'}">
            <div class="feed-block" th:if="${showRecentPosts}" data-aos="fade-up">
              <div class="block-head">
                <h2 class="block-label">近期笔记</h2>
                <a th:href="@{/archives}" class="block-more">更多 &gt;</a>
              </div>
              
              <div class="article-wrapper">
                <th:block th:replace="~{modules/watermark :: watermark('article-watermark')}" />
                <ul class="article-feed">
                  <th:block th:if="${not #lists.isEmpty(postFinder.list(1, 8).items)}">
                    <li th:each="post, iterStat : ${postFinder.list(1, 8).items}" class="article-row" th:classappend="${post.spec.pinned ? ' article-row-pinned' : ''}">
                      <!-- 置顶标识 -->
                      <span class="article-pin" th:if="${post.spec.pinned}" title="置顶文章">
                        <svg viewBox="0 0 1024 1024" width="16" height="16">
                          <path d="M618.666667 209.066667V213.333333v-4.266666zM870.4 345.6l-196.266667-196.266667h-4.266666c-12.8-12.8-34.133333-21.333333-55.466667-21.333333s-42.666667 8.533333-55.466667 25.6H554.666667v4.266667c-17.066667 21.333333-25.6 46.933333-17.066667 76.8l17.066667 59.733333L435.2 384l-128-21.333333h-4.266667c-17.066667-4.266667-38.4 0-51.2 12.8-8.533333 0-12.8 4.266667-17.066666 8.533333l-51.2 51.2c-12.8 12.8-17.066667 21.333333-17.066667 34.133333 0 12.8 4.266667 21.333333 12.8 29.866667L324.266667 640l-183.466667 183.466667c-8.533333 12.8-12.8 21.333333-12.8 34.133333 0 12.8 4.266667 21.333333 12.8 29.866667s17.066667 8.533333 29.866667 8.533333c12.8 0 21.333333-4.266667 29.866666-12.8L384 699.733333l145.066667 145.066667c8.533333 8.533333 17.066667 12.8 29.866666 12.8 12.8 0 21.333333-4.266667 29.866667-12.8l51.2-51.2c4.266667-4.266667 8.533333-8.533333 8.533333-17.066667 8.533333-17.066667 12.8-34.133333 12.8-55.466666l-21.333333-128 89.6-119.466667 59.733333 17.066667h4.266667c21.333333 4.266667 42.666667 0 59.733333-8.533334 17.066667-12.8 29.866667-25.6 38.4-51.2 8.533333-34.133333 4.266667-59.733333-21.333333-85.333333zM810.666667 405.333333l-89.6-25.6c-17.066667-4.266667-34.133333 0-42.666667 17.066667L563.2 554.666667c-8.533333 8.533333-8.533333 21.333333-8.533333 29.866666l21.333333 145.066667c-4.266667 4.266667-4.266667 8.533333-8.533333 8.533333l-12.8 17.066667L268.8 469.333333l12.8-12.8c4.266667 0 8.533333-4.266667 12.8-8.533333l145.066667 21.333333c12.8 0 21.333333 0 29.866666-8.533333L627.2 341.333333c17.066667-12.8 21.333333-25.6 17.066667-42.666666l-25.6-85.333334L810.666667 405.333333z" fill="currentColor"/>
                        </svg>
                      </span>
                      <a th:href="@{${post.status.permalink}}" class="article-link">
                        <span class="article-index" th:text="${iterStat.count lt 10 ? '0' + iterStat.count : iterStat.count}">01</span>
                        <div class="article-cover">
                          <img th:src="${post.spec.cover ?: 'https://picsum.photos/seed/post/120/80'}" 
                               th:alt="${post.spec.title}" alt="Cover" />
                        </div>
                        <div class="article-detail">
                          <h3 class="article-name" th:text="${post.spec.title}">文章标题</h3>
                          <p class="article-desc" th:with="excerpt = ${post.status.excerpt ?: '暂无摘要...'}" th:text="|${#temporals.format(post.spec.publishTime, 'M月d日')} · ${#strings.length(excerpt) > 30 ? #strings.substring(excerpt, 0, 30) + '...' : excerpt}|">3天前 · 文章摘要...</p>
                        </div>
                        <span class="article-views" th:text="|阅读量 ${post.stats.visit ?: 0}|">阅读量 0</span>
                      </a>
                    </li>
                  </th:block>
                  
                  <th:block th:if="${#lists.isEmpty(postFinder.list(1, 8).items)}">
                    <li class="article-row" style="justify-content:center;padding:3rem 1rem;border:none;">
                      <div style="text-align:center;color:var(--color-text-muted);opacity:0.5;">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="40" height="40" style="margin:0 auto 0.75rem;display:block;"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
                        <p style="font-size:0.9rem;margin:0;">暂无文章</p>
                        <p style="font-size:0.75rem;margin:0.25rem 0 0;opacity:0.6;">发布文章后将在此展示</p>
                      </div>
                    </li>
                  </th:block>
                </ul>
              </div>
            </div>

            <div class="feed-block" th:if="${showActivity}" data-aos="fade-up" data-aos-delay="200" th:with="siteStats = ${siteStatsFinder.getStats()}, recentPosts = ${postFinder.list(1, 5).items}, recentMomentsResult = ${momentFinder != null ? momentFinder.list(1, 5) : null}, photoGroups = ${photoFinder != null ? photoFinder.groupBy() : null}, allTags = ${tagFinder.listAll()}, allCategories = ${categoryFinder.listAll()}">
              <div class="block-head">
                <h2 class="block-label">站点动态</h2>
                <div class="block-stats">
                  <span class="stat-item" th:text="|总访问 ${#numbers.formatInteger(siteStats.visit ?: 0, 1, 'COMMA')}|">总访问 0</span>
                  <span class="stat-divider">·</span>
                  <span class="stat-item" th:text="|文章 ${siteStats.post ?: 0}|">文章 0</span>
                </div>
              </div>
              
              <div class="stream-wrapper">
                <th:block th:replace="~{modules/watermark :: watermark('stream-watermark')}" />
                <ul class="stream-feed" id="stream-feed">
                  <th:block th:if="${not #lists.isEmpty(recentPosts) || (recentMomentsResult != null && recentMomentsResult.items != null && !recentMomentsResult.items.isEmpty()) || (photoGroups != null && !photoGroups.isEmpty())}">
                    <th:block th:each="post : ${recentPosts}">
                      <li class="stream-row" th:data-time="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd HH:mm:ss')}">
                        <span class="stream-marker"></span>
                        <div class="stream-body">
                          <span class="stream-verb">发布了文章</span>
                          <a th:href="@{${post.status.permalink}}" class="stream-object" th:text="${post.spec.title}">文章标题</a>
                        </div>
                        <span class="stream-time" th:text="${#temporals.format(post.spec.publishTime, 'M月d日')}">1月15日</span>
                      </li>
                    </th:block>
                    
                    <th:block th:if="${recentMomentsResult != null && recentMomentsResult.items != null}" th:each="moment : ${recentMomentsResult.items}">
                      <li class="stream-row" th:with="content = ${moment.spec.content}" th:data-time="${moment.spec.releaseTime != null ? #temporals.format(moment.spec.releaseTime, 'yyyy-MM-dd HH:mm:ss') : ''}">
                        <span class="stream-marker"></span>
                        <div class="stream-body">
                          <span class="stream-verb">更新了碎碎念</span>
                          <a href="/moments" class="stream-object stream-moment" th:if="${content != null && content.raw != null}" th:utext="${content.raw}">碎碎念内容</a>
                        </div>
                        <span class="stream-time" th:text="${moment.spec.releaseTime != null ? #temporals.format(moment.spec.releaseTime, 'M月d日') : ''}">1月15日</span>
                      </li>
                    </th:block>
                    
                    <!-- 图库更新 -->
                    <th:block th:if="${photoGroups != null && !photoGroups.isEmpty()}">
                      <th:block th:each="group : ${photoGroups}">
                        <th:block th:each="photo, photoStat : ${group.photos}" th:if="${photoStat.index < 3}">
                          <li class="stream-row" th:data-time="${photo.metadata.creationTimestamp != null ? #temporals.format(photo.metadata.creationTimestamp, 'yyyy-MM-dd HH:mm:ss') : ''}">
                            <span class="stream-marker"></span>
                            <div class="stream-body">
                              <span class="stream-verb">上传了图片</span>
                              <a href="/photos" class="stream-object" th:text="${photo.spec.displayName ?: '新图片'}">图片名称</a>
                            </div>
                            <span class="stream-time" th:if="${photo.metadata.creationTimestamp}" th:text="${#temporals.format(photo.metadata.creationTimestamp, 'M月d日')}">1月15日</span>
                          </li>
                        </th:block>
                      </th:block>
                    </th:block>
                    
                    <!-- 标签更新 -->
                    <th:block th:if="${allTags != null && !allTags.isEmpty()}">
                      <th:block th:each="tag, tagStat : ${allTags}" th:if="${tagStat.index < 5}">
                        <li class="stream-row" th:data-time="${tag.metadata.creationTimestamp != null ? #temporals.format(tag.metadata.creationTimestamp, 'yyyy-MM-dd HH:mm:ss') : ''}">
                          <span class="stream-marker"></span>
                          <div class="stream-body">
                            <span class="stream-verb">添加了标签</span>
                            <a th:href="@{${tag.status.permalink}}" class="stream-object" th:text="${tag.spec.displayName}">标签名称</a>
                          </div>
                          <span class="stream-time" th:if="${tag.metadata.creationTimestamp}" th:text="${#temporals.format(tag.metadata.creationTimestamp, 'M月d日')}">1月15日</span>
                        </li>
                      </th:block>
                    </th:block>
                    
                    <!-- 分类更新 -->
                    <th:block th:if="${allCategories != null && !allCategories.isEmpty()}">
                      <th:block th:each="category, catStat : ${allCategories}" th:if="${catStat.index < 5}">
                        <li class="stream-row" th:data-time="${category.metadata.creationTimestamp != null ? #temporals.format(category.metadata.creationTimestamp, 'yyyy-MM-dd HH:mm:ss') : ''}">
                          <span class="stream-marker"></span>
                          <div class="stream-body">
                            <span class="stream-verb">添加了分类</span>
                            <a th:href="@{${category.status.permalink}}" class="stream-object" th:text="${category.spec.displayName}">分类名称</a>
                          </div>
                          <span class="stream-time" th:if="${category.metadata.creationTimestamp}" th:text="${#temporals.format(category.metadata.creationTimestamp, 'M月d日')}">1月15日</span>
                        </li>
                      </th:block>
                    </th:block>
                  </th:block>
                  
                  <th:block th:if="${#lists.isEmpty(recentPosts) && (recentMomentsResult == null || recentMomentsResult.items == null || recentMomentsResult.items.isEmpty()) && (photoGroups == null || photoGroups.isEmpty())}">
                    <li class="stream-row" style="justify-content:center;padding:3rem 1rem;border:none;">
                      <div style="text-align:center;color:var(--color-text-muted);opacity:0.5;">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="40" height="40" style="margin:0 auto 0.75rem;display:block;"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                        <p style="font-size:0.9rem;margin:0;">暂无动态</p>
                        <p style="font-size:0.75rem;margin:0.25rem 0 0;opacity:0.6;">发布内容后将在此展示</p>
                      </div>
                    </li>
                  </th:block>
                </ul>
              </div>
            </div>
          </div>

          <div class="memo-zone" data-aos="fade-up" th:if="${theme.config.home == null || theme.config.home.memoCardsConfig == null || theme.config.home.memoCardsConfig.showMemoCards == null || theme.config.home.memoCardsConfig.showMemoCards}" th:with="photoGroups = ${photoFinder != null ? photoFinder.groupBy() : null}">
            <div class="block-head">
              <h2 class="block-label">随想碎片</h2>
              <span class="block-subtitle">拾光成句，心事留白</span>
              <div class="memo-nav">
                <button class="memo-nav-btn memo-swiper-prev" aria-label="上一张">&lt;</button>
                <button class="memo-nav-btn memo-swiper-next" aria-label="下一张">&gt;</button>
              </div>
            </div>
            <div class="swiper memo-swiper">
              <div class="swiper-wrapper">
                <!-- 使用官方图库插件 - 按分组展示 -->
                <th:block th:if="${photoGroups != null && !photoGroups.isEmpty()}">
                  <th:block th:each="group : ${photoGroups}">
                    <th:block th:each="photo : ${group.photos}">
                      <div class="swiper-slide memo-card photo-card">
                        <img class="photo-img" th:src="${photo.spec.url}" th:alt="${photo.spec.displayName}" loading="lazy" />
                        <!-- 右上角时间 -->
                        <span class="photo-time" th:if="${photo.metadata.creationTimestamp != null}" th:text="${#strings.substring(photo.metadata.creationTimestamp.toString(), 5, 10)}">01-01</span>
                        <!-- 底部名称 -->
                        <span class="photo-name" th:if="${photo.spec.displayName != null}" th:text="${photo.spec.displayName}">图片名称</span>
                        <!-- 右下角分组标签 -->
                        <span class="photo-group-tag" th:text="${group.spec.displayName}">分组</span>
                      </div>
                    </th:block>
                  </th:block>
                </th:block>
                
                <!-- 未安装插件或无数据时的占位 -->
                <th:block th:if="${photoGroups == null || photoGroups.isEmpty()}">
                  <div class="swiper-slide" style="width:100%!important;display:flex;align-items:center;justify-content:center;min-height:200px;">
                    <div style="text-align:center;color:var(--color-text-muted);opacity:0.5;">
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="40" height="40" style="margin:0 auto 0.75rem;display:block;"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
                      <p style="font-size:0.9rem;margin:0;">暂无照片</p>
                      <p style="font-size:0.75rem;margin:0.25rem 0 0;opacity:0.6;">安装「图库」插件并添加照片后展示</p>
                    </div>
                  </div>
                </th:block>
              </div>
            </div>
          </div>
          
          <div class="life-zone" data-aos="fade-up" th:if="${theme.config.home == null || theme.config.home.lifeMomentsConfig == null || theme.config.home.lifeMomentsConfig.showLifeMoments == null || theme.config.home.lifeMomentsConfig.showLifeMoments}" th:with="momentsResult = ${momentFinder != null ? momentFinder.list(1, 10) : null}">
            <div class="block-head">
              <h2 class="block-label">生活回想</h2>
              <span class="block-subtitle">念念不忘必有回响</span>
              <a href="/moments" class="block-more">更多 &gt;</a>
            </div>
            <div class="swiper life-swiper">
              <div class="swiper-wrapper">
                <th:block th:if="${momentsResult != null && momentsResult.items != null && !momentsResult.items.isEmpty()}">
                  <th:block th:each="moment : ${momentsResult.items}" th:with="content = ${moment.spec.content}">
                    <a href="/moments" class="swiper-slide life-card" th:with="hasMedia = ${content != null && content.medium != null && !content.medium.isEmpty()}, firstMedia = ${hasMedia ? content.medium[0] : null}, isVideo = ${firstMedia != null && firstMedia.type.name() == 'VIDEO'}, isPhoto = ${firstMedia != null && firstMedia.type.name() == 'PHOTO'}, mediaUrl = ${(isPhoto || isVideo) ? firstMedia.url : ''}">
                      <!-- 图片类型 -->
                      <img th:if="${!isVideo}" th:src="${mediaUrl}" alt="" loading="lazy" />
                      <!-- 视频类型 - 显示视频缩略图 -->
                      <th:block th:if="${isVideo}">
                        <video class="life-video" th:src="${mediaUrl}" muted preload="metadata"></video>
                        <span class="video-play-icon">▶</span>
                      </th:block>
                      <span class="life-date" th:text="${moment.spec.releaseTime != null ? #temporals.format(moment.spec.releaseTime, 'yyyy-MM-dd') : ''}">2026-01-10</span>
                      <div class="life-overlay">
                        <span class="life-title" th:text="${moment.spec.tags != null && !moment.spec.tags.isEmpty() ? moment.spec.tags[0] : '生活记录'}">生活记录</span>
                        <span class="life-desc" th:if="${content != null && content.html != null}" th:utext="${content.html}">碎碎念内容</span>
                      </div>
                    </a>
                  </th:block>
                </th:block>
                
                <th:block th:if="${momentsResult == null || momentsResult.items == null || momentsResult.items.isEmpty()}">
                  <div class="swiper-slide" style="width:100%!important;display:flex;align-items:center;justify-content:center;min-height:200px;background:var(--color-bg-soft);border-radius:12px;">
                    <div style="text-align:center;color:var(--color-text-muted);opacity:0.5;">
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="40" height="40" style="margin:0 auto 0.75rem;display:block;"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                      <p style="font-size:0.9rem;margin:0;">暂无动态</p>
                      <p style="font-size:0.75rem;margin:0.25rem 0 0;opacity:0.6;">安装「瞬间」插件并发布动态后展示</p>
                    </div>
                  </div>
                </th:block>
              </div>
            </div>
          </div>
        </div>
      </section>

      <!-- 首页随想碎片灯箱 -->
      <script>
        function initMemoLightbox() {

          if (!window.__memoLightbox && typeof SerenityLightbox !== 'undefined') {
            var memoZone = document.querySelector('.memo-zone');
            if (memoZone) {
              window.__memoLightbox = SerenityLightbox.create({
                className: 'memo-lightbox',
                delegateSelector: '.memo-zone .photo-img'
              });
            }
          }
        }

        document.addEventListener('DOMContentLoaded', function() {
          initMemoLightbox();
          
          var weatherBar = document.querySelector('.hero-weather-bar');
          if (weatherBar) {
            var style = getComputedStyle(weatherBar);
            var weatherColor = style.getPropertyValue('--weather-color').trim();
            var isGradient = weatherColor && weatherColor.includes('gradient');
            
            document.querySelectorAll('.weather-text').forEach(function(el) {
              el.setAttribute('data-gradient', isGradient ? 'true' : 'false');
            });
          }
        });
      </script>
    </main>
  </th:block>
</html>
