<template>
  <div class="screen-page lr-page" :class="{ 'is-loading': loading }">
    <div v-if="loadError" class="lr-error" @click="fetchDashboard">{{ loadError }}（点击重试）</div>

    <!-- <div class="lr-year-bar">
      <label class="lr-year-bar__label">统计年份</label>
      <select
        v-model="statYear"
        class="lr-year-bar__select"
        :disabled="loading"
        @change="onYearChange"
      >
        <option v-for="y in availableYears" :key="y" :value="String(y)">{{ y }}年</option>
      </select>
      <span v-if="statDate" class="lr-year-bar__date">统计日 {{ statDate }}</span>
    </div> -->

    <!-- 左栏：核心总览 + 活跃/用户/分类/模型 -->
    <div class="screen-page--home-column">
      <div class="screen-page--home-column-top">
        <div class="top_title">核心数据总览 གཙོ་བོའི་གནས་ཚད་བསྡུས་གསལ།</div>
        <div class="lr-overview-grid">
          <div
            v-for="item in overviewItems"
            :key="item.key"
            class="lr-overview-cell"
          >
            <div class="content_title"><div>{{ item.label }}</div></div>
            <div class="content_num">
              <ScreenScrollNumber
                class="content_num__value"
                :value="item.rawValue"
                :format="item.format"
              />
              <span v-if="item.unit" class="content_num__unit">{{ item.unit }}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">农村三资数据 ཞིང་འབྲོག་རྒྱུ་ནོར་གསུམ།</div>
          <div class="flex_content flex_content--assets">
            <div class="lr-assets">
              <div class="lr-assets__left">
                <div class="lr-assets__card">
                  <div class="lr-assets__icon lr-assets__icon--op" aria-hidden="true">
                    <span>¥</span>
                  </div>
                  <div class="lr-assets__body">
                    <div class="lr-assets__label">经营性固定资产</div>
                    <div class="lr-assets__val">
                      <strong class="lr-assets__num lr-assets__num--op">{{ ruralAssetsDisplay.operating }}</strong>
                      <em>万元</em>
                    </div>
                  </div>
                </div>
                <div class="lr-assets__card">
                  <div class="lr-assets__icon lr-assets__icon--non" aria-hidden="true">
                    <span>▣</span>
                  </div>
                  <div class="lr-assets__body">
                    <div class="lr-assets__label">非经营性固定资产</div>
                    <div class="lr-assets__val">
                      <strong class="lr-assets__num lr-assets__num--non">{{ ruralAssetsDisplay.nonOperating }}</strong>
                      <em>万元</em>
                    </div>
                  </div>
                </div>
              </div>
              <div class="lr-assets__right">
                <div class="lr-assets__ring">
                  <div class="lr-assets__ring-outer">
                    <div class="lr-assets__ring-inner">
                      <div class="lr-assets__ring-val">
                        <strong>{{ ruralAssetsDisplay.fixed }}</strong>
                        <em>万元</em>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="lr-assets__ring-label">固定资产</div>
              </div>
            </div>
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div
            class="flex_title flex_title--clickable"
            role="button"
            tabindex="0"
            @click="threeAssetsProblemDialogVisible = true"
            @keyup.enter="threeAssetsProblemDialogVisible = true"
          >
            三资具体问题上报 རྒྱུ་ནོར་གསུམ་གནད་དོན།
          </div>
          <div class="flex_content flex_content--rank">
            <ul v-if="problemReportRankItems.length" class="lr-rank-bars">
              <li
                v-for="(item, idx) in problemReportRankItems"
                :key="item.levelCode || idx"
                class="lr-rank-bars__row"
              >
                <div class="lr-rank-bars__meta">
                  <span class="lr-rank-bars__label">{{ item.levelName }}</span>
                  <span class="lr-rank-bars__value">{{ item.valueText }}</span>
                </div>
                <div class="lr-rank-bars__track">
                  <div
                    class="lr-rank-bars__fill"
                    :class="'lr-rank-bars__fill--' + (idx + 1)"
                    :style="{
                      width: rankBarsAnimated ? item.barWidth : '0%',
                      transitionDelay: rankBarsAnimated ? `${idx * 120}ms` : '0ms'
                    }"
                  />
                </div>
              </li>
            </ul>
            <span v-else class="lr-empty">暂无上报数据</span>
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div
            class="flex_title flex_title--clickable"
            role="button"
            tabindex="0"
            @click="productOutputDialogVisible = true"
            @keyup.enter="productOutputDialogVisible = true"
          >
            畜牧产品产量 འབྲོག་ལས་ཐོན་རྫས་ཐོན་ཚད།
          </div>
          <div class="flex_content">
            <ScreenChart :option="productOutputTrendOption" />
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div
            class="flex_title flex_title--clickable"
            role="button"
            tabindex="0"
            @click="vaccinationDialogVisible = true"
            @keyup.enter="vaccinationDialogVisible = true"
          >
            疫苗接种 རིམས་འགོག་བཀག་ཐབས།
          </div>
          <div class="flex_content flex_content--vax">
            <div class="lr-vax">
              <div class="lr-vax__chart">
                <ScreenChart :option="vaccinationOverviewOption" />
              </div>
              <div class="lr-vax__stats">
                <div class="lr-vax__row">
                  <span class="lr-vax__label">应免数</span>
                  <strong class="lr-vax__num">{{ vaccinationDisplay.should }}</strong>
                </div>
                <div class="lr-vax__row">
                  <span class="lr-vax__label">实免数</span>
                  <strong class="lr-vax__num">{{ vaccinationDisplay.actual }}</strong>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 右栏：分时热度 + 分布/榜单/词云 -->
    <div class="screen-page--home-column">
      <div class="screen-page--home-column-right lr-heat-panel">
        <div class="top_title">线下预约服务 མངོན་སུམ་དུས་བཀོད་ཞབས་ཞུ།</div>
        <div class="lr-appoint">
          <div class="lr-appoint__left">
            <div
              v-for="item in appointmentLeftItems"
              :key="item.key"
              class="lr-appoint__item"
              :class="{ 'lr-appoint__item--clickable': item.clickable }"
              :role="item.clickable ? 'button' : undefined"
              :tabindex="item.clickable ? 0 : undefined"
              @click="item.clickable && item.onClick && item.onClick()"
              @keyup.enter="item.clickable && item.onClick && item.onClick()"
            >
              <div class="lr-appoint__label">{{ item.label }}</div>
              <div class="lr-appoint__val">
                <ScreenScrollNumber
                  class="lr-appoint__num"
                  :value="item.rawValue"
                  format="int"
                />
                <span class="lr-appoint__unit">{{ item.unit }}</span>
              </div>
            </div>
          </div>
          <div class="lr-appoint__right">
            <ScreenChart :option="appointmentBarOption" />
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">科技特派员 ཚན་རྩལ་མངགས་མི།</div>
          <div class="flex_content">
            <ScreenChart :option="techEnvoyStructureOption" />
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">农业事业单位 ཞིང་ལས་སྤྱི་གཞུང་སྡེ་ཚན།</div>
          <div class="flex_content flex_content--unit-rank">
            <ul v-if="agriUnitRankItems.length" class="lr-unit-rank">
              <li
                v-for="(item, idx) in agriUnitRankItems"
                :key="item.itemCode || idx"
                class="lr-unit-rank__row"
              >
                <span
                  class="lr-unit-rank__badge"
                  :class="'lr-unit-rank__badge--' + (idx + 1)"
                >{{ idx + 1 }}</span>
                <span class="lr-unit-rank__label">{{ item.itemName }}</span>
                <div class="lr-unit-rank__track">
                  <div
                    class="lr-unit-rank__fill"
                    :style="{
                      width: agriUnitBarsAnimated ? item.barWidth : '0%',
                      transitionDelay: agriUnitBarsAnimated ? `${idx * 100}ms` : '0ms'
                    }"
                  >
                    <span class="lr-unit-rank__num">{{ item.count }}</span>
                  </div>
                </div>
              </li>
            </ul>
            <span v-else class="lr-empty">暂无事业单位数据</span>
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">农技课堂 ཞིང་ལས་ལག་རྩལ་སློབ་ཁང་།</div>
          <div class="flex_content flex_content--agri">
            <div v-if="agriClassroomDisplay.hasData" class="lr-agri">
              <div class="lr-agri__side">
                <span class="lr-agri__tri" aria-hidden="true" />
                <div class="lr-agri__side-label">课程视频</div>
                <strong class="lr-agri__side-num">{{ agriClassroomDisplay.video }}</strong>
              </div>
              <div class="lr-agri__center">
                <div class="lr-agri__frame" aria-hidden="true">
                  <i class="lr-agri__corner lr-agri__corner--tl" />
                  <i class="lr-agri__corner lr-agri__corner--tr" />
                  <i class="lr-agri__corner lr-agri__corner--bl" />
                  <i class="lr-agri__corner lr-agri__corner--br" />
                </div>
                <div
                  class="lr-agri__ring"
                  :style="{ background: agriClassroomDisplay.ringBg }"
                >
                  <div class="lr-agri__ring-hole">
                    <strong>{{ agriClassroomDisplay.total }}</strong>
                    <span>培训内容</span>
                  </div>
                </div>
              </div>
              <div class="lr-agri__side">
                <span class="lr-agri__tri" aria-hidden="true" />
                <div class="lr-agri__side-label">实战培训</div>
                <strong class="lr-agri__side-num">{{ agriClassroomDisplay.training }}</strong>
              </div>
            </div>
            <span v-else class="lr-empty">暂无农技课堂数据</span>
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">实战培训报名 ལག་ལེན་སྦྱོང་བརྡར་མིང་ཐོ་འགོད་པ།</div>
          <div class="flex_content">
            <ScreenChart :option="trainingTrendOption" />
          </div>
        </div>
      </div>
    </div>
  </div>

  <ThreeAssetsProblemReportDialog v-model="threeAssetsProblemDialogVisible" />
  <ProductOutputDialog v-model="productOutputDialogVisible" />
  <VaccinationDataDialog v-model="vaccinationDialogVisible" />
  <VetCountDialog v-model="vetCountDialogVisible" />
