    // ===== Anime keywords for categorization =====
    const ANIME_KWS=['仙逆','凡人修仙传','斗破苍穹','斗破','盘龙','完美世界','一念永恒','妖神记','星辰变','遮天','神墓','吞噬星空','武动乾坤','大主宰','全职高手','鬼灭之刃','海贼王','火影忍者','死神','龙珠','进击的巨人','咒术回战','一人之下','狐妖小红娘','魔道祖师','天官赐福','时光代理人','大王饶命','斗罗大陆','绝世唐门','不良人','秦时明月','全职法师','牧神记','三体','灵笼','雾山五行','凡人','仙王的日常生活','百妖谱','眷思量','镖人','伍六七','刺客伍六七','葬送的芙莉莲','间谍过家家']

    // ===== Quotes =====
    const QUOTES=['学而时习之，不亦说乎。','温故而知新，可以为师矣。','三人行，必有我师焉。','学而不思则罔，思而不学则殆。','博学之，审问之，慎思之，明辨之，笃行之。','千里之行，始于足下。','不积跬步，无以至千里。','知之为知之，不知为不知，是知也。','工欲善其事，必先利其器。','玉不琢，不成器；人不学，不知道。','学以致用，知行合一。','学海无涯，勤作舟。','书山有路，勤为径。','宝剑锋从磨砺出，梅花香自苦寒来。','锲而不舍，金石可镂。','业精于勤，荒于嬉。','读书破万卷，下笔如有神。','路漫漫其修远兮，吾将上下而求索。','采菊东篱下，悠然见南山。','海内存知己，天涯若比邻。','长风破浪会有时，直挂云帆济沧海。','会当凌绝顶，一览众山小。','山重水复疑无路，柳暗花明又一村。']

    // ===== Home Page =====
    function homeSearch(){
      const q=document.getElementById('homeSearchInput').value.trim()
      if(q)doSearchFromHome(q)
    }

    function doSearchFromHome(q){
      document.getElementById('homePage').style.display='none'
      document.getElementById('searchView').style.display='block'
      document.getElementById('searchInput').value=q
      window.history.replaceState({},'','/h5?q='+encodeURIComponent(q))
      doSearch()
    }
    function renderHomePage(data){
    fetch("/api/site-config").then(r=>r.json()).then(cfg=>{
      // 显示 Logo（优先图片，其次文字）
      var logoEl=document.getElementById("homeLogo");
      var headerEl=document.getElementById("headerTitle");
      if(cfg.site_logo){
        logoEl.innerHTML='<img src="'+cfg.site_logo+'" class="home-logo-img" alt="logo" />';
        logoEl.style.display="";
        headerEl.innerHTML='<img src="'+cfg.site_logo+'" class="header-logo-img" alt="logo" />';
        headerEl.style.display="";
      }else if(cfg.site_name){
        logoEl.textContent=cfg.site_name;
        logoEl.style.display="";
        headerEl.textContent=cfg.site_name;
        headerEl.style.display="";
      }else{
        logoEl.textContent="CloudSearch";
        logoEl.style.display="";
        headerEl.textContent="CloudSearch";
        headerEl.style.display="";
      }
      if(cfg.site_disclaimer){
        document.getElementById("footerContent").innerHTML=cfg.site_disclaimer.replace(/\n/g,'<br>');
        document.getElementById("siteFooter").style.display="block";
      }
    }).catch(()=>{})
      const categories=data.categories||[]
      const fetchedAt=data.fetchedAt||''
      // Quote
      fetch('https://v1.(function(){
        var q=QUOTES[Math.floor(Math.random()*QUOTES.length)];
        document.getElementById('homeQuote').textContent='「 '+q+' 」';
        document.getElementById('homeQuoteAuthor').textContent='——古籍经典';
      })()

      // Store expanded state per category
      window.__expanded=window.__expanded||{}
      window.__activeTab=window.__activeTab||{}

      const el=document.getElementById('homeRankings')
      let html=''
      for(const cat of categories){
        const icons={movie:'🎬',tv:'📺',western_movie:'🎥',western:'🌍',donghua:'🐉',global_anime:'🌐',variety:'🎤',niche:'💎',hotsite:'🏆'}
        const icon=icons[cat.category]||'📋'
        const key=cat.category
        if(!window.__activeTab[key])window.__activeTab[key]='hot'

        html+='<div class="rank-block">'
        html+='<div class="rank-block-hdr">'+
          '<span class="rank-block-title">'+icon+' '+cat.label+'</span>'+
          '<div class="rank-block-tabs" id="rtabs-'+key+'">'+
            '<span class="rank-tab'+(window.__activeTab[key]==='hot'?' active':'')+'" onclick="switchRankTab(\''+key+'\',\'hot\')">热榜</span>'+
            '<span class="rank-tab'+(window.__activeTab[key]==='newest'?' active':'')+'" onclick="switchRankTab(\''+key+'\',\'newest\')">最新</span>'+
          '</div>'+
        '</div>'
        html+='<div class="rank-block-items" id="ritems-'+key+'" data-hot=\''+JSON.stringify({items:cat.hot||[]}).replace(/'/g,"&#39;")+'\' data-newest=\''+JSON.stringify({items:cat.newest||[]}).replace(/'/g,"&#39;")+'\'>'
        const items=window.__activeTab[key]==='hot'?(cat.hot||[]):(cat.newest||[])
        html+=renderRankItems(items,key,false)
        html+='</div>'
        // 数据来源
        html+='<div class="rank-block-ftr">'+
          '<span>'+(cat.category!=='hotsite'?'数据来源：TMDB':'本站搜索数据')+'</span>'+
          '<span class="ftr-time">'+fetchedAt+'</span>'+
        '</div></div>'
      }
      el.innerHTML=html
    }

    function renderRankItems(items,key,expanded){
      if(!items||items.length===0)return'<div style="padding:10px;text-align:center;color:#c0c4cc;font-size:12px">暂无数据</div>'
      const limit=3
      const show=expanded?items.length:Math.min(limit,items.length)
      let html=items.slice(0,show).map((item,i)=>{
        const c=i<3?' rank-idx top3':' rank-idx'
        return '<div class="rank-item" onclick="doSearchFromHome(\''+item.keyword.replace(/'/g,"\\'")+'\')">'+
          '<span class="'+c+'">'+(i+1)+'</span>'+
          '<span class="rank-name">'+item.keyword+'</span>'+
          '<span class="rank-cnt">'+(item.rating?'⭐'+item.rating:item.searchCount)+'</span>'+
        '</div>'
      }).join('')
      if(items.length>limit&&!expanded){
        html+='<div class="rank-expand" onclick="expandRank(\''+key+'\')">展开全部 ▼</div>'
      }
      return html
    }

    function expandRank(key){
      const container=document.getElementById('ritems-'+key)
      if(!container)return
      const tab=window.__activeTab[key]||'hot'
      const data=JSON.parse(tab==='hot'?container.dataset.hot:container.dataset.newest)
      container.innerHTML=renderRankItems(data.items,key,true)
    }

    function switchRankTab(category,tab){
      window.__activeTab[category]=tab
      const tabsContainer=document.getElementById('rtabs-'+category)
      if(tabsContainer){
        tabsContainer.querySelectorAll('.rank-tab').forEach(t=>t.className='rank-tab')
        tabsContainer.querySelector(tab==='hot'?'.rank-tab:first-child':'.rank-tab:last-child').className='rank-tab active'
      }
      const container=document.getElementById('ritems-'+category)
      if(container){
        const data=JSON.parse(tab==='hot'?container.dataset.hot:container.dataset.newest)
        container.innerHTML=renderRankItems(data.items,category,false)
      }
    }
    let userInfo = null
    let allResults = []
    let allChannels = []
    let activeTab = ''
    let currentSaveItem = null
    const CLOUD_ICONS = {quark:'☁️',baidu:'🔵',aliyun:'🟠','115':'🟣',tianyi:'🔷','123pan':'🔴',uc:'🟡',xunlei:'🟢',pikpak:'🟤',magnet:'🧲',ed2k:'🔗',others:'📁'}
    const CLOUD_LABELS = {quark:'夸克网盘',baidu:'百度网盘',aliyun:'阿里云盘','115':'115网盘',tianyi:'天翼云盘','123pan':'123云盘',uc:'UC网盘',xunlei:'迅雷云盘',pikpak:'PikPak',magnet:'磁力链接',ed2k:'电驴链接',others:'其他'}
    const CLOUD_COLORS = {quark:'#07c160',baidu:'#4e6ef2',aliyun:'#ff6a00','115':'#9b59b6',tianyi:'#00a1d6','123pan':'#e74c3c',uc:'#f39c12',xunlei:'#2ecc71',pikpak:'#8e44ad',magnet:'#95a5a6',ed2k:'#7f8c8d',others:'#95a5a6'}
    const CLOUD_ORDER = {quark:1,baidu:2,aliyun:3,'115':4,tianyi:5,'123pan':6,uc:7,xunlei:8,pikpak:9,magnet:10,ed2k:11,others:12}

    // ===== Fetch helpers =====
    function getToken(){return localStorage.getItem('h5_admin_token')}
    function apiHeaders(){const h={'Content-Type':'application/json'};const t=getToken();if(t)h['Authorization']='Bearer '+t;return h}

    // ===== Toast =====
    let toastTimer
    function showToast(msg,isError){
      const el=document.getElementById('toast')
      el.textContent=msg
      el.className='toast show'+(isError?' error':'')
      clearTimeout(toastTimer)
      toastTimer=setTimeout(()=>el.className='toast',2000)
    }

    // ===== User =====
    async function checkLogin(){
      try{
        const res=await fetch('/api/me',{headers:apiHeaders()})
        if(res.ok){
          const data=await res.json()
          if(data.loggedIn){
            userInfo=data
            document.getElementById('userArea').innerHTML='<span class="user-badge">'+data.username+'</span><button class="logout-btn-small" onclick="logout()">退出</button>'
          }
        }
      }catch(e){}
    }

    function logout(){
      localStorage.removeItem('h5_admin_token')
      userInfo=null
      document.getElementById('userArea').innerHTML='<button class="login-btn-small" onclick="showLogin()">登录</button>'
      showToast('已退出')
    }

    function showLogin(){
      document.getElementById('loginErr').textContent=''
      document.getElementById('loginUser').value=''
      document.getElementById('loginPass').value=''
      document.getElementById('loginModal').style.display='block'
      document.getElementById('overlay').style.display='block'
    }

    function closeLogin(){
      document.getElementById('loginModal').style.display='none'
      document.getElementById('overlay').style.display='none'
    }

    async function handleLogin(){
      const user=document.getElementById('loginUser').value.trim()
      const pass=document.getElementById('loginPass').value
      if(!user||!pass){showToast('请输入用户名和密码',true);return}
      const btn=document.getElementById('loginBtn')
      btn.disabled=true;btn.textContent='登录中...'
      try{
        const res=await fetch('/api/admin/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({username:user,password:pass})})
        if(res.ok){
          const data=await res.json()
          localStorage.setItem('h5_admin_token',data.token)
          userInfo={username:user}
          document.getElementById('userArea').innerHTML='<span class="user-badge">'+user+'</span><button class="logout-btn-small" onclick="logout()">退出</button>'
          closeLogin()
          showToast('登录成功')
        }else{
          const err=await res.json().catch(()=>({}))
          document.getElementById('loginErr').textContent=err.error||'登录失败'
        }
      }catch(e){
        document.getElementById('loginErr').textContent='网络错误'
      }finally{
        btn.disabled=false;btn.textContent='登录'
      }
    }

    // ===== Search =====
    function handleKeydown(e){if(e.key==='Enter')doSearch()}

    let searchTimer
    function doSearch(){
      const q=document.getElementById('searchInput').value.trim()
      if(!q)return
      // Update URL
      window.history.replaceState({},'','/h5?q='+encodeURIComponent(q))
      // Show loading
      document.getElementById('results').innerHTML=''
      document.getElementById('tabs').style.display='none'
      document.getElementById('infoBar').style.display='none'
      document.getElementById('loading').style.display='block'
      document.getElementById('loadingText').textContent='🔍 正在搜索中...'
      document.getElementById('searchBtn').disabled=true

      let progress=0
      const bar=document.getElementById('loadingBar')
      const progressTimer=setInterval(()=>{
        if(progress<60)progress+=1+Math.random()*3
        else if(progress<85)progress+=0.5+Math.random()
        bar.style.width=progress+'%'
      },200)

      // Use streaming search for live updates
      streamSearch(q,progressTimer,bar)
    }

    async function streamSearch(q,progressTimer,bar){
      const startTime=Date.now()
      try{
        const response=await fetch('/api/query',{method:'POST',headers:apiHeaders(),body:JSON.stringify({q})})
        if(!response.ok)throw new Error('搜索失败 ('+response.status+')')

        const reader=response.body.getReader()
        const decoder=new TextDecoder()
        let buffer=''
        let allItems=[]
        let channels=[]
        let totalCount=0
        let filteredCount=0

        while(true){
          const {done,value}=await reader.read()
          if(done)break

          buffer+=decoder.decode(value,{stream:true})
          const lines=buffer.split('\n')
          buffer=lines.pop()||''

          for(const line of lines){
            if(!line.trim())continue
            try{
              const msg=JSON.parse(line)
              if(msg.type==='stats'){
                totalCount=msg.total||0
                filteredCount=msg.filtered||0
                document.getElementById('loadingText').textContent='🔍 搜索到 '+totalCount+' 条，正在验证...'
              }else if(msg.type==='result'){
                if(msg.valid&&msg.id){
                  allItems.push(msg.id)
                }
              }else if(msg.type==='complete'){
                const results=msg.results||[]
                channels=msg.channels||[]
                clearInterval(progressTimer)
                bar.style.width='100%'
                setTimeout(()=>renderResults(results,channels,totalCount,filteredCount,Date.now()-startTime),300)
                return
              }
            }catch(e){}
          }
        }
      }catch(e){
        clearInterval(progressTimer)
        document.getElementById('loading').style.display='none'
        document.getElementById('searchBtn').disabled=false
        document.getElementById('results').innerHTML='<div class="empty">搜索失败：'+e.message+'</div>'
      }
    }

    // ===== Render =====
    function renderResults(results,channels,totalCount,filteredCount,time){
      document.getElementById('loading').style.display='none'
      document.getElementById('searchBtn').disabled=false
      allResults=results
      allChannels=channels||[]

      // Info bar
      if(totalCount>0){
        document.getElementById('infoBar').style.display='flex'
        document.getElementById('infoCount').textContent='已为您挑选到最符合 '+totalCount+' 条结果'
        document.getElementById('infoTime').textContent='⏱ '+time+'ms'
        if(filteredCount>0)document.getElementById('infoFiltered').textContent='❌ 失效 '+filteredCount
        else document.getElementById('infoFiltered').textContent=''
      }else{
        document.getElementById('infoBar').style.display='none'
      }

      // Build tabs
      const tabsEl=document.getElementById('tabs')
      tabsEl.innerHTML=''
      const typeCounts={}
      for(const r of results){const ct=r.cloud_type||'others';typeCounts[ct]=(typeCounts[ct]||0)+1}
      const sorted=Object.keys(typeCounts).sort((a,b)=>(CLOUD_ORDER[a]||99)-(CLOUD_ORDER[b]||99))
      // "全部" tab
      const allTab=document.createElement('div')
      allTab.className='tab active'
      allTab.textContent='📋 全部 ('+results.length+')'
      allTab.onclick=()=>{setActiveTab('');renderCardList(results)}
      tabsEl.appendChild(allTab)
      for(const ct of sorted){
        const tab=document.createElement('div')
        tab.className='tab'
        tab.textContent=(CLOUD_ICONS[ct]||'📁')+' '+(CLOUD_LABELS[ct]||ct)+' ('+typeCounts[ct]+')'
        tab.onclick=()=>{setActiveTab(ct);renderCardList(results.filter(r=>(r.cloud_type||'others')===ct))}
        tabsEl.appendChild(tab)
      }
      tabsEl.style.display=results.length>0?'flex':'none'
      activeTab=''

      // Render cards
      renderCardList(results)
    }

    function setActiveTab(ct){
      activeTab=ct
      document.querySelectorAll('.tab').forEach((t,i)=>{
        const isAll=i===0&&!ct
        const active=i>0&&ct&&t.textContent.includes(CLOUD_LABELS[ct])
        t.className='tab'+(active||isAll?' active':'')
      })
    }

    function renderCardList(items){
      const el=document.getElementById('results')
      if(items.length===0){
        el.innerHTML='<div class="empty">暂无结果</div>'
        return
      }
      el.innerHTML=items.map((item,idx)=>{
        const coverHtml=item.cover
          ? '<img src="'+escapeHtml(item.cover)+'" alt="" onerror="this.parentElement.innerHTML=\'<div class=placeholder>'+escapeHtml(CLOUD_ICONS[item.cloud_type||'others'])+'</div>\'" loading="lazy" />'
          : '<div class="placeholder">'+escapeHtml(CLOUD_ICONS[item.cloud_type||'others'])+'</div>'
        const cloudLabel=CLOUD_LABELS[item.cloud_type]||item.cloud_type||''
        const cloudColor=CLOUD_COLORS[item.cloud_type]||'#95a5a6'
        const tags=extractTags(item.title||'')
        const cleanTitle=(item.title||'').replace(/【[^】]+】/g,'').trim()
        const relativeTime=formatTime(item.update_time||item.datetime||'')
        return '<div class="card" onclick="saveItem('+idx+')">'+
          '<div class="card-cover">'+coverHtml+'<span class="tag" style="background:'+cloudColor+'">'+cloudLabel+'</span></div>'+
          '<div class="card-body">'+
            '<div class="card-title">'+escapeHtml(cleanTitle)+'</div>'+
            '<div class="card-meta"><span>🕐 '+relativeTime+'</span>'+(item.file_size?'<span class="size">📦 '+escapeHtml(item.file_size)+'</span>':'')+'</div>'+
            (tags.length>0?'<div class="card-tags">'+tags.map(t=>'<span'+(isQualityTag(t)?' class="quality"':'')+'>'+escapeHtml(t)+'</span>').join('')+'</div>':'')+
            '<div class="card-actions">'+
              '<span class="card-source">'+(item.source?escapeHtml(item.source):'网盘')+'</span>'+
              '<button class="card-btn" onclick="event.stopPropagation();saveItem('+idx+')">🔗 获取分享链接</button>'+
            '</div>'+
          '</div>'+
        '</div>'
      }).join('')

      // Store items for save reference
      window.__h5Results=items
    }

    function escapeHtml(s){if(!s)return '';return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;')}

    function extractTags(title){
      const tags=[]
      // Quality tags
      const quality=['4K','1080P','2160P','720P','480P','HDR','HDR10','BluRay','REMUX','HEVC','x264','x265','WEB-DL','WEBRip']
      for(const q of quality){if(title.includes(q)&&!tags.includes(q))tags.push(q)}
      const kw=['杜比视界','杜比全景声','高码率','内封简繁英字幕','内嵌字幕','中文字幕','中英字幕']
      for(const k of kw){if(title.includes(k)&&!tags.includes(k))tags.push(k)}
      return tags.slice(0,6)
    }

    function isQualityTag(t){const q=['4K','1080P','2160P','720P','480P','HDR','HDR10','BluRay','REMUX','HEVC','x264','x265','臻彩','高清','WEB-DL','WEBRip'];return q.includes(t)}

    function formatTime(s){
      if(!s)return ''
      const d=new Date(s)
      if(isNaN(d.getTime()))return s.slice(0,10)
      const diff=Date.now()-d.getTime()
      if(diff<0)return s.slice(0,10)
      const mins=Math.floor(diff/60000)
      if(mins<60)return mins<=1?'刚刚':mins+' 分钟前'
      const hours=Math.floor(mins/60)
      if(hours<24)return hours+' 小时前'
      const days=Math.floor(hours/24)
      if(days<30)return days+' 天前'
      return Math.floor(days/30)+' 个月前'
    }

    // ===== Save / Share =====
    function saveItem(idx){
      const items=window.__h5Results||[]
      currentSaveItem=items[idx]
      if(!currentSaveItem)return

      document.getElementById('progressSteps').style.display='block'
      document.getElementById('shareContent').style.display='none'
      document.getElementById('saveError').style.display='none'
      document.getElementById('copyBtn2').style.display='none'

      const title=(currentSaveItem.title||'').replace(/【[^】]+】/g,'').trim()||'资源'
      document.getElementById('shareTitle').textContent=title

      // Show modal
      document.getElementById('overlay').style.display='block'
      document.getElementById('shareModal').style.display='block'

      // Reset steps
      resetSteps()
      advanceStep(1)

      // Call save API
      doSave()
    }

    async function doSave(){
      try{
        const res=await fetch('/api/save',{method:'POST',headers:apiHeaders(),body:JSON.stringify({type:'search',source:currentSaveItem,target_cloud:currentSaveItem.cloud_type||'quark'})})
        const data=await res.json()

        if(!data.success){
          document.getElementById('progressSteps').style.display='none'
          document.getElementById('saveError').style.display='flex'
          document.getElementById('saveError').textContent=data.message||data.error||'保存失败'
          return
        }

        // Step 2
        advanceStep(2)
        await sleep(500)

        // Step 3
        advanceStep(3)
        await sleep(300)

        if(data.share_url){
          advanceStep(4)
          await sleep(200)
          showShareResult(data)
        }else{
          advanceStep(4)
          document.getElementById('progressSteps').style.display='none'
          document.getElementById('saveError').style.display='flex'
          document.getElementById('saveError').textContent='生成分享链接失败'
        }
      }catch(e){
        document.getElementById('progressSteps').style.display='none'
        document.getElementById('saveError').style.display='flex'
        document.getElementById('saveError').textContent=e.message||'保存请求失败'
      }
    }

    function showShareResult(data){
      document.getElementById('progressSteps').style.display='none'
      document.getElementById('shareContent').style.display='block'

      const link=data.share_url
      document.getElementById('shareLinkInput').value=link

      const diskLabel=CLOUD_LABELS[currentSaveItem.cloud_type]||'夸克网盘'
      document.getElementById('qrLabel').textContent=diskLabel+' APP扫码转存'

      // Generate QR
      const qrContainer=document.getElementById('qrContainer')
      qrContainer.innerHTML=''
      new QRCode(qrContainer,{text:link,width:140,height:140})

      // Password
      const pwd=data.share_pwd||data.sharePwd||''
      if(pwd){
        document.getElementById('sharePwdRow').style.display='flex'
        document.getElementById('sharePwdTag').textContent=pwd
      }else{
        document.getElementById('sharePwdRow').style.display='none'
      }

      document.getElementById('copyBtn2').style.display='inline-block'
    }

    function resetSteps(){
      for(let i=1;i<=3;i++){
        const el=document.getElementById('step'+i)
        el.className='step'
        el.querySelector('.step-dot').innerHTML='<span>'+i+'</span>'
        el.querySelector('.step-status').textContent='等待中'
        el.querySelector('.step-status').className='step-status wait'
      }
    }

    function advanceStep(n){
      for(let i=1;i<=3;i++){
        const el=document.getElementById('step'+i)
        if(i<n){
          el.className='step done'
          el.querySelector('.step-dot').innerHTML='<span class="step-check">✓</span>'
          el.querySelector('.step-status').textContent='已完成'
          el.querySelector('.step-status').className='step-status done'
        }else if(i===n){
          el.className='step active'
          el.querySelector('.step-dot').innerHTML='<span>'+i+'</span>'
          const titles=['正在转存到','正在重命名文件（防和谐）','正在生成分享链接']
          el.querySelector('.step-title').textContent=titles[i-1]+'...'
          el.querySelector('.step-status').textContent='进行中'
          el.querySelector('.step-status').className='step-status doing'
        }
      }
    }

    function sleep(ms){return new Promise(r=>setTimeout(r,ms))}

    function copyShareLink(){
      const input=document.getElementById('shareLinkInput')
      if(!input.value)return
      if(navigator.clipboard&&navigator.clipboard.writeText){
        navigator.clipboard.writeText(input.value).then(()=>showToast('链接已复制')).catch(()=>fallbackCopy(input.value))
      }else{
        fallbackCopy(input.value)
      }
    }

    function fallbackCopy(text){
      const ta=document.createElement('textarea')
      ta.value=text;ta.style.position='fixed';ta.style.left='-9999px';document.body.appendChild(ta)
      ta.select()
      try{document.execCommand('copy');showToast('链接已复制')}catch{showToast('复制失败',true)}
      document.body.removeChild(ta)
    }

    function openDisclaimer(){
      window.open('/disclaimer/','_blank')
    }

    function closeModal(){
      document.getElementById('overlay').style.display='none'
      document.getElementById('shareModal').style.display='none'
      document.getElementById('loginModal').style.display='none'
    }

    // ===== Init =====
    checkLogin()

    // Add Enter key handler for home search
    document.getElementById('homeSearchInput').addEventListener('keydown',function(e){if(e.key==='Enter')homeSearch()})
    // Also add for search view input
    document.getElementById('searchInput').addEventListener('keydown',function(e){if(e.key==='Enter')doSearch()})

    // Fetch home page data
    fetch('/api/rankings/categorized').then(r=>r.json()).then(data=>{
      renderHomePage(data)
    }).catch(()=>{
      document.getElementById('homeQuote').textContent='「 学而时习之，不亦说乎。 」'
      document.getElementById('homeQuoteAuthor').textContent='---孔子'
    })

    // Check URL for query
    const params=new URLSearchParams(window.location.search)
    const q=params.get('q')
    if(q){
      document.getElementById('homePage').style.display='none'
      document.getElementById('searchView').style.display='block'
      document.getElementById('searchInput').value=q
      doSearch()
    }

// ===== Dark Mode Toggle =====
(function() {
  var btn = document.createElement('button');
  btn.className = 'theme-btn';
  btn.title = '切换暗色模式';
  var isDark = localStorage.getItem('h5_theme') === 'dark';
  if (!isDark && window.matchMedia('(prefers-color-scheme: dark)').matches) isDark = true;
  btn.textContent = isDark ? '☀️' : '🌙';
  if (isDark) document.documentElement.setAttribute('data-theme', 'dark');
  btn.onclick = function() {
    var dark = document.documentElement.getAttribute('data-theme') !== 'dark';
    document.documentElement.setAttribute('data-theme', dark ? 'dark' : '');
    localStorage.setItem('h5_theme', dark ? 'dark' : 'light');
    btn.textContent = dark ? '☀️' : '🌙';
  };
  document.body.appendChild(btn);
})();
