<template>
  <div class="home-dashboard">
    <section class="hero-panel">
      <div class="hero-content">
        <div class="platform-state">
          <span class="state-dot"></span>
          CMVR 智能测试平台
        </div>
        <h1>机器人智能测试管理系统</h1>
        <p class="hero-description">
          连接设备、编排流程、执行测试与巡检任务，集中管理机器人全生命周期测试业务。
        </p>
        <div class="hero-actions">
          <el-button type="primary" size="large" @click="router.push('/flow')">
            <el-icon><Connection /></el-icon>
            流程编排
          </el-button>
          <el-button size="large" class="cockpit-button" @click="router.push('/inspection/cockpit')">
            <el-icon><Monitor /></el-icon>
            巡检驾驶舱
          </el-button>
        </div>
      </div>

      <div class="hero-time" aria-label="当前时间">
        <span class="time-label">{{ greeting }}，{{ displayName }}</span>
        <strong>{{ currentTime }}</strong>
        <span>{{ currentDate }}</span>
      </div>
    </section>

    <section class="overview-section" aria-labelledby="overview-title">
      <div class="section-heading">
        <div>
          <span class="section-kicker">SYSTEM OVERVIEW</span>
          <h2 id="overview-title">系统概览</h2>
        </div>
        <el-tooltip content="刷新首页数据" placement="top">
          <el-button class="refresh-button" circle :loading="loading" @click="loadDashboardData">
            <el-icon v-if="!loading"><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
      </div>

      <div class="metric-grid">
        <article v-for="item in metrics" :key="item.key" class="metric-card">
          <div class="metric-icon" :class="`metric-icon--${item.tone}`">
            <el-icon><component :is="item.icon" /></el-icon>
          </div>
          <div class="metric-content">
            <span>{{ item.label }}</span>
            <strong>{{ displayMetric(item.key) }}</strong>
            <small>{{ item.description }}</small>
          </div>
          <span v-if="stats[item.key].restricted" class="metric-state">无权限</span>
        </article>
      </div>
    </section>

    <section class="workspace-grid">
      <div class="dashboard-panel task-panel">
        <div class="panel-heading">
          <div>
            <span class="section-kicker">LIVE OPERATIONS</span>
            <h2>任务运行态</h2>
          </div>
          <button class="text-action" type="button" @click="navigateToFeature(features[2])">
            查看全部
            <el-icon><ArrowRight /></el-icon>
          </button>
        </div>

        <div v-if="activeTasks.length" class="task-list">
          <button
            v-for="task in activeTasks"
            :key="task.id"
            class="task-row"
            type="button"
            @click="navigateToFeature(features[2])"
          >
            <span class="task-status-dot" :class="`status-${task.status}`"></span>
            <span class="task-main">
              <strong>{{ task.taskName || '未命名任务' }}</strong>
              <small>{{ task.robotName || '暂未分配机器人' }}</small>
            </span>
            <span class="task-meta">
              <el-tag :type="inspectionStatus(task.status).type" effect="light" size="small">
                {{ inspectionStatus(task.status).label }}
              </el-tag>
              <small>{{ formatTime(task.startTime || task.createTime) }}</small>
            </span>
            <el-icon class="row-arrow"><ArrowRight /></el-icon>
          </button>
        </div>

        <div v-else class="empty-state">
          <div class="empty-icon"><el-icon><CircleCheck /></el-icon></div>
          <strong>{{ activeTasksRestricted ? '暂无任务查看权限' : '当前没有运行中的任务' }}</strong>
          <span>{{ activeTasksRestricted ? '请联系管理员分配巡检任务权限' : '新的巡检任务启动后会显示在这里' }}</span>
        </div>
      </div>

      <div class="dashboard-panel capability-panel">
        <div class="panel-heading">
          <div>
            <span class="section-kicker">CAPABILITIES</span>
            <h2>能力中心</h2>
          </div>
        </div>

        <div class="feature-grid">
          <button
            v-for="feature in features"
            :key="feature.title"
            class="feature-item"
            type="button"
            @click="navigateToFeature(feature)"
          >
            <span class="feature-icon" :style="{ color: feature.color, backgroundColor: feature.background }">
              <el-icon><component :is="feature.icon" /></el-icon>
            </span>
            <span class="feature-copy">
              <strong>{{ feature.title }}</strong>
              <small>{{ feature.description }}</small>
            </span>
            <el-icon class="feature-arrow"><ArrowRight /></el-icon>
          </button>
        </div>
      </div>
    </section>

    <section class="dashboard-panel recent-panel">
      <div class="panel-heading">
        <div>
          <span class="section-kicker">RECENT EXECUTIONS</span>
          <h2>最近测试实例</h2>
        </div>
        <button class="text-action" type="button" @click="navigateToFeature(features[4])">
          执行记录
          <el-icon><ArrowRight /></el-icon>
        </button>
      </div>

      <div v-if="recentInstances.length" class="recent-list">
        <div v-for="instance in recentInstances" :key="instance.id" class="recent-item">
          <div class="recent-order">{{ String(instance.order).padStart(2, '0') }}</div>
          <div class="recent-info">
            <strong>{{ instance.taskName || '未命名测试实例' }}</strong>
            <span>{{ instance.remark || '机器人测试任务' }}</span>
          </div>
          <span class="recent-time">{{ formatTime(instance.createTime) }}</span>
          <el-tag :type="testStatus(instance.status).type" effect="plain" size="small">
            {{ testStatus(instance.status).label }}
          </el-tag>
        </div>
      </div>

      <div v-else class="recent-empty">
        <el-icon><DocumentChecked /></el-icon>
        <span>{{ recentInstancesRestricted ? '暂无测试实例查看权限' : '暂无测试执行记录' }}</span>
      </div>
    </section>
  </div>