</template>

<script setup>
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import ScreenChart from '@/components/ScreenChart.vue'
import ScreenScrollNumber from '@/components/ScreenScrollNumber.vue'
import { getLivestockResourceDashboard } from '@/api/livestockResources'
import { useStatYear } from '@/stores/statYear'
import ThreeAssetsProblemReportDialog from './ThreeAssetsProblemReportDialog.vue'
import ProductOutputDialog from './ProductOutputDialog.vue'
import VaccinationDataDialog from './VaccinationDataDialog.vue'
import VetCountDialog from './VetCountDialog.vue'
import {
  buildActivityTrendOption,
  buildAppointmentBarOption,
  buildCategoryShareOption,
  buildHourlyHeatOption,
  buildModelCallOption,
  buildProductOutputTrendOption,
  buildTechEnvoyStructureOption,
  buildTrainingTrendOption,
  buildVaccinationOverviewOption
} from './chartOptions'

const loading = ref(false)
const loadError = ref('')
const { statYear, mergeAvailableYears } = useStatYear()
const statDate = ref('')
/** 接口原始 data，先接入不往各模块赋值 */
const dashboardData = ref(null)
const threeAssetsProblemDialogVisible = ref(false)
const productOutputDialogVisible = ref(false)
const vaccinationDialogVisible = ref(false)
const vetCountDialogVisible = ref(false)

