<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { NButton, NEmpty, NIcon } from 'naive-ui'
import { ChevronDownOutline, ChevronUpOutline, CloseCircleOutline, HelpCircleOutline, OptionsOutline, RefreshOutline, SearchOutline } from '@vicons/ionicons5'
import { api } from '../../api/client'
import { useAuthStore } from '../../stores/auth'
import { useToast } from '../../composables/useToast'
import { trackAction } from '../../composables/useAnalytics'
import { useLiteraturePreview } from '../../composables/useLiteraturePreview'
import PageSkeleton from '../../components/common/PageSkeleton.vue'
import type { LiteratureItem, TagOption } from '../../types'

const router = useRouter()
const route = useRoute()
const auth = useAuthStore()
const toast = useToast()

// ── 搜索状态（统一数据源） ──
const searchParams = ref({
  query: '',
  field: 'all',
  tag_ids: [] as string[],
  date_from: null as string | null,
  date_to: null as string | null,
  retracted: '',
  negative_result: '',
  precision_mode: 'majr',
  page_size: 20,
  sort: 'date',
})

const feedItems = ref<LiteratureItem[]>([])
const loading = ref(false)
const searched = ref(false)
const searchTotal = ref(0)

// keyset 游标（用于"加载更多"，page 被忽略）
const cursorDate = ref<string | null>(null)
const cursorId = ref<string | null>(null)
const hasMoreItems = ref(false)

// ── 公开统计 ──
const platformStats = ref({ literature_total: 0, journal_total: 0, daily_avg_30d: 0 })
const statsLoading = ref(true)

// ── 热搜 ──
const hotArticles = ref<any[]>([])
const hotPage = ref(1)
const hotPageSize = 5
const hotTotal = ref(0)
const hotMaxPage = 6 // 最多3页
const hotError = ref(false)

const hotAvailablePages = computed(() => Math.min(hotMaxPage, Math.ceil(hotTotal.value / hotPageSize)))

async function loadHotArticles() {
  try {
    const { data } = await api.get('/public/hot-articles', { params: { page: hotPage.value, page_size: hotPageSize } })
    hotArticles.value = data.items || []
    hotTotal.value = data.total || 0
    hotError.value = false
  } catch (e) { hotError.value = true }
}

function refreshHot() {
  const max = Math.min(hotMaxPage, Math.ceil(hotTotal.value / hotPageSize) || 1)
  hotPage.value = hotPage.value >= max ? 1 : hotPage.value + 1
  loadHotArticles()
}

async function loadStats() {
  try {
    const { data } = await api.get('/public/stats')
    platformStats.value = data
  } catch (e) { /* stats are non-critical */ }
  finally { statsLoading.value = false }
}

// ── 热门标签 ──
const allTags = ref<TagOption[]>([])
const selectedTagIds = ref<string[]>([])
const showAllTags = ref(false)
const isMobile = ref(window.innerWidth < 768)

// ── 高级搜索展开 ──
const showAdvanced = ref(false)

function onDocumentMouseDown(e: MouseEvent) {
  if (!showAdvanced.value) return
  const el = e.target as HTMLElement
  if (!el?.closest('.adv-filter-panel') && !el?.closest('.adv-icon-btn')) {
    showAdvanced.value = false
  }
}

// ── 本地搜索关键词（行内快速搜索） ──
const localQuery = ref('')

// ── 预览抽屉 ──
const { showPreview, previewPmid, openPreview: setPreviewPmid, closePreview } = useLiteraturePreview()

// ── 收藏 ──
const saving = ref<Set<number>>(new Set())
const savedPmids = ref<Set<number>>(new Set())

// ── "上次看到这里" 分隔线（用日期字符串比较，不含时间精度） ──
const lastVisitDateStr = localStorage.getItem('home_last_visit_date')

const dividerIndex = computed(() => {
  if (!lastVisitDateStr || !feedItems.value.length) return -1
  const idx = feedItems.value.findIndex((item: LiteratureItem) => {
    const d = (item.article_date || item.pub_date)?.slice(0, 10)
    return d && d <= lastVisitDateStr
  })
  return idx > 0 ? idx : -1
})