</template>

<script setup name="Index">
import {
  ArrowRight,
  CircleCheck,
  Connection,
  Cpu,
  DataAnalysis,
  DocumentChecked,
  Grid,
  Headset,
  Monitor,
  Odometer,
  Operation,
  Refresh,
  SetUp,
} from '@element-plus/icons-vue'
import { listRegister } from '@/api/device/register'
import { getTaskList } from '@/api/inspection/task'
import { getRunTaskList } from '@/api/inspection/runTask'
import { listConfig } from '@/api/test/config'
import { listInst } from '@/api/test/log'
import auth from '@/plugins/auth'
import usePermissionStore from '@/store/modules/permission'
import useUserStore from '@/store/modules/user'

const router = useRouter()
const userStore = useUserStore()
const permissionStore = usePermissionStore()

const loading = ref(false)
const now = ref(new Date())
const activeTasks = ref([])
const recentInstances = ref([])
const activeTasksRestricted = ref(false)
const recentInstancesRestricted = ref(false)
let clockTimer

const stats = reactive({
  devices: { value: null, restricted: false },
  workflows: { value: null, restricted: false },
  inspections: { value: null, restricted: false },
  instances: { value: null, restricted: false },
})

const metrics = [
  { key: 'devices', label: '接入设备', description: '已注册设备总数', icon: Cpu, tone: 'blue' },
  { key: 'workflows', label: '测试流程', description: '可用测试编排', icon: Connection, tone: 'green' },
  { key: 'inspections', label: '巡检任务', description: '已配置巡检任务', icon: Odometer, tone: 'orange' },
  { key: 'instances', label: '测试实例', description: '累计执行实例', icon: DataAnalysis, tone: 'red' },
]