const overview = ref(null)
const ruralThreeAssets = ref(null)
const problemReportShare = ref(null)
/** 进度条入场动画开关：先 0% 再展开到目标宽度 */
const rankBarsAnimated = ref(false)
const productOutputTrend = ref(null)
const vaccinationOverview = ref(null)
const appointment = ref(null)
const techEnvoyStructure = ref(null)
const agriUnitStructure = ref(null)
/** 农业事业单位进度条入场动画 */
const agriUnitBarsAnimated = ref(false)
const agriClassroom = ref(null)
const trainingTrend = ref(null)
const activityTrend = ref(null)
const userStructure = ref(null)
const categoryShare = ref(null)
const modelCallAnalysis = ref([])
const hourlyHeat = ref(null)
const sessionReplyDistribution = ref([])
const hotTopics = ref([])
const topKeywords = ref([])

const activityTrendOption = computed(() => buildActivityTrendOption(activityTrend.value))
const productOutputTrendOption = computed(() =>
  buildProductOutputTrendOption(productOutputTrend.value)
)
const vaccinationOverviewOption = computed(() =>
  buildVaccinationOverviewOption(vaccinationOverview.value)
)
const appointmentBarOption = computed(() => buildAppointmentBarOption(appointment.value))
const techEnvoyStructureOption = computed(() =>
  buildTechEnvoyStructureOption(techEnvoyStructure.value)
)
const trainingTrendOption = computed(() => buildTrainingTrendOption(trainingTrend.value))
const categoryShareOption = computed(() => buildCategoryShareOption(categoryShare.value))
const modelCallOption = computed(() => buildModelCallOption(modelCallAnalysis.value))
const hourlyHeatOption = computed(() => buildHourlyHeatOption(hourlyHeat.value))

/** 疫苗接种右侧应免/实免 */
const vaccinationDisplay = computed(() => {
  const v = vaccinationOverview.value
  return {
    should: formatNum(v?.shouldVaccinateCount),
    actual: formatNum(v?.actualVaccinateCount)
  }
})

/** 线下预约左侧三项台账 */
const appointmentLeftItems = computed(() => {
  const a = appointment.value
  return [
    {
      key: 'vet',
      label: '兽医人员',
      unit: '人',
      rawValue: a?.annualVetCount,
      clickable: true,
      onClick: () => {
        vetCountDialogVisible.value = true
      }
    },
    { key: 'expert', label: '专家人员', unit: '人', rawValue: a?.annualExpertCount },
    { key: 'org', label: '诊疗机构', unit: '家', rawValue: a?.annualOrgCount }
  ]
})

/** 三资问题上报：横向排行条（名称左、次数[百分比]右，均在柱上方） */
const problemReportRankItems = computed(() => {
  const items = [...(problemReportShare.value?.items || [])]
  if (!items.length) {
    return []
  }
  const sorted = items.sort((a, b) => Number(b.count || 0) - Number(a.count || 0))
  const maxCount = Math.max(...sorted.map((item) => Number(item.count || 0)), 0)
  const total =
    Number(problemReportShare.value?.totalCount) ||
    sorted.reduce((sum, item) => sum + Number(item.count || 0), 0)
  return sorted.map((item) => {
    const count = Number(item.count || 0)
    let ratio = item.ratio != null && item.ratio !== '' ? Number(item.ratio) : NaN
    if (!Number.isFinite(ratio)) {
      ratio = total > 0 ? (count / total) * 100 : 0
    }
    const widthPct = maxCount > 0 ? Math.max(count > 0 ? 6 : 0, Math.min(100, (count / maxCount) * 100)) : 0
    const ratioStr = `${Number(ratio).toFixed(1)}%`
    return {
      levelCode: item.levelCode,
      levelName: item.levelName || item.levelCode || '未知',
      count,
      // 格式：value[百分比]，如 128[45.2%]
      valueText: `${count}[${ratioStr}]`,
      barWidth: `${widthPct}%`
    }
  })
})