// ── 首页专用加载（不走高级搜索） ──
async function loadHomepageFeed() {
  try {
    const { data } = await api.get('/public/homepage-feed')
    feedItems.value = data.items || []
    hasMoreItems.value = data.has_more ?? false
    const items = data.items || []
    if (items.length > 0) {
      const last = items[items.length - 1]
      cursorDate.value = (last.article_date || last.pub_date)?.slice(0, 10) || null
      cursorId.value = last.id || null
    }
    searched.value = true
  } catch (e) { toast.apiError(e, '加载文献失败') }
}

// ── 数据加载核心 ──
async function fetchData(resetPage = true) {
  if (resetPage) {
    cursorDate.value = null
    cursorId.value = null
  }
  loading.value = true
  try {
    const body: Record<string, any> = { page_size: searchParams.value.page_size, sort: searchParams.value.sort }
    if (searchParams.value.query) body.query = searchParams.value.query
    if (searchParams.value.field !== 'all') body.field = searchParams.value.field
    if (searchParams.value.tag_ids.length) body.tag_ids = searchParams.value.tag_ids
    if (searchParams.value.date_from) body.date_from = searchParams.value.date_from
    if (searchParams.value.date_to) body.date_to = searchParams.value.date_to
    if (searchParams.value.retracted) body.retracted = searchParams.value.retracted
    if (searchParams.value.negative_result) body.negative_result = searchParams.value.negative_result
    if (searchParams.value.precision_mode) body.precision_mode = searchParams.value.precision_mode
    // keyset 游标
    if (cursorDate.value && cursorId.value) {
      body.cursor_date = cursorDate.value
      body.cursor_id = cursorId.value
    }
    const { data } = await api.post('/features/search/advanced', body)
    if (resetPage) {
      feedItems.value = data.items || []
      searchTotal.value = data.total ?? 0
    } else {
      feedItems.value.push(...(data.items || []))
    }
    hasMoreItems.value = data.has_more ?? false
    // 记录游标（取最后一条）
    const items = data.items || []
    if (items.length > 0) {
      const last = items[items.length - 1]
      cursorDate.value = (last.article_date || last.pub_date)?.slice(0, 10) || null
      cursorId.value = last.id || null
    }
    searched.value = true
  } catch (e) { toast.apiError(e, '搜索文献失败，请重试') }
  finally { loading.value = false }
}

// ── 标签筛选（多选） ──
function toggleTag(tagId: string | number) {
  const id = String(tagId)
  const idx = selectedTagIds.value.indexOf(id)
  if (idx >= 0) {
    selectedTagIds.value.splice(idx, 1)
  } else {
    selectedTagIds.value.push(id)
    trackAction('click_tag', 'tag', id)
  }
  searchParams.value.tag_ids = [...selectedTagIds.value]
  fetchData()
}

// ── 癌种标签（过滤 tag_category === 'cancer'，二级标签，有中文名，按文献数倒序） ──
const cancerTags = computed(() => allTags.value
  .filter((t: TagOption) => t.tag_category === 'cancer' && t.level === 2 && t.name_zh)
  .sort((a, b) => ((b.article_count as number) || 0) - ((a.article_count as number) || 0))
)

// 超过 7 个标签时显示"更多"按钮（仅移动端折叠）
const hasMoreTags = computed(() => cancerTags.value.length > 7)

// 折叠时只显示第一行标签，展开时显示全部
const visibleTags = computed(() => {
  if (showAllTags.value) return cancerTags.value
  return cancerTags.value.slice(0, 7)
})

// ── 行内搜索 ──
function doLocalSearch() {
  showAdvanced.value = false
  searchParams.value.field = 'all'
  if (localQuery.value.trim()) {
    searchParams.value.query = localQuery.value
  } else {
    searchParams.value.query = ''
  }
  fetchData()
}

function clearSearch() {
  localQuery.value = ''
  searchParams.value = {
    query: '', field: 'all', tag_ids: [], date_from: null, date_to: null,
    retracted: '', negative_result: '', precision_mode: 'majr',
    page_size: 20, sort: 'date',
  }
  selectedTagIds.value = []
  showAdvanced.value = false
  fetchData()
}