const features = [
  {
    title: '设备接入',
    description: '配置机器人与终端设备',
    icon: SetUp,
    color: '#2563eb',
    background: '#eaf2ff',
    menuTitles: ['设备注册', '设备配置管理', '设备管理'],
    fallback: '/device/register',
  },
  {
    title: '流程编排',
    description: '构建可视化测试工作流',
    icon: Operation,
    color: '#0f8a73',
    background: '#e7f6f2',
    menuTitles: ['任务流程编排', '流程编排'],
    fallback: '/flow',
  },
  {
    title: '巡检执行',
    description: '调度机器人巡检任务',
    icon: Monitor,
    color: '#c56a16',
    background: '#fff3e5',
    menuTitles: ['执行任务', '运行任务', '巡检任务执行'],
    fallback: '/inspection/runTask',
  },
  {
    title: '巡检配置',
    description: '管理地图、点位与任务',
    icon: Grid,
    color: '#6b57c7',
    background: '#f0edff',
    menuTitles: ['巡检任务', '巡检地图', '地图管理'],
    fallback: '/inspection/task',
  },
  {
    title: '测试记录',
    description: '追踪执行结果与日志',
    icon: DocumentChecked,
    color: '#d14343',
    background: '#ffeded',
    menuTitles: ['任务历史', '测试记录', '任务实例', '执行记录'],
    fallback: '/test/history',
  },
  {
    title: '语料中心',
    description: '管理语音与合成资源',
    icon: Headset,
    color: '#087f9c',
    background: '#e8f7fa',
    menuTitles: ['语料库', '语料管理', '车载语料'],
    fallback: '/corpusManger/corpus',
  },
]

const displayName = computed(() => userStore.nickName || userStore.name || '用户')
const currentTime = computed(() => new Intl.DateTimeFormat('zh-CN', {
  hour: '2-digit',
  minute: '2-digit',
  hour12: false,
}).format(now.value))
const currentDate = computed(() => new Intl.DateTimeFormat('zh-CN', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  weekday: 'long',
}).format(now.value))
const greeting = computed(() => {
  const hour = now.value.getHours()
  if (hour < 6) return '夜深了'
  if (hour < 12) return '上午好'
  if (hour < 18) return '下午好'
  return '晚上好'
})

function displayMetric(key) {
  const metric = stats[key]
  if (metric.restricted) return '--'
  return metric.value === null ? '--' : metric.value.toLocaleString('zh-CN')
}

function hasPermission(permission) {
  return auth.hasPermi(permission)
}

function createMetricRequest(key, permission, request) {
  if (!hasPermission(permission)) {
    stats[key].restricted = true
    return null
  }
  stats[key].restricted = false
  return request()
    .then((response) => {
      stats[key].value = Number(response.total ?? response.rows?.length ?? 0)
    })
    .catch(() => {
      stats[key].value = null
    })
}

async function loadDashboardData() {
  if (loading.value) return
  loading.value = true

  const requests = [
    createMetricRequest('devices', 'device:register:list', () => listRegister({ pageNum: 1, pageSize: 1 })),
    createMetricRequest('workflows', 'test:config:list', () => listConfig({ pageNum: 1, pageSize: 1 })),
    createMetricRequest('inspections', 'inspection:task:list', () => getTaskList({ pageNum: 1, pageSize: 1 })),
    createMetricRequest('instances', 'test:inst:list', () => listInst({ pageNum: 1, pageSize: 5 })),
  ].filter(Boolean)

  if (hasPermission('inspection:taskInstance:list')) {
    activeTasksRestricted.value = false
    requests.push(
      getRunTaskList({ pageNum: 1, pageSize: 5, statusList: ['1', '3', '5'] })
        .then((response) => {
          activeTasks.value = (response.rows || []).slice(0, 4)
        })
        .catch(() => {
          activeTasks.value = []
        }),
    )
  } else {
    activeTasksRestricted.value = true
    activeTasks.value = []
  }

  if (hasPermission('test:inst:list')) {
    recentInstancesRestricted.value = false
    requests.push(
      listInst({ pageNum: 1, pageSize: 4 })
        .then((response) => {
          recentInstances.value = (response.rows || []).slice(0, 4).map((item, index) => ({
            ...item,
            order: index + 1,
          }))
        })
        .catch(() => {
          recentInstances.value = []
        }),
    )
  } else {
    recentInstancesRestricted.value = true
    recentInstances.value = []
  }

  await Promise.allSettled(requests)
  loading.value = false
}