/** 农业事业单位：职级人数排行（按人数降序） */
const agriUnitRankItems = computed(() => {
  const items = [...(agriUnitStructure.value?.rankItems || [])]
  if (!items.length) {
    return []
  }
  const sorted = items.sort((a, b) => Number(b.count || 0) - Number(a.count || 0))
  const maxCount = Math.max(...sorted.map((item) => Number(item.count || 0)), 0)
  return sorted.map((item) => {
    const count = Number(item.count || 0)
    const widthPct =
      maxCount > 0 ? Math.max(count > 0 ? 12 : 0, Math.min(100, (count / maxCount) * 100)) : 0
    return {
      itemCode: item.itemCode,
      itemName: item.itemName || item.itemCode || '未知',
      count,
      barWidth: `${widthPct}%`
    }
  })
})

/** 数据到位后：先收束为 0，再错开展开进度条 */
watch(
  problemReportRankItems,
  async (items) => {
    rankBarsAnimated.value = false
    if (!items.length) {
      return
    }
    await nextTick()
    requestAnimationFrame(() => {
      rankBarsAnimated.value = true
    })
  },
  { deep: true }
)

watch(
  agriUnitRankItems,
  async (items) => {
    agriUnitBarsAnimated.value = false
    if (!items.length) {
      return
    }
    await nextTick()
    requestAnimationFrame(() => {
      agriUnitBarsAnimated.value = true
    })
  },
  { deep: true }
)

/** 农技课堂：课程视频 / 实战培训 / 培训内容合计 */
const agriClassroomDisplay = computed(() => {
  const a = agriClassroom.value
  const video = Number(a?.videoCourseCount || 0)
  const training = Number(a?.practicalTrainingCount || 0)
  const total =
    a?.trainingContentTotal != null && a.trainingContentTotal !== ''
      ? Number(a.trainingContentTotal)
      : video + training
  const hasData = a?.hasAgriData === true || total > 0
  const videoDeg = total > 0 ? (video / total) * 360 : 0
  const ringBg = `conic-gradient(from -90deg,
    #5ef0c8 0deg ${videoDeg}deg,
    rgba(61, 217, 176, 0.18) ${videoDeg}deg 360deg)`
  return {
    video: formatNum(video),
    training: formatNum(training),
    total: formatNum(total),
    hasData,
    ringBg
  }
})

/** 农村三资：左右展示 */
const ruralAssetsDisplay = computed(() => {
  const a = ruralThreeAssets.value
  return {
    operating: formatMoney(a?.operatingFixedAssets),
    nonOperating: formatMoney(a?.nonOperatingFixedAssets),
    fixed: formatMoney(a?.fixedAssets)
  }
})

/** 核心总览 8 项：三资 + 产量 + 免疫率 + 人员 */
const overviewItems = computed(() => {
  const o = overview.value
  return [
    {
      key: 'operatingFixedAssets',
      label: '经营性固定资产',
      unit: '万元',
      rawValue: o?.operatingFixedAssets,
      format: 'money'
    },
    {
      key: 'nonOperatingFixedAssets',
      label: '非经营性固定资产',
      unit: '万元',
      rawValue: o?.nonOperatingFixedAssets,
      format: 'money'
    },
    {
      key: 'meatOutput',
      label: '肉产量',
      unit: '万吨',
      rawValue: o?.meatOutput,
      format: 'area'
    },
    {
      key: 'milkOutput',
      label: '奶产量',
      unit: '万吨',
      rawValue: o?.milkOutput,
      format: 'area'
    },
    {
      key: 'immunityRate',
      label: '免疫率',
      unit: '%',
      rawValue: o?.immunityRate,
      format: 'area'
    },
    {
      key: 'vetCount',
      label: '兽医',
      unit: '人',
      rawValue: o?.vetCount,
      format: 'int'
    },
    {
      key: 'techEnvoyCount',
      label: '科技特派员',
      unit: '人',
      rawValue: o?.techEnvoyCount,
      format: 'int'
    },
    {
      key: 'agriUnitCount',
      label: '农业事业单位',
      unit: '人',
      rawValue: o?.agriUnitCount,
      format: 'int'
    }
  ]
})

function formatNum(val) {
  if (val === null || val === undefined || val === '') {
    return '0'
  }
  const n = Number(val)
  if (Number.isNaN(n)) {
    return '0'
  }
  return n.toLocaleString('zh-CN')
}

function formatMoney(val) {
  if (val === null || val === undefined || val === '') {
    return '0'
  }
  const n = Number(val)
  if (Number.isNaN(n)) {
    return '0'
  }
  return n.toLocaleString('zh-CN', {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2
  })
}