// ── 高级搜索 ──
function handleAdvancedSearch(params: {
  query: string
  field: string
  date_from: string | null
  date_to: string | null
  journal_tiers: string[]
  tag_ids: string[]
  retracted: string
  negative_result: string
  precision_mode: string
  sort: string
}) {
  searchParams.value.query = params.query
  searchParams.value.field = params.field
  searchParams.value.date_from = params.date_from
  searchParams.value.date_to = params.date_to
  searchParams.value.tag_ids = params.tag_ids
  searchParams.value.retracted = params.retracted
  searchParams.value.negative_result = params.negative_result
  searchParams.value.precision_mode = params.precision_mode
  searchParams.value.sort = params.sort
  selectedTagIds.value = [...params.tag_ids]
  showAdvanced.value = false
  fetchData()
}

// ── 收藏 ──
async function saveLiterature(item: LiteratureItem) {
  if (!auth.isAuthenticated) {
    router.push('/auth/login')
    return
  }
  if (saving.value.has(item.pmid) || savedPmids.value.has(item.pmid)) return
  saving.value = new Set(saving.value).add(item.pmid)
  try {
    await api.post(`/literature/${item.pmid}/save`)
    savedPmids.value = new Set(savedPmids.value).add(item.pmid)
    toast.success('已收藏')
  } catch (e) { toast.apiError(e, '收藏文献失败，请重试') }
  finally {
    const s = new Set(saving.value)
    s.delete(item.pmid)
    saving.value = s
  }
}

// ── 预览 ──
function openPreview(item: LiteratureItem) {
  if (item.pmid) setPreviewPmid(item.pmid)
}
function goDetail(item: LiteratureItem) {
  closePreview()
  const q = searchParams.value.query
  router.push(q ? `/literature/${item.pmid}?q=${encodeURIComponent(q)}` : `/literature/${item.pmid}`)
}

// ── 收藏持久化 ──
async function loadSavedPmids() {
  if (!auth.isAuthenticated) return
  try {
    const { data } = await api.get('/literature/saved')
    savedPmids.value = new Set((data.items || []).map((i: any) => i.pmid))
  } catch (e) { toast.apiError(e, '加载收藏状态失败') }
}

// ── 加载更多（追加下一页） ──
const loadingMore = ref(false)
const hasMore = computed(() => hasMoreItems.value)

// ── 回到顶部 ──
const showScrollTop = ref(false)
function onScroll() {
  showScrollTop.value = window.scrollY > window.innerHeight
}
function scrollToTop() {
  window.scrollTo({ top: 0, behavior: 'smooth' })
}
function onResize() {
  isMobile.value = window.innerWidth < 768
}

async function loadMore() {
  if (loadingMore.value || !hasMore.value) return
  loadingMore.value = true
  try {
    const body: Record<string, any> = { page_size: searchParams.value.page_size, sort: 'date' }
    if (searchParams.value.query) body.query = searchParams.value.query
    if (searchParams.value.field !== 'all') body.field = searchParams.value.field
    if (searchParams.value.tag_ids.length) body.tag_ids = searchParams.value.tag_ids
    if (searchParams.value.date_from) body.date_from = searchParams.value.date_from
    if (searchParams.value.date_to) body.date_to = searchParams.value.date_to
    if (searchParams.value.retracted) body.retracted = searchParams.value.retracted
    if (searchParams.value.negative_result) body.negative_result = searchParams.value.negative_result
    if (searchParams.value.precision_mode) body.precision_mode = searchParams.value.precision_mode
    if (cursorDate.value && cursorId.value) {
      body.cursor_date = cursorDate.value
      body.cursor_id = cursorId.value
    }
    const { data } = await api.post('/features/search/advanced', body)
    feedItems.value.push(...(data.items || []))
    hasMoreItems.value = data.has_more ?? false
    // 更新游标
    const items = data.items || []
    if (items.length > 0) {
      const last = items[items.length - 1]
      cursorDate.value = (last.article_date || last.pub_date)?.slice(0, 10) || null
      cursorId.value = last.id || null
    }
  } catch (e) { toast.apiError(e, '加载更多失败，请重试') }
  finally { loadingMore.value = false }
}