function inspectionStatus(status) {
  return {
    '0': { label: '已完成', type: 'success' },
    '1': { label: '执行中', type: 'warning' },
    '2': { label: '失败', type: 'danger' },
    '3': { label: '已暂停', type: 'primary' },
    '4': { label: '已终止', type: 'info' },
    '5': { label: '等待执行', type: 'info' },
  }[String(status)] || { label: '未知', type: 'info' }
}

function testStatus(status) {
  return {
    '0': { label: '已完成', type: 'success' },
    '1': { label: '执行中', type: 'warning' },
    '2': { label: '失败', type: 'danger' },
  }[String(status)] || { label: '未知', type: 'info' }
}

function formatTime(value) {
  if (!value) return '尚未开始'
  const date = new Date(String(value).replace(/-/g, '/'))
  if (Number.isNaN(date.getTime())) return String(value)
  return new Intl.DateTimeFormat('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false,
  }).format(date)
}

function joinPath(parentPath, routePath) {
  if (!routePath) return parentPath || '/'
  if (routePath.startsWith('/')) return routePath
  const parent = parentPath && parentPath !== '/' ? parentPath.replace(/\/$/, '') : ''
  return `${parent}/${routePath}`.replace(/\/+/g, '/')
}

function flattenMenus(routes, parentPath = '', result = []) {
  for (const route of routes || []) {
    const path = joinPath(parentPath, route.path)
    if (!route.hidden && route.meta?.title) {
      result.push({ title: route.meta.title, path })
    }
    if (route.children?.length) flattenMenus(route.children, path, result)
  }
  return result
}

function resolveFeaturePath(feature) {
  const menus = flattenMenus(permissionStore.sidebarRouters)
  const exact = menus.find((menu) => feature.menuTitles.includes(menu.title))
  if (exact) return exact.path
  const partial = menus.find((menu) => feature.menuTitles.some((title) => menu.title.includes(title)))
  return partial?.path || feature.fallback
}

function navigateToFeature(feature) {
  router.push(resolveFeaturePath(feature))
}

onMounted(() => {
  loadDashboardData()
  clockTimer = window.setInterval(() => {
    now.value = new Date()
  }, 1000)
})

onBeforeUnmount(() => {
  window.clearInterval(clockTimer)
})
</script>

<style scoped lang="scss">
.home-dashboard {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  padding: 0 2px 24px;
  color: var(--el-text-color-primary);
}

.hero-panel {
  position: relative;
  min-height: 236px;
  padding: 36px 42px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  border-radius: 6px;
  background-image: url('../assets/images/index-background.jpg');
  background-position: center 48%;
  background-size: cover;
  color: #fff;
}

.hero-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(8, 24, 37, 0.72);
}

.hero-content,
.hero-time {
  position: relative;
  z-index: 1;
}

.hero-content {
  max-width: 760px;
}

.platform-state {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 13px;
  color: rgba(255, 255, 255, 0.82);
  font-size: 13px;
  font-weight: 600;
}

.state-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #35d2a0;
  box-shadow: 0 0 0 5px rgba(53, 210, 160, 0.16);
  animation: status-pulse 2.2s ease-in-out infinite;
}

.hero-content h1 {
  margin: 0;
  font-size: 32px;
  line-height: 1.28;
  font-weight: 700;
  letter-spacing: 0;
}