function display(val) {
  return formatNum(val)
}

function formatRatio(val) {
  const n = Number(val)
  if (Number.isNaN(n)) {
    return '0.0'
  }
  return n.toFixed(1)
}

/** 兼容拦截器返回 AjaxResult，或直接返回 data 本体 */
function resolveDashboard(res) {
  if (!res) {
    return null
  }
  const payload = res.data !== undefined ? res.data : res
  if (payload && payload.data && payload.overview == null && payload.data.overview) {
    return payload.data
  }
  return payload
}

function normalizeActivityTrend(raw) {
  if (!raw) {
    return null
  }
  if (Array.isArray(raw)) {
    return { dailySeries: raw }
  }
  return raw
}

function normalizeHourlyHeat(raw) {
  if (!raw) {
    return null
  }
  if (Array.isArray(raw)) {
    return { hourlySeries: raw }
  }
  return raw
}

function normalizeReplyStatus(raw) {
  if (!raw) {
    return null
  }
  if (Array.isArray(raw)) {
    return { items: raw }
  }
  return raw
}

function pickHotTopics(data, categoryItems) {
  if (data.hotTopics?.length) {
    return data.hotTopics
  }
  return [...(categoryItems || [])]
    .filter((item) => toNum(item?.count) > 0)
    .sort((a, b) => toNum(b.count) - toNum(a.count))
    .slice(0, 5)
}

function toNum(val) {
  const n = Number(val)
  return Number.isNaN(n) ? 0 : n
}

function applyDashboard(data) {
  if (!data) {
    return
  }
  mergeAvailableYears(data.availableYears)
  dashboardData.value = data
  statDate.value = data.statDate || ''
  // 核心数据总览
  overview.value = data.overview || null
  // 农村三资数据
  ruralThreeAssets.value = data.ruralThreeAssets || null
  // 三资具体问题上报
  problemReportShare.value = data.problemReportShare || null
  // 畜牧产品产量
  productOutputTrend.value = data.productOutputTrend || null
  // 疫苗接种
  vaccinationOverview.value = data.vaccinationOverview || null
  // 线下预约服务
  appointment.value = data.appointment || null
  // 科技特派员
  techEnvoyStructure.value = data.techEnvoyStructure || null
  // 农业事业单位
  agriUnitStructure.value = data.agriUnitStructure || null
  // 农技课堂
  agriClassroom.value = data.agriClassroom || null
  // 实战培训报名
  trainingTrend.value = data.trainingTrend || null
}

async function fetchDashboard() {
  loading.value = true
  loadError.value = ''
  try {
    const res = await getLivestockResourceDashboard(statYear.value)
    applyDashboard(resolveDashboard(res))
  } catch (e) {
    dashboardData.value = null
    overview.value = null
    ruralThreeAssets.value = null
    problemReportShare.value = null
    rankBarsAnimated.value = false
    productOutputTrend.value = null
    vaccinationOverview.value = null
    appointment.value = null
    techEnvoyStructure.value = null
    agriUnitStructure.value = null
    agriUnitBarsAnimated.value = false
    agriClassroom.value = null
    trainingTrend.value = null
    loadError.value = e?.message || '看板数据加载失败'
  } finally {
    loading.value = false
  }
}

function onYearChange() {
  fetchDashboard()
}

watch(statYear, () => {
  fetchDashboard()
})

onMounted(() => {
  fetchDashboard()
})
</script>