// ── 从 URL 恢复状态 ──
function restoreFromUrl() {
  const tag = route.query.tag as string
  const date = route.query.date as string
  const q = route.query.q as string
  if (tag) {
    const ids = tag.split(',')
    selectedTagIds.value = ids
    searchParams.value.tag_ids = ids
  }
  if (date) {
    searchParams.value.date_from = date
    searchParams.value.date_to = date
  }
  if (q) {
    searchParams.value.query = q
    localQuery.value = q
  }
}

// ── 同步状态到 URL ──
const _mounted = ref(false)
const searchKey = computed(() =>
  JSON.stringify([searchParams.value.query, searchParams.value.tag_ids, searchParams.value.date_from, searchParams.value.date_to, searchParams.value.sort])
)

watch(searchKey, () => {
  if (!_mounted.value) return
  const query: Record<string, string> = {}
  if (searchParams.value.tag_ids.length) query.tag = searchParams.value.tag_ids.join(',')
  if (searchParams.value.date_from) query.date = searchParams.value.date_from
  if (searchParams.value.query) query.q = searchParams.value.query
  router.replace({ query })
})

// ── 初始化 ──
onMounted(async () => {
  restoreFromUrl()
  loadStats()
  loadHotArticles()
  // URL 有搜索参数时不加载首页 Feed（后续 fetchData 会覆盖）
  const hasSearchParams = !!(searchParams.value.query || searchParams.value.tag_ids.length ||
      searchParams.value.date_from || searchParams.value.date_to)
  const [tagsResp] = await Promise.all([
    api.get('/public/tags').catch(() => ({ data: { tags: [] } })),
    hasSearchParams ? Promise.resolve() : loadHomepageFeed(),
  ])
  allTags.value = (tagsResp?.data?.tags || [])
  if (hasSearchParams) {
    await fetchData()
  }
  await loadSavedPmids()
  // 记录本次访问日期（用于"上次看到这里"分隔线，只用日期避免时间精度问题）
  localStorage.setItem('home_last_visit_date', new Date().toLocaleDateString('sv'))
  _mounted.value = true
  window.addEventListener('scroll', onScroll)
  window.addEventListener('resize', onResize)
  document.addEventListener('mousedown', onDocumentMouseDown)
})

onBeforeUnmount(() => {
  window.removeEventListener('scroll', onScroll)
  window.removeEventListener('resize', onResize)
  document.removeEventListener('mousedown', onDocumentMouseDown)
})
</script>