.hero-description {
  max-width: 670px;
  margin: 12px 0 22px;
  color: rgba(255, 255, 255, 0.76);
  font-size: 15px;
  line-height: 1.7;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.hero-actions :deep(.el-button) {
  min-width: 126px;
  margin: 0;
  border-radius: 4px;
  font-weight: 600;
}

.hero-actions :deep(.el-button--primary) {
  border-color: #1688e7;
  background: #1688e7;
}

.cockpit-button {
  border-color: rgba(255, 255, 255, 0.42) !important;
  background: rgba(255, 255, 255, 0.1) !important;
  color: #fff !important;
}

.cockpit-button:hover {
  border-color: #fff !important;
  background: rgba(255, 255, 255, 0.18) !important;
}

.hero-time {
  min-width: 190px;
  padding-left: 26px;
  border-left: 1px solid rgba(255, 255, 255, 0.24);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.hero-time strong {
  margin: 6px 0 2px;
  font-size: 42px;
  line-height: 1;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.hero-time > span:last-child,
.time-label {
  color: rgba(255, 255, 255, 0.72);
  font-size: 13px;
}

.overview-section {
  padding: 24px 0 20px;
}

.section-heading,
.panel-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.section-heading {
  margin-bottom: 14px;
}

.section-kicker {
  display: block;
  margin-bottom: 4px;
  color: var(--el-color-primary);
  font-size: 10px;
  line-height: 1.2;
  font-weight: 700;
}

.section-heading h2,
.panel-heading h2 {
  margin: 0;
  color: var(--el-text-color-primary);
  font-size: 18px;
  line-height: 1.35;
  letter-spacing: 0;
}

.refresh-button {
  flex: 0 0 auto;
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.metric-card {
  position: relative;
  min-height: 116px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 6px;
  background: var(--el-bg-color);
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.metric-card:hover {
  transform: translateY(-2px);
  border-color: var(--el-border-color);
  box-shadow: 0 10px 24px rgba(28, 44, 64, 0.08);
}

.metric-icon {
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  font-size: 24px;
}

.metric-icon--blue { color: #2563eb; background: #eaf2ff; }
.metric-icon--green { color: #0f8a73; background: #e7f6f2; }
.metric-icon--orange { color: #c56a16; background: #fff3e5; }
.metric-icon--red { color: #d14343; background: #ffeded; }

.metric-content {
  min-width: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  column-gap: 10px;
}

.metric-content > span {
  color: var(--el-text-color-regular);
  font-size: 14px;
}

.metric-content strong {
  grid-column: 2;
  grid-row: 1 / span 2;
  color: var(--el-text-color-primary);
  font-size: 28px;
  line-height: 1;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.metric-content small {
  margin-top: 7px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.metric-state {
  position: absolute;
  right: 12px;
  bottom: 8px;
  color: var(--el-text-color-placeholder);
  font-size: 10px;
}

.workspace-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(360px, 0.75fr);
  gap: 16px;
  margin-bottom: 16px;
}

.dashboard-panel {
  min-width: 0;
  padding: 20px;
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 6px;
  background: var(--el-bg-color);
}

.panel-heading {
  min-height: 40px;
  margin-bottom: 14px;
}

.text-action {
  border: 0;
  padding: 5px 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  color: var(--el-color-primary);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.text-action:hover {
  color: var(--el-color-primary-light-3);
}

.task-list {
  display: flex;
  flex-direction: column;
}

.task-row {
  width: 100%;
  min-height: 63px;
  padding: 11px 6px;
  border: 0;
  border-top: 1px solid var(--el-border-color-extra-light);
  display: grid;
  grid-template-columns: 10px minmax(130px, 1fr) auto 18px;
  align-items: center;
  gap: 12px;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.task-row:first-child {
  border-top: 0;
}

.task-row:hover {
  background: var(--el-fill-color-light);
}

.task-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--el-color-info);
}

.task-status-dot.status-1 { background: var(--el-color-warning); }
.task-status-dot.status-3 { background: var(--el-color-primary); }
.task-status-dot.status-5 { background: var(--el-color-info); }

.task-main,
.task-meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.task-main strong {
  overflow: hidden;
  color: var(--el-text-color-primary);
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.task-main small,
.task-meta small {
  color: var(--el-text-color-secondary);
  font-size: 11px;
}

.task-meta {
  align-items: flex-end;
}

.row-arrow,
.feature-arrow {
  color: var(--el-text-color-placeholder);
}

.empty-state {
  min-height: 184px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--el-text-color-regular);
  text-align: center;
}

.empty-icon {
  width: 44px;
  height: 44px;
  margin-bottom: 10px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--el-color-success-light-9);
  color: var(--el-color-success);
  font-size: 22px;
}

.empty-state strong {
  font-size: 14px;
}

.empty-state > span {
  margin-top: 6px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.feature-item {
  min-width: 0;
  min-height: 76px;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 5px;
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) 14px;
  align-items: center;
  gap: 9px;
  background: var(--el-fill-color-extra-light);
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
}

.feature-item:hover {
  border-color: var(--el-border-color);
  background: var(--el-fill-color-light);
}

.feature-icon {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 5px;
  font-size: 20px;
}

.feature-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.feature-copy strong {
  color: var(--el-text-color-primary);
  font-size: 13px;
  font-weight: 600;
}

.feature-copy small {
  overflow: hidden;
  color: var(--el-text-color-secondary);
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recent-panel {
  margin-bottom: 2px;
}

.recent-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 26px;
}

.recent-item {
  min-width: 0;
  min-height: 62px;
  border-top: 1px solid var(--el-border-color-extra-light);
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 11px;
}

.recent-item:nth-child(-n + 2) {
  border-top: 0;
}

.recent-order {
  color: var(--el-text-color-placeholder);
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.recent-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.recent-info strong,
.recent-info span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recent-info strong {
  color: var(--el-text-color-primary);
  font-size: 13px;
  font-weight: 600;
}

.recent-info span,
.recent-time {
  color: var(--el-text-color-secondary);
  font-size: 11px;
}

.recent-empty {
  min-height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--el-text-color-secondary);
  font-size: 13px;
}

.recent-empty .el-icon {
  font-size: 19px;
}

:global(html.dark) .hero-panel::before {
  background: rgba(4, 13, 22, 0.82);
}

:global(html.dark) .metric-card:hover {
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22);
}

:global(html.dark) .metric-icon,
:global(html.dark) .feature-icon {
  background: var(--el-fill-color) !important;
}

@keyframes status-pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(53, 210, 160, 0.12); }
  50% { box-shadow: 0 0 0 7px rgba(53, 210, 160, 0.04); }
}

@media (max-width: 1200px) {
  .metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .workspace-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .home-dashboard {
    padding-bottom: 16px;
  }

  .hero-panel {
    min-height: 0;
    padding: 28px 22px;
    align-items: flex-start;
    flex-direction: column;
  }

  .hero-content h1 {
    font-size: 26px;
  }

  .hero-description {
    font-size: 14px;
  }

  .hero-time {
    width: 100%;
    padding: 18px 0 0;
    border-top: 1px solid rgba(255, 255, 255, 0.24);
    border-left: 0;
    align-items: flex-start;
  }

  .hero-time strong {
    font-size: 34px;
  }

  .metric-grid,
  .feature-grid,
  .recent-list {
    grid-template-columns: 1fr;
  }

  .recent-item:nth-child(2) {
    border-top: 1px solid var(--el-border-color-extra-light);
  }
}

@media (max-width: 520px) {
  .metric-grid {
    gap: 10px;
  }

  .metric-card {
    min-height: 104px;
    padding: 16px;
  }

  .metric-content {
    grid-template-columns: 1fr;
  }

  .metric-content strong {
    grid-column: 1;
    grid-row: auto;
    margin-top: 5px;
    font-size: 24px;
  }

  .task-row {
    grid-template-columns: 10px minmax(0, 1fr) 16px;
  }

  .task-meta {
    display: none;
  }

  .recent-item {
    grid-template-columns: 28px minmax(0, 1fr) auto;
  }

  .recent-time {
    display: none;
  }
}
</style>