<style scoped>
.lr-page {
  position: relative;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 20px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.lr-page.is-loading {
  opacity: 0.92;
}

.lr-error {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  padding: 4px 12px;
  font-size: 12px;
  color: #ffb4b4;
  background: rgba(80, 20, 20, 0.75);
  border-radius: 4px;
  cursor: pointer;
}

.lr-year-bar {
  position: absolute;
  top: 8px;
  right: 24px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
}

.lr-year-bar__label {
  font-size: 12px;
  color: var(--screen-text-secondary, #a8d4c8);
}

.lr-year-bar__select {
  min-width: 88px;
  height: 28px;
  padding: 0 8px;
  font-size: 13px;
  color: #e8eef5;
  background: rgba(4, 48, 40, 0.85);
  border: 1px solid var(--screen-line-dim, rgba(61, 217, 176, 0.42));
  border-radius: 4px;
  outline: none;
}

.lr-year-bar__date {
  font-size: 11px;
  color: var(--screen-text-secondary, #a8d4c8);
}

.screen-page--home-column {
  width: 617px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.screen-page--home-column-top {
  width: 617px;
  height: 201px;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: url('../../assets/live/live.png') no-repeat center center;
  background-size: 100% 100%;
}

.screen-page--home-column-right {
  width: 617px;
  height: 201px;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: url('../../assets/home/box_right.png') no-repeat center center;
  background-size: 100% 100%;
}

.lr-heat-panel {
  overflow: hidden;
}

.lr-appoint {
  flex: 1;
  min-height: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  padding: 0 12px 10px 28px;
  gap: 8px;
}

.lr-appoint__left {
  width: 120px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
  padding: 8px 5px 4px 8px;
  box-sizing: border-box;
  text-align: center;
}

.lr-appoint__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
}

.lr-appoint__item--clickable {
  cursor: pointer;
}

.lr-appoint__item--clickable:hover .lr-appoint__label {
  color: #ecd27b;
}

.lr-appoint__label {
  font-size: 12px;
  color: #a8d4c8;
  line-height: 1.2;
}

.lr-appoint__val {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  line-height: 1.15;
  width: 100%;
  text-align: right;
}

.lr-appoint__num {
  font-size: 20px;
  font-weight: 700;
}

.lr-appoint__val :deep(.screen-scroll-number) {
  font-size: 20px;
  font-weight: 700;
  justify-content: flex-end;
}

.lr-appoint__val :deep(.screen-scroll-number__strip),
.lr-appoint__val :deep(.screen-scroll-number__sep) {
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lr-appoint__unit {
  font-size: 11px;
  color: #7aa89a;
}

.lr-appoint__right {
  flex: 1;
  min-width: 0;
  min-height: 0;
}

.lr-heat-chart {
  flex: 1;
  min-height: 0;
  box-sizing: border-box;
  padding: 0 8px 8px;
}

.screen-page--home-column-flex {
  width: 617px;
  height: 223px;
  display: flex;
  justify-content: space-between;
}

.screen-page--home-column-flex-item {
  width: 304px;
  height: 223px;
  background: url('../../assets/home/mini_box.png') no-repeat center center;
  background-size: 100% 100%;
}

.top_title {
  width: 100%;
  height: 35px;
  box-sizing: border-box;
  font-size: 18px;
  color: #fff;
  line-height: 35px;
  padding-left: 100px;
  margin-bottom: 8px;
  flex-shrink: 0;
}

/* 核心总览：4 列 × 2 行，对齐交易总览样式 */
.lr-overview-grid {
  flex: 1;
  min-height: 0;
  box-sizing: border-box;
  padding: 4px 20px 12px 28px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 2px 16px;
}

.lr-overview-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  min-height: 0;
  width: 100%;
  text-align: right;
  box-sizing: border-box;
  padding-right: 6px;
}

.lr-overview-cell .content_title {
  width: 100%;
  text-align: right;
}

.lr-overview-cell .content_num {
  width: 100%;
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 4px;
  margin: 2px 0 0;
  line-height: 1.2;
}

.content_num__value {
  flex: 1;
  min-width: 0;
  text-align: right;
  font-size: 20px;
  font-weight: 600;
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.content_num :deep(.screen-scroll-number) {
  flex: 1;
  min-width: 0;
  justify-content: flex-end;
  font-size: 20px;
  font-weight: 600;
}

.content_num :deep(.screen-scroll-number__strip),
.content_num :deep(.screen-scroll-number__sep) {
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.content_num__unit {
  flex-shrink: 0;
  font-size: 11px;
  color: #a8d4c8;
  line-height: 1.2;
}

.content_title {
  font-size: 10px;
  color: #a8d4c8;
  line-height: 1.25;
}

.flex_title {
  width: 100%;
  box-sizing: border-box;
  height: 35px;
  font-size: 16px;
  color: #fff;
  line-height: 35px;
  padding-left: 45px;
  margin-bottom: 5px;
}

.flex_title--clickable {
  cursor: pointer;
}

.flex_title--clickable:hover {
  color: #ecd27b;
}

.flex_content {
  width: 100%;
  height: 180px;
  box-sizing: border-box;
  padding: 5px;
}

.flex_content--user {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px 8px;
}

.flex_content--assets {
  display: flex;
  align-items: center;
  padding: 2px 8px 8px 10px;
}

/* 农村三资：左两项 + 右合计环 */
.lr-assets {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
}

.lr-assets__left {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}

.lr-assets__card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  min-height: 58px;
  padding: 6px 8px;
  box-sizing: border-box;
  border: 1px solid rgba(61, 217, 176, 0.28);
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(4, 48, 40, 0.55) 0%, rgba(8, 36, 48, 0.25) 100%);
  box-shadow: inset 0 0 12px rgba(69, 240, 184, 0.06);
}

.lr-assets__icon {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  color: #e8eef5;
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.lr-assets__icon--op {
  background: linear-gradient(145deg, rgba(59, 130, 246, 0.45), rgba(14, 70, 140, 0.55));
  box-shadow: 0 0 10px rgba(59, 130, 246, 0.35);
}

.lr-assets__icon--non {
  background: linear-gradient(145deg, rgba(245, 158, 11, 0.45), rgba(154, 80, 12, 0.55));
  box-shadow: 0 0 10px rgba(245, 158, 11, 0.3);
}

.lr-assets__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lr-assets__label {
  font-size: 11px;
  color: #a8d4c8;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lr-assets__val {
  display: flex;
  align-items: baseline;
  gap: 4px;
  line-height: 1.15;
}

.lr-assets__num {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lr-assets__num--op {
  color: #5eb8ff;
  text-shadow: 0 0 8px rgba(94, 184, 255, 0.35);
}

.lr-assets__num--non {
  color: #f0a04b;
  text-shadow: 0 0 8px rgba(240, 160, 75, 0.35);
}

.lr-assets__val em {
  font-style: normal;
  font-size: 10px;
  color: #7aa89a;
}

.lr-assets__right {
  width: 108px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.lr-assets__ring {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
}

.lr-assets__ring-outer {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border: 1px solid rgba(255, 120, 120, 0.28);
  box-shadow:
    0 0 14px rgba(255, 90, 90, 0.35),
    inset 0 0 10px rgba(255, 80, 80, 0.12);
  background: radial-gradient(circle at 40% 35%, rgba(80, 24, 28, 0.55), rgba(4, 28, 24, 0.2) 70%);
}

.lr-assets__ring-inner {
  position: relative;
  width: 78%;
  height: 78%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lr-assets__ring-inner::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 3px;
  background: linear-gradient(150deg, #ff8a8a 0%, #e23b3b 48%, #ecd27b 100%);
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.lr-assets__ring-val {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.1;
  padding: 0 4px;
}

.lr-assets__ring-val strong {
  font-size: 15px;
  font-weight: 700;
  color: #ecd27b;
  letter-spacing: 0.01em;
}

.lr-assets__ring-val em {
  margin-top: 2px;
  font-style: normal;
  font-size: 10px;
  color: #a8d4c8;
}

.lr-assets__ring-label {
  font-size: 12px;
  color: #c8e8dc;
  letter-spacing: 0.04em;
}

/* 用户结构双圆环（对齐 commonProsperity 数字赋能 cp-ring） */
.lr-rings {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-around;
  gap: 8px;
}

.lr-ring {
  flex: 1;
  min-width: 0;
  max-width: 130px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.lr-ring__figure {
  width: 104px;
  height: 104px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lr-ring__outer {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border: 2px solid rgba(236, 210, 123, 0.22);
  background: transparent;
}

.lr-ring__inner {
  position: relative;
  width: 82%;
  height: 82%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
}

.lr-ring__inner::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 3px;
  background: linear-gradient(160deg, #45f0b8 0%, #1d9a7a 42%, #ecd27b 100%);
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.lr-ring__val {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 0 4px;
  box-sizing: border-box;
  text-align: center;
  line-height: 1.15;
  color: #e8eef5;
}

.lr-ring__val strong {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #ecd27b;
}

.lr-ring__label {
  margin-top: 6px;
  width: 100%;
  padding: 0 2px;
  box-sizing: border-box;
  font-size: 10px;
  color: #a8d4c8;
  text-align: center;
  line-height: 1.35;
}

.lr-ring__ratio {
  margin-top: 2px;
  font-size: 9px;
  color: #5ef0c8;
  text-align: center;
  line-height: 1.3;
}

.flex_content--vax {
  display: flex;
  align-items: center;
  padding: 2px 8px 8px 6px;
}

.lr-vax {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
}

.lr-vax__chart {
  flex: 1;
  min-width: 0;
  height: 100%;
}

.lr-vax__stats {
  width: 96px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
  padding-right: 4px;
}

.lr-vax__row {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lr-vax__label {
  font-size: 11px;
  color: #a8d4c8;
  line-height: 1.2;
}

.lr-vax__num {
  font-size: 18px;
  font-weight: 700;
  color: #ecd27b;
  letter-spacing: 0.02em;
  line-height: 1.15;
  word-break: break-all;
}

.flex_content--rank {
  display: flex;
  align-items: center;
  padding: 4px 12px 10px;
}

.flex_content--unit-rank {
  display: flex;
  align-items: center;
  padding: 6px 12px 8px;
  overflow: hidden;
}

.lr-unit-rank {
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  gap: 8px;
  height: 100%;
}

.lr-unit-rank__row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 22px;
}

.lr-unit-rank__badge {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 3px;
  background: rgba(90, 110, 130, 0.85);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}

.lr-unit-rank__badge--1 {
  background: #e84a3c;
}

.lr-unit-rank__badge--2 {
  background: #f08a2a;
}

.lr-unit-rank__badge--3 {
  background: #e0a820;
}

.lr-unit-rank__label {
  flex-shrink: 0;
  width: 42px;
  font-size: 12px;
  color: #c8d4de;
  white-space: nowrap;
}

.lr-unit-rank__track {
  flex: 1;
  min-width: 0;
  height: 18px;
  border-radius: 2px;
  background: rgba(8, 28, 40, 0.55);
  overflow: hidden;
}

.lr-unit-rank__fill {
  height: 100%;
  min-width: 0;
  width: 0%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 8px;
  box-sizing: border-box;
  background: linear-gradient(90deg, #1a4a8c 0%, #2f7fd6 45%, #5eb8f5 100%);
  transition: width 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: width;
}

.lr-unit-rank__num {
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  line-height: 1;
  white-space: nowrap;
}

.lr-rank-bars {
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
}

.lr-rank-bars__row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.lr-rank-bars__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  line-height: 1.1;
}

.lr-rank-bars__label {
  font-size: 12px;
  color: #e8eef5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lr-rank-bars__value {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  color: #ecd27b;
}

.lr-rank-bars__track {
  width: 100%;
  height: 10px;
  border-radius: 999px;
  background: rgba(8, 36, 48, 0.72);
  border: 1px solid rgba(61, 217, 176, 0.18);
  overflow: hidden;
  box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.35);
}

.lr-rank-bars__fill {
  height: 100%;
  border-radius: 999px;
  min-width: 0;
  width: 0%;
  transition: width 0.85s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: width;
}

.lr-rank-bars__fill--1 {
  background: linear-gradient(90deg, #7c5cff 0%, #45f0b8 100%);
  box-shadow: 0 0 10px rgba(69, 240, 184, 0.45);
}

.lr-rank-bars__fill--2 {
  background: linear-gradient(90deg, #1f8fff 0%, #ecd27b 100%);
  box-shadow: 0 0 10px rgba(236, 210, 123, 0.4);
}

.lr-rank-bars__fill--3 {
  background: linear-gradient(90deg, #e23b6d 0%, #ff9a5a 100%);
  box-shadow: 0 0 10px rgba(255, 154, 90, 0.4);
}

.lr-rank-bars__fill--4 {
  background: linear-gradient(90deg, #0f8f72 0%, #6eb5ff 100%);
}

.flex_content--list {
  padding: 6px 10px;
  overflow: hidden;
}

.flex_content--agri {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px 8px;
  overflow: hidden;
}

.lr-agri {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  padding: 8px 10px;
  box-sizing: border-box;
}

.lr-agri__side {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.lr-agri__tri {
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 8px solid #5ef0c8;
  filter: drop-shadow(0 0 4px rgba(94, 240, 200, 0.65));
}

.lr-agri__side-label {
  font-size: 12px;
  color: #e8eef5;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.lr-agri__side-num {
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  line-height: 1;
  text-shadow: 0 0 10px rgba(94, 240, 200, 0.35);
}

.lr-agri__center {
  position: relative;
  flex-shrink: 0;
  width: 118px;
  height: 118px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lr-agri__frame {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border: 1px solid rgba(94, 240, 200, 0.22);
  box-shadow:
    0 0 12px rgba(61, 217, 176, 0.18),
    inset 0 0 18px rgba(61, 217, 176, 0.08);
}

.lr-agri__corner {
  position: absolute;
  width: 12px;
  height: 12px;
  border-color: #5ef0c8;
  border-style: solid;
  opacity: 0.9;
}

.lr-agri__corner--tl {
  top: -1px;
  left: -1px;
  border-width: 2px 0 0 2px;
}

.lr-agri__corner--tr {
  top: -1px;
  right: -1px;
  border-width: 2px 2px 0 0;
}

.lr-agri__corner--bl {
  bottom: -1px;
  left: -1px;
  border-width: 0 0 2px 2px;
}

.lr-agri__corner--br {
  right: -1px;
  bottom: -1px;
  border-width: 0 2px 2px 0;
}

.lr-agri__ring {
  position: relative;
  z-index: 1;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    0 0 16px rgba(94, 240, 200, 0.45),
    inset 0 0 10px rgba(0, 0, 0, 0.35);
}

.lr-agri__ring::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px dashed rgba(94, 240, 200, 0.35);
  pointer-events: none;
}

.lr-agri__ring-hole {
  width: 68%;
  height: 68%;
  border-radius: 50%;
  background: radial-gradient(circle at 45% 35%, rgba(18, 48, 42, 0.96), rgba(4, 22, 18, 0.98));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.45);
}

.lr-agri__ring-hole strong {
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  line-height: 1;
}

.lr-agri__ring-hole span {
  font-size: 11px;
  color: #c8e8dc;
  letter-spacing: 0.04em;
}

.lr-hot-list {
  list-style: none;
  margin: 0;
  padding: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.lr-hot-list__row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 4px;
  border-bottom: 1px solid rgba(61, 217, 176, 0.12);
}

.lr-hot-list__row:last-child {
  border-bottom: none;
}

.lr-hot-list__rank {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 3px;
  background: rgba(61, 217, 176, 0.25);
  color: #a8d4c8;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}

.lr-hot-list__rank--1 {
  background: linear-gradient(135deg, #ecd27b, #c9a030);
  color: #1a2e28;
}

.lr-hot-list__rank--2 {
  background: rgba(236, 210, 123, 0.55);
  color: #fff;
}

.lr-hot-list__rank--3 {
  background: rgba(110, 181, 255, 0.45);
  color: #fff;
}

.lr-hot-list__name {
  flex: 1;
  min-width: 0;
  font-size: 11px;
  color: #e8eef5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lr-hot-list__meta {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 10px;
  color: #a8d4c8;
}

.lr-hot-list__meta strong {
  font-size: 12px;
  color: #5ef0c8;
  font-weight: 600;
}

.lr-hot-list__meta em {
  font-style: normal;
  color: #ecd27b;
}

.lr-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 13px;
  color: rgba(168, 212, 200, 0.75);
}
</style>