<template>
  <div class="home">

    <h1 class="visually-hidden">OncoLit 肿瘤科研文献速递——每日更新的肿瘤学文献平台</h1>

    <!-- ====== 内容网格：左侧（搜索 + 标签 + 文献）+ 右侧（热榜） ====== -->
    <div class="content-grid">
      <div class="content-grid-main">

        <!-- 搜索工具栏 -->
        <section class="section section-toolbar">
          <div class="search-row">
            <div class="search-row-left">
              <div class="search-input-group">
                <div class="search-input-top">
                  <input class="search-input" v-model="localQuery" placeholder="搜索标题、摘要、PMID、DOI..." @keyup.enter="doLocalSearch" />
                  <NButton v-if="localQuery" text size="tiny" @click="clearSearch" class="clear-search-btn" title="清除搜索">
                    <template #icon><NIcon size="16"><CloseCircleOutline /></NIcon></template>
                  </NButton>
                </div>
                <div class="search-input-actions">
                  <NButton text size="tiny" @click="router.push('/help?tab=syntax')" class="help-icon-btn" title="搜索帮助">
                    <template #icon><NIcon size="19"><HelpCircleOutline /></NIcon></template>
                  </NButton>
                  <NButton text size="tiny" @click="showAdvanced = !showAdvanced" :title="showAdvanced?'收起筛选':'高级搜索'" class="adv-icon-btn">
                    <template #icon><NIcon size="18"><OptionsOutline /></NIcon></template>
                  </NButton>
                  <NButton size="small" type="primary" @click="doLocalSearch" class="sky-btn search-submit-btn">
                    <template #icon><NIcon size="14"><SearchOutline /></NIcon></template>搜索
                  </NButton>
                </div>
              </div>
            </div>
          </div>
          <AdvancedSearchPanel
            :show="showAdvanced"
            :loading="loading"
            :tags="allTags"
            @search="handleAdvancedSearch"
          />
        </section>

        <!-- 热门标签快速筛选 -->
        <section class="section" v-if="cancerTags.length">
          <div class="tag-bar">
            <span class="tag-label">热门</span>
            <span v-for="t in visibleTags" :key="t.id" class="tag-pill"
              :class="{ active: selectedTagIds.includes(String(t.id)) }" @click="toggleTag(t.id)">
              {{ t.name_zh || t.name_en }}<span v-if="selectedTagIds.includes(String(t.id))" class="tag-x">✕</span>
            </span>
            <span v-if="hasMoreTags && !showAllTags" class="tag-expand-btn" @click="showAllTags = true">更多 <NIcon size="13" style="vertical-align:-2px"><ChevronDownOutline /></NIcon></span>
            <span v-if="showAllTags" class="tag-expand-btn" @click="showAllTags = false">收起 <NIcon size="13" style="vertical-align:-2px"><ChevronUpOutline /></NIcon></span>
          </div>
        </section>

        <!-- 文献列表 -->
        <section class="section section-list">
          <PageSkeleton :loading="loading && !feedItems.length">
            <NEmpty v-if="!loading && !feedItems.length" description="暂无文献" />
            <div v-if="!loading && !feedItems.length && searched && searchParams.query" class="search-result-count" style="text-align:center;margin-top:8px">共 0 条结果</div>

            <template v-if="feedItems.length">
              <template v-for="(item, idx) in feedItems" :key="item.id || item.pmid">
                <div v-if="idx === dividerIndex" class="read-divider">
                <span class="read-divider-line"></span>
                <span class="read-divider-text">—— 上次看到这里 ——</span>
                <span class="read-divider-line"></span>
              </div>
              <LiteratureCard
                :item="item"
                :showSave="auth.isAuthenticated"
                :savedPmids="savedPmids"
                :searchQuery="searchParams.query"
                @detail="goDetail"
                @preview="openPreview"
                @save="saveLiterature"
              />
            </template>

            <div v-if="searched && searchParams.query" class="search-result-count">共 {{ searchTotal }} 条结果</div>

            <div v-if="hasMore" class="load-more">
              <NButton class="sky-btn" :loading="loadingMore" @click="loadMore" size="small"><template #icon><NIcon size="14"><ChevronDownOutline /></NIcon></template>展示更多</NButton>
            </div>
          </template>
        </PageSkeleton>
        </section>
      </div>
      <div class="content-grid-side">
        <section v-if="hotError" class="section-hot-side" style="padding-top:12px">
          <div class="hot-header"><span>🔥 热搜</span></div>
          <div style="text-align:center;padding:20px 0;font-size:13px;color:var(--text-muted)">加载失败</div>
        </section>
        <section v-else-if="hotArticles.length" class="section-hot-side">
          <div class="hot-header">
            <span>🔥 热搜</span>
            <div class="hot-header-right">
              <span class="hot-page-dots">
                <span v-for="p in hotAvailablePages" :key="p" class="hot-page-dot" :class="{ active: hotPage === p }"></span>
              </span>
              <NButton text size="tiny" style="font-size:12px;color:var(--text-muted)" @click="refreshHot">
                <template #icon><NIcon size="12"><RefreshOutline /></NIcon></template>换一批
              </NButton>
            </div>
          </div>
          <div class="hot-list">
            <a v-for="(art, i) in hotArticles" :key="art.id" class="hot-item" :href="`/literature/${art.pmid}`">
              <span class="hot-rank" :class="{ 'hot-rank-top': (hotPage-1)*hotPageSize + i + 1 <= 3 }">{{ (hotPage-1)*hotPageSize + i + 1 }}</span>
              <div class="hot-content">
                <span class="hot-title" :title="art.title">{{ art.title }}</span>
                <span class="hot-meta">{{ art.journal }} · {{ art.cited_by_count ?? 0 }} 被引</span>
              </div>
            </a>
          </div>
        </section>
        <section v-if="!statsLoading" class="sidebar-stats-section">
          <div class="stats-header">
            <span>📚 OncoLit 肿瘤科研文献</span>
            <span class="stats-header-right">每日更新</span>
          </div>
          <div class="stats-subtitle">PubMed 全量文献数据 +</div>
          <template v-if="platformStats.literature_total > 0">
          <div class="sidebar-stats">
          <div class="sidebar-stat-item">
            <span class="sidebar-stat-num">{{ platformStats.literature_total.toLocaleString() }}</span>
            <span class="sidebar-stat-label">文献总量</span>
          </div>
          <div class="sidebar-stat-item">
            <span class="sidebar-stat-num">{{ platformStats.journal_total }}</span>
            <span class="sidebar-stat-label">收录期刊</span>
          </div>
          <div class="sidebar-stat-item">
            <span class="sidebar-stat-num">{{ platformStats.daily_avg_30d.toFixed(1) }}</span>
            <span class="sidebar-stat-label">日均新增</span>
          </div>
        </div>
        </template>
        <div v-else style="text-align:center;padding:12px;font-size:13px;color:var(--text-muted)">统计信息加载中...</div>
        <div class="sidebar-feedback" @click="router.push('/help?tab=feedback')">
          <svg class="feedback-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><line x1="9" y1="10" x2="15" y2="10"/></svg>
          <span>意见反馈</span>
          <svg class="feedback-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
        </div>
        </section>
      </div>
    </div>

    <!-- ====== 注册引导 CTA（未登录） ====== -->
    <!-- <section v-if="!auth.isAuthenticated && feedItems.length > 3" class="section section-cta">
      <div class="cta-banner">
        <div class="cta-text">
          <div class="cta-title">🔒 注册后获得完整功能</div>
          <div class="cta-desc">收藏文献 · 设置关注领域 · 每日精准推送 · 团队共享</div>
        </div>
        <NButton class="sky-btn" type="primary" size="large" @click="router.push('/auth/register')"><template #icon><NIcon size="14"><PersonAddOutline /></NIcon></template>免费注册</NButton>
      </div>
    </section> -->

    <!-- ====== 文献预览抽屉 ====== -->
    <LiteraturePreviewDrawer
      :show="showPreview"
      :pmid="previewPmid"
      @close="closePreview"
      @goDetail="goDetail"
    />

    <!-- 回到顶部 -->
    <button v-if="showScrollTop" class="scroll-top" @click="scrollToTop">↑</button>
  </div>
</template>

<style scoped>
.home { max-width: 1100px; margin: 0 auto; padding: 0 24px; color: var(--text-primary); }
.section { padding: 3px 0; }
.section-list { padding-bottom: 16px; }
.section-cta { padding: 12px 0 24px; }

/* 内容网格：文献列表 + 热榜侧栏 */
.content-grid { display: flex; gap: 24px; align-items: flex-start; }
.content-grid-main { flex: 3; min-width: 0; }
.content-grid-side { flex: 1; min-width: 260px; max-width: 300px; }
.section-hot-side { padding-top: 12px; }
.section-hot-side .hot-header { font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; display: flex; align-items: center; justify-content: space-between; }
.section-hot-side .hot-header-right { display: flex; align-items: center; gap: 6px; padding-right: 3px; }
.hot-page-dots { display: flex; align-items: center; gap: 4px; }
.hot-page-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border-color); transition: background .15s; }
.hot-page-dot.active { background: var(--kw-pill-color); }
html.dark .hot-page-dot.active { background: #6ab0e0; }
.hot-rank-top { color: #d03050 !important; font-weight: 800 !important; }
.section-hot-side .hot-list { display: flex; flex-direction: column; gap: 3px; }
.section-hot-side .hot-item { display: flex; align-items: flex-start; gap: 3px; padding: 6px 4px; border-radius: 6px; text-decoration: none; transition: background .12s; }
.section-hot-side .hot-item:hover { background: var(--bg-hover); }
.section-hot-side .hot-rank { flex-shrink: 0; width: 20px; text-align: center; font-size: 13px; font-weight: 700; color: #d03050; line-height: 1.6; }
.section-hot-side .hot-content { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.section-hot-side .hot-title { font-size: 16px; color: var(--text-primary); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.section-hot-side .hot-title:hover { color: var(--kw-pill-color); }
html.dark .section-hot-side .hot-title:hover { color: #6ab0e0; }
.section-hot-side .hot-meta { font-size: 14px; color: var(--text-muted); }

/* 热门标签 */
.tag-bar { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 0; align-items: center; }
.tag-label { font-size: 14px; font-weight: 600; color: var(--text-primary); white-space: nowrap; margin-right: 4px; flex-shrink: 0; }
.tag-pill {
  white-space: nowrap; padding: 5px 14px; border-radius: 20px; font-size: 14px; cursor: pointer;
  border: 1px solid var(--border-color); color: var(--text-secondary); background: var(--bg-card); transition: all .12s; user-select: none;
  display: inline-flex; align-items: center; gap: 3px;
}
.tag-pill:hover { border-color: var(--kw-pill-color); color: var(--kw-pill-color); }
html.dark .tag-pill:hover { border-color: #6ab0e0; color: #6ab0e0; }
.tag-pill.active { background: var(--kw-pill-color); color: #fff; border-color: var(--kw-pill-color); }
html.dark .tag-pill.active { background: #2a5a8a; color: #fff; border-color: #2a5a8a; }
.tag-x { font-size: 11px; margin-left: 1px; opacity: .8; }
.tag-expand-btn {
  white-space: nowrap; font-size: 13px; cursor: pointer; user-select: none;
  padding: 3px 10px; border-radius: 20px; border: 1px solid #b3d8ff;
  background: #e6f4ff; color: var(--text-primary);
  align-self: center; line-height: 1.5;
}
.tag-expand-btn:hover { background: #d0ebff; }
html.dark .tag-expand-btn { background: #1a3a5c; border-color: #2a5a8a; color: #6ab0e0; }
html.dark .tag-expand-btn:hover { background: #1e4a6c; }

/* "上次看到这里" 分隔线 */
.read-divider {
  display: flex; align-items: center; gap: 12px;
  padding: 24px 0 12px; user-select: none;
}
.read-divider-line { flex: 1; height: 1px; background: linear-gradient(to right, transparent, var(--border-color) 30%, var(--border-color) 70%, transparent); }
.read-divider-text { font-size: 13px; color: var(--text-muted); white-space: nowrap; }

/* 搜索工具栏 — 小圆角左对齐 */
.section-toolbar { padding: 15px 0 2px; }
.search-row {
  display: flex; justify-content: flex-start; align-items: center;
  gap: 6px; margin-bottom: 2px;
}
.search-row-left { display: flex; flex: 1; }
.search-input-group {
  display: flex; flex-direction: column; flex: 1; min-width: 120px;
  border: 2px solid var(--border-color); border-radius: 6px;
  background: var(--bg-card); padding: 6px 12px 6px;
  transition: border-color .15s;
}
.search-input-group:focus-within { border-color: var(--kw-pill-color); }
html.dark .search-input-group:focus-within { border-color: #6ab0e0; }
.search-input-top { display: flex; align-items: center; gap: 4px; flex: 1; }
.search-input {
  border: none; outline: none; padding: 8px 0 4px; font-size: 16px;
  flex: 1; min-width: 0; background: transparent;
}
.search-input::placeholder { font-size: 14px; color: var(--text-muted); }
html.dark .search-input { color: #fff; }
html.dark .search-input::placeholder { color: #bbb; }
.search-input-actions { display: flex; align-items: center; justify-content: flex-end; gap: 20px; }
.adv-icon-btn { color: var(--kw-pill-color); margin-left: -3px; }
html.dark .adv-icon-btn { color: #6ab0e0; }
.help-icon-btn { color: var(--kw-pill-color); }
html.dark .help-icon-btn { color: #6ab0e0; }
.clear-search-btn { color: var(--text-muted); flex-shrink: 0; }
.search-submit-btn { height: 28px; border-radius: 6px; }

/* 加载更多 */

/* 加载更多 */
.load-more { text-align: center; padding: 20px; }
.search-result-count { padding: 6px 0 2px; font-size: 12px; color: var(--text-muted); text-align: left; }

/* CTA */
.cta-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 20px 24px; background: var(--bg-hover); border-radius: 10px;
}
.cta-title { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.cta-desc { font-size: 12px; color: var(--text-secondary); }

/* 侧栏统计 */
.sidebar-stats-section { padding-top: 15px; }
.stats-header { font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; display: flex; align-items: center; justify-content: space-between; }
.stats-header-right { font-size: 12px; font-weight: 400; color: var(--text-muted); padding-right: 3px; }
.stats-subtitle { font-size: 13px; color: var(--text-muted); margin: -4px 0 5px 25px; }
.sidebar-stats { display: flex; flex-direction: column; gap: 12px; padding: 12px; background: var(--bg-hover); border-radius: 8px; }
.sidebar-stat-item { display: flex; justify-content: space-between; align-items: center; }
.sidebar-stat-num { font-size: 15px; font-weight: 700; color: var(--kw-pill-color); }
html.dark .sidebar-stat-num { color: #6ab0e0; }
.sidebar-stat-label { font-size: 14px; color: var(--text-muted); }

/* 反馈入口 */
.sidebar-feedback {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px; padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px; font-weight: 500; color: var(--kw-pill-color);
  cursor: pointer; user-select: none;
  border: 1px dashed var(--kw-pill-color);
  background: color-mix(in srgb, var(--kw-pill-color) 6%, transparent);
  transition: all .2s;
}
.sidebar-feedback:hover {
  background: color-mix(in srgb, var(--kw-pill-color) 14%, transparent);
  border-style: solid;
}
html.dark .sidebar-feedback { color: #6ab0e0; border-color: #6ab0e0; background: color-mix(in srgb, #6ab0e0 8%, transparent); }
html.dark .sidebar-feedback:hover { background: color-mix(in srgb, #6ab0e0 18%, transparent); }
.feedback-icon { flex-shrink: 0; }
.feedback-arrow { margin-left: auto; flex-shrink: 0; opacity: .5; }


/* 回到顶部 */
.scroll-top {
  position: fixed; right: 30px; bottom: 40px; z-index: 999;
  width: 42px; height: 42px; border-radius: 50%;
  border: none; background: var(--kw-pill-color); color: #fff;
  font-size: 20px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.2);
  transition: opacity .2s;
}
.scroll-top:hover { background: #154360; }
html.dark .scroll-top { background: #2a5a8a; }
html.dark .scroll-top:hover { background: #1a4a7a; }

@media (max-width: 768px) {
  .home { padding: 0 8px; overflow-x: hidden; max-width: 100%; box-sizing: border-box; }
  .search-row { flex-direction: column; align-items: stretch; }
  .search-input-group { padding: 6px 10px 6px; }
  .search-input { font-size: 16px; padding: 8px 0 4px; }
  .section-cta { padding: 8px 0 20px; }
  .cta-banner { flex-direction: column; text-align: center; padding: 16px; }
  .content-grid { flex-direction: column; gap: 8px; max-width: 100%; width: 100%; align-items: stretch; }
  .content-grid-side { max-width: 100%; position: static; margin-top: 0; min-width: 0; width: 100%; }
  .content-grid-main { flex: 1; max-width: 100%; min-width: 0; width: 100%; }
  section.section { max-width: 100%; min-width: 0; width: 100%; }
  .section-hot-side { margin-top: 12px; }
  .tag-pill { padding: 3px 10px; }
  .tag-bar {
    display: flex; flex-wrap: wrap; gap: 4px; overflow: hidden;
    max-width: 100%; width: 100%; box-sizing: border-box; padding: 2px 0;
  }
  .tag-label { flex-shrink: 0; }
  .sidebar-stats { margin-top: 8px; flex-direction: row; flex-wrap: wrap; justify-content: space-around; padding: 10px; max-width: 100%; box-sizing: border-box; }
  .sidebar-stat-item { flex-direction: column; gap: 2px; }
  .search-input-group { max-width: 100%; box-sizing: border-box; }
}

@media (min-width: 1400px) {
  .home { max-width: 1200px; padding: 0 32px; }
  .sidebar-stat-num { font-size: 19px; }
}
</style>
