<script setup lang="ts">
import type { ModelApiTypeOption, ModelLibraryDto, ModelTypeOption } from '@/api/model/types';
import { Box, Close, CopyDocument, OfficeBuilding, Search } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { getApiTypeOptions, getModelLibraryList, getModelTypeOptions, getProviderList } from '@/api/model';
import { useScreenStore } from '@/hooks/useScreen';

const router = useRouter();
const { isMobile } = useScreenStore();

const showMobileFilter = ref(false);
const loading = ref(false);
const modelList = ref<ModelLibraryDto[]>([]);
const totalCount = ref(0);
const currentPage = ref(1);
const pageSize = ref(12);

// 筛选条件
const searchKey = ref('');
const selectedProviders = ref<string[]>([]);
const selectedModelTypes = ref<number[]>([]);
const selectedApiTypes = ref<number[]>([]);
const isPremiumOnly = ref(false);

// 供应商列表
const providerList = ref<string[]>([]);

// 模型类型选项
const modelTypeOptions = ref<ModelTypeOption[]>([]);

// API类型选项
const apiTypeOptions = ref<ModelApiTypeOption[]>([]);

function goToMonitor() {
  window.open('http://data.ccnetcore.com:91/?period=24h', '_blank');
}

// 格式化倍率显示
function formatMultiplier(multiplier: number): string {
  if (multiplier >= 10000) {
    // 倍率大于等于10000，显示为次数
    const tokenCount = multiplier / 10000;
    return `${tokenCount}w/次`;
  }
  // 倍率小于10000，显示为倍率
  return `${multiplier}×`;
}

async function fetchModelList() {
  loading.value = true;
  try {
    const params = {
      searchKey: searchKey.value || undefined,
      providerNames: selectedProviders.value.length > 0 ? selectedProviders.value : undefined,
      modelTypes: selectedModelTypes.value.length > 0 ? selectedModelTypes.value : undefined,
      modelApiTypes: selectedApiTypes.value.length > 0 ? selectedApiTypes.value : undefined,
      isPremiumOnly: isPremiumOnly.value || undefined,
      skipCount: currentPage.value,
      maxResultCount: pageSize.value,
    };

    const response = await getModelLibraryList(params);
    const data = response.data;

    modelList.value = data.items;
    totalCount.value = data.totalCount;
  }
  catch (error) {
    console.error('获取模型列表失败:', error);
    ElMessage.error('获取模型列表失败');
  }
  finally {
    loading.value = false;
  }
}

// 获取所有供应商列表（用于筛选栏）
async function fetchProviderList() {
  try {
    const response = await getProviderList();
    providerList.value = response.data.sort();
  }
  catch (error) {
    console.error('获取供应商列表失败:', error);
  }
}

// 获取模型类型选项
async function fetchModelTypeOptions() {
  try {
    const response = await getModelTypeOptions();
    modelTypeOptions.value = response.data;
  }
  catch (error) {
    console.error('获取模型类型选项失败:', error);
  }
}

// 获取API类型选项
async function fetchApiTypeOptions() {
  try {
    const response = await getApiTypeOptions();
    apiTypeOptions.value = response.data;
  }
  catch (error) {
    console.error('获取API类型选项失败:', error);
  }
}

function copyModelId(modelId: string) {
  navigator.clipboard.writeText(modelId).then(() => {
    ElMessage.success('模型ID已复制');
  });
}

function resetFilters() {
  searchKey.value = '';
  selectedProviders.value = [];
  selectedModelTypes.value = [];
  selectedApiTypes.value = [];
  isPremiumOnly.value = false;
  currentPage.value = 1;
}

function toggleProvider(provider: string | null) {
  if (provider === null) {
    // 点击"全部"，清空所有选择
    selectedProviders.value = [];
  }
  else {
    const index = selectedProviders.value.indexOf(provider);
    if (index > -1) {
      selectedProviders.value.splice(index, 1);
    }
    else {
      selectedProviders.value.push(provider);
    }
  }
  currentPage.value = 1;
}

function toggleModelType(type: number | null) {
  if (type === null) {
    // 点击"全部"，清空所有选择
    selectedModelTypes.value = [];
  }
  else {
    const index = selectedModelTypes.value.indexOf(type);
    if (index > -1) {
      selectedModelTypes.value.splice(index, 1);
    }
    else {
      selectedModelTypes.value.push(type);
    }
  }
  currentPage.value = 1;
}

function toggleApiType(type: number | null) {
  if (type === null) {
    // 点击"全部"，清空所有选择
    selectedApiTypes.value = [];
  }
  else {
    const index = selectedApiTypes.value.indexOf(type);
    if (index > -1) {
      selectedApiTypes.value.splice(index, 1);
    }
    else {
      selectedApiTypes.value.push(type);
    }
  }
  currentPage.value = 1;
}

function togglePremiumOnly(isPremium: boolean | null) {
  if (isPremium === null) {
    // 点击"全部"，设置为false
    isPremiumOnly.value = false;
  }
  else {
    isPremiumOnly.value = isPremium;
  }
  currentPage.value = 1;
}

function handlePageChange(page: number) {
  currentPage.value = page;
  fetchModelList();
}

function handleSizeChange(size: number) {
  pageSize.value = size;
  currentPage.value = 1;
  fetchModelList();
}

function goToHome() {
  router.push('/');
}

// 监听筛选条件变化，自动刷新数据
// 搜索关键词使用防抖，其他条件立即触发
let searchTimer: ReturnType<typeof setTimeout> | null = null;
watch(searchKey, () => {
  if (searchTimer) {
    clearTimeout(searchTimer);
  }
  searchTimer = setTimeout(() => {
    currentPage.value = 1;
    fetchModelList();
  }, 500);
});

watch([selectedProviders, selectedModelTypes, selectedApiTypes, isPremiumOnly], () => {
  currentPage.value = 1;
  fetchModelList();
}, { deep: true });

function openMobileFilter() {
  showMobileFilter.value = true;
}

function closeMobileFilter() {
  showMobileFilter.value = false;
}

onMounted(() => {
  fetchProviderList();
  fetchModelTypeOptions();
  fetchApiTypeOptions();
  fetchModelList();
});
</script>

<template>
  <div class="model-library-container">
    <!-- 顶部横幅 -->
    <div class="banner-section">
      <div class="banner-content">
        <div class="banner-header">
          <div class="banner-left">
            <div class="banner-text-section">
              <h1 class="banner-title">
                意心AI模型库
              </h1>
              <p class="banner-subtitle">
                探索并接入全球顶尖AI模型，覆盖文本、图像、嵌入等多个领域
              </p>
              <p class="banner-subtitle">
                尊享Token = 实际消耗Token * 当前模型倍率
              </p>
            </div>
            <!-- 统计信息卡片 -->
            <div class="stats-cards">
              <div class="stat-card">
                <div class="stat-icon">
                  <el-icon><Box /></el-icon>
                </div>
                <div class="stat-info">
                  <div class="stat-value">
                    {{ totalCount }}
                  </div>
                  <div class="stat-label">
                    可用模型
                  </div>
                </div>
              </div>
              <div class="stat-card">
                <div class="stat-icon">
                  <el-icon><OfficeBuilding /></el-icon>
                </div>
                <div class="stat-info">
                  <div class="stat-value">
                    {{ providerList.length > 1 ? providerList.length : 1 - 1 }}
                  </div>
                  <div class="stat-label">
                    支持供应商
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="monitor-card" @click="goToMonitor">
            <!-- 动态网格背景 -->
            <div class="grid-background">
              <div v-for="i in 6" :key="`line-${i}`" class="grid-line" />
            </div>

            <!-- 扫描线效果 -->
            <div class="scan-line" />

            <!-- 粒子效果 -->
            <div class="particles">
              <span v-for="i in 8" :key="`particle-${i}`" class="particle" />
            </div>

            <!-- 点击引导手势 -->
            <div class="click-hint">
              <svg class="hand-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M9 11V6C9 5.44772 9.44772 5 10 5C10.5523 5 11 5.44772 11 6V11M9 11V16.5C9 17.8807 10.1193 19 11.5 19H12.5C13.8807 19 15 17.8807 15 16.5V11M9 11H7.5C6.67157 11 6 11.6716 6 12.5C6 13.3284 6.67157 14 7.5 14H9M15 11V8C15 7.44772 15.4477 7 16 7C16.5523 7 17 7.44772 17 8V11M15 11H17.5C18.3284 11 19 11.6716 19 12.5C19 13.3284 18.3284 14 17.5 14H15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
              </svg>
              <span class="hint-text">点击查看</span>
            </div>

            <div class="monitor-content">
              <!-- 左侧：AI神经网络节点 + 脉冲圆环 -->
              <div class="monitor-visual">
                <div class="pulse-rings">
                  <div class="pulse-ring" />
                  <div class="pulse-ring" />
                  <div class="pulse-ring" />
                </div>

                <!-- AI神经网络节点 -->
                <div class="ai-network">
                  <!-- 中心节点 -->
                  <div class="center-node">
                    <div class="node-core" />
                  </div>

                  <!-- 外围节点 -->
                  <div class="outer-nodes">
                    <div v-for="i in 6" :key="`node-${i}`" class="outer-node" :style="{ transform: `rotate(${(i - 1) * 60}deg) translateY(-25px)` }">
                      <div class="node-dot" />
                      <div class="connection-line" />
                    </div>
                  </div>

                  <!-- 数据流动粒子 -->
                  <div class="data-particles">
                    <span v-for="i in 6" :key="`data-${i}`" class="data-particle" :style="{ animationDelay: `${(i - 1) * 0.3}s` }" />
                  </div>
                </div>

                <div class="status-dot">
                  <span class="dot-core" />
                </div>
              </div>

              <!-- 右侧：信息 + 实时数据流 -->
              <div class="monitor-info">
                <div class="monitor-header">
                  <span class="status-badge">
                    <span class="badge-dot" />
                    LIVE
                  </span>
                  <div class="monitor-title">
                    实时监控
                  </div>
                </div>
                <div class="monitor-subtitle">
                  服务可用性矩阵
                </div>
                <!-- 实时数据波形 -->
                <div class="waveform">
                  <span v-for="i in 12" :key="`bar-${i}`" class="wave-bar" />
                </div>
              </div>
            </div>

            <!-- 边框光效 -->
            <div class="border-glow" />
          </div>
        </div>
      </div>
    </div>

    <!-- 主内容区 -->
    <div class="main-content">
      <div class="content-wrapper">
        <!-- 左侧筛选栏 -->
        <aside class="filter-sidebar" :class="{ 'mobile-active': showMobileFilter }">
          <!-- 移动端遮罩 -->
          <div v-if="isMobile && showMobileFilter" class="mobile-overlay" @click="closeMobileFilter" />

          <div class="filter-section">
            <div class="filter-header">
              <h3 class="filter-title">
                <el-icon><i-ep-filter /></el-icon>
                筛选条件
              </h3>
              <div class="filter-header-actions">
                <el-button link type="primary" size="small" @click="resetFilters">
                  重置
                </el-button>
                <el-icon v-if="isMobile" class="close-btn" @click="closeMobileFilter">
                  <Close />
                </el-icon>
              </div>
            </div>

            <!-- 搜索框 -->
            <div class="filter-group">
              <el-input
                v-model="searchKey"
                placeholder="搜索模型..."
                clearable
                size="default"
              >
                <template #prefix>
                  <el-icon><Search /></el-icon>
                </template>
              </el-input>
            </div>

            <!-- 供应商 -->
            <div class="filter-group">
              <h4 class="filter-group-title">
                供应商
              </h4>
              <div class="filter-tags">
                <el-check-tag
                  :checked="selectedProviders.length === 0"
                  class="filter-tag"
                  @change="toggleProvider(null)"
                >
                  全部供应商
                </el-check-tag>
                <el-check-tag
                  v-for="provider in providerList"
                  :key="provider"
                  :checked="selectedProviders.includes(provider)"
                  class="filter-tag"

                  @change="toggleProvider(provider)"
                >
                  {{ provider }}
                </el-check-tag>
              </div>
            </div>

            <!-- 模型类型 -->
            <div class="filter-group">
              <h4 class="filter-group-title">
                模型类型
              </h4>
              <div class="filter-tags">
                <el-check-tag
                  :checked="selectedModelTypes.length === 0"
                  class="filter-tag"
                  @change="toggleModelType(null)"
                >
                  全部类型
                </el-check-tag>
                <el-check-tag
                  v-for="option in modelTypeOptions"
                  :key="option.value"
                  :checked="selectedModelTypes.includes(option.value)"
                  class="filter-tag"
                  @change="toggleModelType(option.value)"
                >
                  {{ option.label }}
                </el-check-tag>
              </div>
            </div>

            <!-- API类型 -->
            <div class="filter-group">
              <h4 class="filter-group-title">
                API类型
              </h4>
              <div class="filter-tags">
                <el-check-tag
                  :checked="selectedApiTypes.length === 0"
                  class="filter-tag"
                  @change="toggleApiType(null)"
                >
                  全部API类型
                </el-check-tag>
                <el-check-tag
                  v-for="option in apiTypeOptions"
                  :key="option.value"
                  :checked="selectedApiTypes.includes(option.value)"
                  class="filter-tag"
                  @change="toggleApiType(option.value)"
                >
                  {{ option.label }}
                </el-check-tag>
              </div>
            </div>

            <!-- 计费类型 -->
            <div class="filter-group">
              <h4 class="filter-group-title">
                计费类型
              </h4>
              <div class="filter-tags">
                <el-check-tag
                  :checked="!isPremiumOnly"
                  class="filter-tag"
                  @change="togglePremiumOnly(null)"
                >
                  全部模型
                </el-check-tag>
                <el-check-tag
                  :checked="isPremiumOnly"
                  class="filter-tag"
                  @change="togglePremiumOnly(true)"
                >
                  仅尊享模型
                </el-check-tag>
              </div>
            </div>
          </div>
        </aside>

        <!-- 右侧模型列表 -->
        <main class="model-list-section">
          <!-- 移动端筛选按钮 -->
          <div v-if="isMobile" class="mobile-filter-bar">
            <el-button type="primary" :icon="Search" plain class="w-full" @click="openMobileFilter">
              筛选与搜索
            </el-button>
          </div>

          <!-- 加载状态 -->
          <div v-if="loading" class="loading-wrapper">
            <el-skeleton :rows="8" animated />
          </div>

          <!-- 空状态 -->
          <div v-else-if="modelList.length === 0" class="empty-wrapper">
            <el-empty description="未找到符合条件的模型">
              <el-button type="primary" @click="resetFilters">
                清除筛选条件
              </el-button>
            </el-empty>
          </div>

          <!-- 模型网格 -->
          <el-row v-else :gutter="20" class="model-grid">
            <el-col
              v-for="model in modelList"
              :key="model.modelId"
              :xs="24"
              :sm="8"
              :lg="6"
            >
              <div
                class="model-card"
                :class="{ 'premium-card': model.isPremium }"
              >
                <el-button
                  circle
                  size="small"
                  :icon="CopyDocument"
                  class="copy-btn-corner"
                  title="复制模型ID"
                  @click="copyModelId(model.modelId)"
                />

                <div class="model-card-header">
                  <div class="model-icon">
                    <img
                      v-if="model.iconUrl"
                      :src="model.iconUrl"
                      :alt="model.name"
                      class="icon-img"
                    >
                    <div v-else class="icon-placeholder">
                      {{ model.name.charAt(0).toUpperCase() }}
                    </div>
                  </div>
                  <div class="model-info">
                    <h3 class="model-name">
                      {{ model.name }}
                    </h3>
                    <div class="model-provider">
                      {{ model.providerName }}
                    </div>
                  </div>
                </div>

                <div class="model-id">
                  <span class="model-id-label">ModelId:</span>
                  <span class="model-id-value">{{ model.modelId }}</span>
                </div>

                <p v-if="model.description" class="model-description">
                  {{ model.description }}
                </p>
                <p v-else class="model-description placeholder">
                  {{ model.modelId }}
                </p>

                <div class="model-footer">
                  <div class="model-tags">
                    <el-tag size="small">
                      {{ model.modelTypeName }}
                    </el-tag>
                    <el-tag v-for="item in model.modelApiTypes" :key="item" size="small">
                      {{ item.modelApiTypeName }}
                    </el-tag>
                  </div>
                  <div class="model-pricing">
                    <span class="pricing-value">{{ formatMultiplier(model.multiplierShow) }}</span>
                  </div>
                </div>
              </div>
            </el-col>
          </el-row>

          <!-- 分页 -->
          <div v-if="totalCount > 0 && !loading" class="pagination-wrapper">
            <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[12, 24, 48, 96]"
              :total="totalCount"
              :layout="isMobile ? 'prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
              prev-text="上一页"
              next-text="下一页"
              background
              @current-change="handlePageChange"
              @size-change="handleSizeChange"
            />
          </div>
        </main>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.model-library-container {
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, #f5f7fa 0%, #ffffff 100%);
  overflow: auto;

  // 顶部横幅
  .banner-section {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 40px 24px;
    position: relative;
    overflow: hidden;

    // 装饰性背景元素
    &::before,
    &::after {
      content: '';
      position: absolute;
      border-radius: 50%;
      background: rgba(255, 255, 255, 0.08);
    }

    &::before {
      width: 400px;
      height: 400px;
      top: -200px;
      right: -100px;
    }

    &::after {
      width: 300px;
      height: 300px;
      bottom: -150px;
      left: -100px;
    }

    .banner-content {
      //max-width: 1400px;
      margin: 0 auto;
      position: relative;
      z-index: 1;

      .banner-header {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 32px;

        .banner-left {
          flex: 1;
          display: flex;
          align-items: center;
          gap: 32px;

          .banner-text-section {
            flex-shrink: 0;

            .banner-title {
              font-size: 36px;
              font-weight: 800;
              color: white;
              margin: 0 0 12px 0;
              letter-spacing: -0.5px;
            }

            .banner-subtitle {
              font-size: 15px;
              color: rgba(255, 255, 255, 0.95);
              margin: 0;
              line-height: 1.6;
              max-width: 500px;
            }
          }

          // 统计卡片
          .stats-cards {
            display: flex;
            gap: 16px;
            flex-shrink: 0;

            .stat-card {
              background: rgba(255, 255, 255, 0.15);
              backdrop-filter: blur(10px);
              border: 1px solid rgba(255, 255, 255, 0.25);
              border-radius: 12px;
              padding: 16px 20px;
              display: flex;
              align-items: center;
              gap: 12px;
              transition: all 0.3s;
              min-width: 160px;

              &:hover {
                background: rgba(255, 255, 255, 0.2);
                transform: translateY(-2px);
              }

              .stat-icon {
                width: 48px;
                height: 48px;
                background: rgba(255, 255, 255, 0.25);
                border-radius: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 24px;
                color: white;
              }

              .stat-info {
                .stat-value {
                  font-size: 28px;
                  font-weight: 700;
                  color: white;
                  line-height: 1;
                  margin-bottom: 6px;
                }

                .stat-label {
                  font-size: 13px;
                  color: rgba(255, 255, 255, 0.9);
                  white-space: nowrap;
                }
              }
            }
          }
        }

        .monitor-card {
          background: rgba(10, 15, 30, 0.6);
          backdrop-filter: blur(20px);
          border: 1px solid rgba(103, 194, 58, 0.3);
          border-radius: 20px;
          padding: 20px 28px;
          cursor: pointer;
          transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
          flex-shrink: 0;
          position: relative;
          overflow: hidden;
          min-width: 280px;
          box-shadow:
            0 8px 32px rgba(0, 0, 0, 0.3),
            inset 0 1px 0 rgba(255, 255, 255, 0.1);

          &::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(135deg,
              rgba(103, 194, 58, 0.1) 0%,
              rgba(64, 158, 255, 0.1) 100%);
            opacity: 0;
            transition: opacity 0.5s;
          }

          &:hover {
            transform: translateY(-6px) scale(1.03);
            border-color: rgba(103, 194, 58, 0.6);
            box-shadow:
              0 16px 48px rgba(103, 194, 58, 0.3),
              0 0 80px rgba(103, 194, 58, 0.2),
              inset 0 1px 0 rgba(255, 255, 255, 0.2);

            &::before {
              opacity: 1;
            }

            .click-hint {
              opacity: 0;
              transform: translate(-50%, -50%) scale(0.8);
            }

            .scan-line {
              animation: scanMove 2s linear infinite;
            }

            .wave-bar {
              animation: waveformPulse 0.8s ease-in-out infinite;
            }

            .border-glow {
              opacity: 1;
            }
          }

          // 点击引导
          .click-hint {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8px;
            z-index: 10;
            pointer-events: none;
            opacity: 1;
            transition: all 0.3s;
            animation: clickHintFloat 2s ease-in-out infinite;

            .hand-icon {
              width: 32px;
              height: 32px;
              color: rgba(255, 255, 255, 0.9);
              filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.3));
              animation: handClick 1.5s ease-in-out infinite;
            }

            .hint-text {
              font-size: 12px;
              font-weight: 600;
              color: rgba(255, 255, 255, 0.9);
              background: rgba(103, 194, 58, 0.3);
              padding: 4px 12px;
              border-radius: 12px;
              border: 1px solid rgba(103, 194, 58, 0.5);
              white-space: nowrap;
              text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
            }
          }

          // 动态网格背景
          .grid-background {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            opacity: 0.15;
            pointer-events: none;

            .grid-line {
              position: absolute;
              background: linear-gradient(90deg, transparent, rgba(103, 194, 58, 0.3), transparent);
              height: 1px;
              width: 100%;
              animation: gridFlow 3s ease-in-out infinite;

              &:nth-child(1) { top: 16.66%; animation-delay: 0.2s; }
              &:nth-child(2) { top: 33.32%; animation-delay: 0.4s; }
              &:nth-child(3) { top: 49.98%; animation-delay: 0.6s; }
              &:nth-child(4) { top: 66.64%; animation-delay: 0.8s; }
              &:nth-child(5) { top: 83.3%; animation-delay: 1s; }
              &:nth-child(6) { top: 99.96%; animation-delay: 1.2s; }
            }
          }

          // 扫描线
          .scan-line {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 2px;
            background: linear-gradient(90deg, transparent, rgba(103, 194, 58, 0.8), transparent);
            box-shadow: 0 0 10px rgba(103, 194, 58, 0.8);
            pointer-events: none;
          }

          // 粒子效果
          .particles {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            pointer-events: none;

            .particle {
              position: absolute;
              width: 2px;
              height: 2px;
              background: rgba(103, 194, 58, 0.6);
              border-radius: 50%;
              animation: particleFloat 4s ease-in-out infinite;

              &:nth-child(1) { left: 12%; animation-delay: 0.3s; animation-duration: 3.5s; }
              &:nth-child(2) { left: 24%; animation-delay: 0.6s; animation-duration: 4s; }
              &:nth-child(3) { left: 36%; animation-delay: 0.9s; animation-duration: 4.5s; }
              &:nth-child(4) { left: 48%; animation-delay: 1.2s; animation-duration: 5s; }
              &:nth-child(5) { left: 60%; animation-delay: 1.5s; animation-duration: 5.5s; }
              &:nth-child(6) { left: 72%; animation-delay: 1.8s; animation-duration: 6s; }
              &:nth-child(7) { left: 84%; animation-delay: 2.1s; animation-duration: 6.5s; }
              &:nth-child(8) { left: 96%; animation-delay: 2.4s; animation-duration: 7s; }
            }
          }

          // 边框光效
          .border-glow {
            position: absolute;
            top: -2px;
            left: -2px;
            right: -2px;
            bottom: -2px;
            background: linear-gradient(45deg,
              rgba(103, 194, 58, 0.5),
              rgba(64, 158, 255, 0.5),
              rgba(103, 194, 58, 0.5));
            background-size: 200% 200%;
            border-radius: 20px;
            opacity: 0;
            filter: blur(8px);
            z-index: -1;
            animation: borderGlowMove 3s ease infinite;
            transition: opacity 0.5s;
          }

          // 内容区域
          .monitor-content {
            display: flex;
            align-items: center;
            gap: 20px;
            position: relative;
            z-index: 1;

            // 左侧视觉效果
            .monitor-visual {
              position: relative;
              width: 70px;
              height: 70px;
              flex-shrink: 0;
              display: flex;
              align-items: center;
              justify-content: center;

              // 脉冲圆环
              .pulse-rings {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);

                .pulse-ring {
                  position: absolute;
                  top: 50%;
                  left: 50%;
                  width: 70px;
                  height: 70px;
                  border: 2px solid rgba(103, 194, 58, 0.4);
                  border-radius: 50%;
                  transform: translate(-50%, -50%);
                  animation: pulseRing 2s ease-out infinite;

                  &:nth-child(2) {
                    animation-delay: 0.6s;
                  }

                  &:nth-child(3) {
                    animation-delay: 1.2s;
                  }
                }
              }

              // AI神经网络
              .ai-network {
                position: relative;
                width: 60px;
                height: 60px;
                z-index: 2;
                animation: networkRotate 8s linear infinite;

                // 中心节点
                .center-node {
                  position: absolute;
                  top: 50%;
                  left: 50%;
                  transform: translate(-50%, -50%);
                  width: 16px;
                  height: 16px;

                  .node-core {
                    width: 100%;
                    height: 100%;
                    background: linear-gradient(135deg, #67c23a, #409eff);
                    border-radius: 50%;
                    box-shadow:
                      0 0 15px rgba(103, 194, 58, 0.8),
                      0 0 30px rgba(64, 158, 255, 0.4),
                      inset 0 0 8px rgba(255, 255, 255, 0.3);
                    animation: centerNodePulse 2s ease-in-out infinite;
                  }
                }

                // 外围节点
                .outer-nodes {
                  position: absolute;
                  top: 50%;
                  left: 50%;
                  width: 100%;
                  height: 100%;
                  transform: translate(-50%, -50%);

                  .outer-node {
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    transform-origin: center;

                    .node-dot {
                      width: 8px;
                      height: 8px;
                      background: rgba(103, 194, 58, 0.8);
                      border: 1px solid rgba(103, 194, 58, 1);
                      border-radius: 50%;
                      box-shadow: 0 0 8px rgba(103, 194, 58, 0.6);
                      animation: outerNodeBlink 2s ease-in-out infinite;
                      animation-delay: inherit;
                    }

                    .connection-line {
                      position: absolute;
                      bottom: 0;
                      left: 50%;
                      width: 1px;
                      height: 25px;
                      background: linear-gradient(to top,
                        rgba(103, 194, 58, 0.6),
                        transparent);
                      transform: translateX(-50%);
                      animation: connectionPulse 2s ease-in-out infinite;
                      animation-delay: inherit;
                    }
                  }
                }

                // 数据流动粒子
                .data-particles {
                  position: absolute;
                  top: 50%;
                  left: 50%;
                  width: 100%;
                  height: 100%;
                  transform: translate(-50%, -50%);

                  .data-particle {
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    width: 3px;
                    height: 3px;
                    background: #409eff;
                    border-radius: 50%;
                    box-shadow: 0 0 6px rgba(64, 158, 255, 0.8);
                    animation: dataParticleMove 2s ease-in-out infinite;
                  }
                }
              }

              // 状态点
              .status-dot {
                position: absolute;
                top: 8px;
                right: 8px;
                z-index: 3;

                .dot-core {
                  display: block;
                  width: 10px;
                  height: 10px;
                  background: #67c23a;
                  border-radius: 50%;
                  box-shadow:
                    0 0 0 0 rgba(103, 194, 58, 0.7),
                    0 0 15px rgba(103, 194, 58, 0.8);
                  animation: statusDotPulse 2s ease-in-out infinite;
                }
              }
            }

            // 右侧信息区域
            .monitor-info {
              flex: 1;
              min-width: 0;

              .monitor-header {
                display: flex;
                align-items: center;
                gap: 10px;
                margin-bottom: 6px;

                .status-badge {
                  display: inline-flex;
                  align-items: center;
                  gap: 5px;
                  padding: 3px 10px;
                  background: rgba(103, 194, 58, 0.2);
                  border: 1px solid rgba(103, 194, 58, 0.5);
                  border-radius: 12px;
                  font-size: 11px;
                  font-weight: 700;
                  color: #67c23a;
                  letter-spacing: 1px;
                  text-transform: uppercase;

                  .badge-dot {
                    width: 6px;
                    height: 6px;
                    background: #67c23a;
                    border-radius: 50%;
                    animation: badgeDotBlink 1.5s ease-in-out infinite;
                  }
                }

                .monitor-title {
                  font-size: 18px;
                  font-weight: 700;
                  color: white;
                  letter-spacing: 0.5px;
                }
              }

              .monitor-subtitle {
                font-size: 12px;
                color: rgba(255, 255, 255, 0.7);
                margin-bottom: 10px;
                letter-spacing: 0.3px;
              }

              // 波形图
              .waveform {
                display: flex;
                align-items: flex-end;
                gap: 3px;
                height: 24px;

                .wave-bar {
                  flex: 1;
                  background: rgba(103, 194, 58, 0.4);
                  border-radius: 2px 2px 0 0;
                  min-width: 2px;
                  transition: all 0.3s;

                  &:nth-child(1) { height: 40%; }
                  &:nth-child(2) { height: 70%; }
                  &:nth-child(3) { height: 50%; }
                  &:nth-child(4) { height: 85%; }
                  &:nth-child(5) { height: 60%; }
                  &:nth-child(6) { height: 90%; }
                  &:nth-child(7) { height: 75%; }
                  &:nth-child(8) { height: 55%; }
                  &:nth-child(9) { height: 80%; }
                  &:nth-child(10) { height: 65%; }
                  &:nth-child(11) { height: 45%; }
                  &:nth-child(12) { height: 70%; }
                }
              }
            }
          }
        }
      }
    }
  }

  // 主内容区
  .main-content {
    padding: 32px 16px;

    .content-wrapper {
      max-width: 100%;
      width: 100%;
      margin: 0 auto;
      padding: 0 8px;
      display: flex;
      gap: 24px;

      // 左侧筛选栏
      .filter-sidebar {
        width: 260px;
        flex-shrink: 0;

        .filter-section {
          background: white;
          border-radius: 16px;
          padding: 20px;
          box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
          position: sticky;
          top: 24px;

          .filter-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 16px;
            border-bottom: 2px solid #f0f0f0;

            .filter-title {
              font-size: 16px;
              font-weight: 700;
              color: #303133;
              margin: 0;
              display: flex;
              align-items: center;
              gap: 8px;
            }
          }

          .filter-group {
            margin-bottom: 24px;

            &:last-child {
              margin-bottom: 0;
            }

            .filter-group-title {
              font-size: 13px;
              font-weight: 600;
              color: #606266;
              margin: 0 0 12px 0;
              text-transform: uppercase;
              letter-spacing: 0.5px;
            }

            .filter-tags {
              display: flex;
              flex-wrap: wrap;
              gap: 8px;

              .filter-tag {
                cursor: pointer;
                transition: all 0.3s;
                user-select: none;

                &:hover {
                  transform: translateY(-2px);
                  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
                }
              }
            }

            .filter-options {
              display: flex;
              flex-direction: column;
              gap: 4px;

              .filter-option {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 8px;
                padding: 10px 12px;
                border-radius: 8px;
                cursor: pointer;
                transition: all 0.2s;
                user-select: none;

                .option-label {
                  font-size: 14px;
                  color: #606266;
                  flex: 1;
                }

                .option-check {
                  color: #667eea;
                  font-size: 16px;
                  display: flex;
                  align-items: center;
                }

                &:hover {
                  background: #f5f7fa;
                }

                &.active {
                  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
                  border: 1px solid rgba(102, 126, 234, 0.3);

                  .option-label {
                    color: #667eea;
                    font-weight: 600;
                  }
                }
              }
            }
          }
        }
      }

      // 右侧模型列表
      .model-list-section {
        flex: 1;
        min-width: 0;
        width: 100%;

        .loading-wrapper,
        .empty-wrapper {
          background: white;
          border-radius: 16px;
          padding: 80px 40px;
          text-align: center;
          box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
        }

        // 模型网格
        .model-grid {
          margin-bottom: 32px;

          .model-card {
            margin-bottom: 20px;
            background: white;
            border-radius: 16px;
            padding: 24px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
            border: 1px solid #f0f0f0;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            cursor: pointer;
            position: relative;
            overflow: hidden;

            &::before {
              content: '';
              position: absolute;
              top: 0;
              left: 0;
              right: 0;
              height: 4px;
              background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
              opacity: 0;
              transition: opacity 0.3s;
            }

            // 尊享模型流光溢彩效果
            &.premium-card {
              border: 2px solid transparent;
              background-image:
                linear-gradient(white, white),
                linear-gradient(45deg, #ff0000, #ff8000, #ffff00, #00ff00, #00ffff, #0000ff, #8000ff, #ff0080);
              background-origin: border-box;
              background-clip: padding-box, border-box;
              animation: gradientFlow 3s ease infinite;
              background-size: 400% 400%;

              &::before {
                background: linear-gradient(90deg, #ff0000, #ff8000, #ffff00, #00ff00, #00ffff, #0000ff, #8000ff, #ff0080);
                background-size: 400% 400%;
                animation: gradientFlow 3s ease infinite;
                opacity: 1;
                height: 3px;
              }

              &:hover {
                box-shadow: 0 12px 32px rgba(255, 0, 128, 0.25);
              }
            }

            &:hover {
              transform: translateY(-4px);
              box-shadow: 0 12px 32px rgba(102, 126, 234, 0.15);
              border-color: #667eea;

              &::before {
                opacity: 1;
              }

              .copy-btn-corner {
                opacity: 1;
              }
            }

            // 右上角复制按钮
            .copy-btn-corner {
              position: absolute;
              top: 16px;
              right: 16px;
              z-index: 10;
              opacity: 1;
              transition: all 0.3s;
              background: rgba(255, 255, 255, 0.9);
              border: 1px solid #e0e0e0;
              box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

              &:hover {
                background: white;
                border-color: #667eea;
                color: #667eea;
                transform: scale(1.1);
              }
            }

            .model-card-header {
              display: flex;
              gap: 16px;
              margin-bottom: 16px;
              align-items: flex-start;

              .model-icon {
                width: 56px;
                height: 56px;
                flex-shrink: 0;

                .icon-img {
                  width: 100%;
                  height: 100%;
                  object-fit: cover;
                  border-radius: 12px;
                  border: 2px solid #f0f0f0;
                }

                .icon-placeholder {
                  width: 100%;
                  height: 100%;
                  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                  border-radius: 12px;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  color: white;
                  font-size: 24px;
                  font-weight: 700;
                }
              }

              .model-info {
                flex: 1;
                min-width: 0;
                display: flex;
                flex-direction: column;
                justify-content: center;

                .model-name {
                  font-size: 18px;
                  font-weight: 600;
                  color: #303133;
                  margin: 0 0 4px 0;
                  line-height: 1.4;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                  overflow: hidden;
                  padding-right: 24px; // 防止文字遮挡复制按钮
                }

                .model-provider {
                  font-size: 13px;
                  color: #909399;
                  font-weight: 500;
                }
              }
            }

            // ModelId 显示区域
            .model-id {
              margin-bottom: 12px;
              padding: 8px 12px;
              background: #f8f9fa;
              border-radius: 8px;
              font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
              display: flex;
              align-items: center;
              gap: 8px;

              .model-id-label {
                font-size: 11px;
                color: #909399;
                font-weight: 600;
                letter-spacing: 0.5px;
              }

              .model-id-value {
                font-size: 12px;
                color: #606266;
                flex: 1;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
              }
            }

            .model-description {
              font-size: 14px;
              color: #606266;
              line-height: 1.7;
              margin: 0 0 20px 0;
              -webkit-box-orient: vertical;
              min-height: 48px; /* 保持2行的高度 */
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-line-clamp: 2;
              line-clamp: 2;
              overflow: hidden;

              /* 添加过渡效果 */
              transition: all 0.3s ease;
              max-height: 3.4em; /* 2行高度 (1.7 * 2 = 3.4em) */

              &.placeholder {
                color: #c0c4cc;
                font-family: 'Monaco', 'Menlo', monospace;
                font-size: 12px;
              }

              /* 悬停时展开 */
              &:hover {
                -webkit-line-clamp: unset; /* 取消行数限制 */
                line-clamp: unset;
                max-height: none; /* 取消最大高度限制 */
                overflow: visible; /* 显示全部内容 */

                /* 可选：添加背景或边框突出显示 */
                background-color: #f9f9f9;
                //padding: 8px 12px;
                border-radius: 4px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
                //margin-bottom: 20px; /* 保持原有间距 */

                /* 如果是绝对定位的父容器，可以增加z-index */
                z-index: 10;
                position: relative;
              }
            }

            .model-footer {
              display: flex;
              justify-content: space-between;
              align-items: center;
              gap: 6px;
              padding-top: 16px;
              border-top: 1px solid #f0f0f0;

              .model-tags {
                display: flex;
                flex-wrap: wrap;
                gap: 6px;
                flex: 1;
              }

              .model-pricing {
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 6px 10px;
                background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%);
                border-radius: 8px;
                white-space: nowrap;
                flex-shrink: 0;

                .pricing-value {
                  font-size: 14px;
                  font-weight: 700;
                  color: #667eea;
                }
              }
            }
          }
        }

        // 分页
        .pagination-wrapper {
          display: flex;
          justify-content: center;
          padding: 0px 0;

          :deep(.el-pagination) {
            gap: 8px;

            .btn-prev,
            .btn-next {
              border-radius: 10px;
              padding: 0 16px;
              font-weight: 500;
              transition: all 0.3s;

              &:hover:not(:disabled) {
                color: #667eea;
                transform: translateY(-2px);
              }
            }

            .el-pager li {
              border-radius: 10px;
              min-width: 40px;
              height: 40px;
              line-height: 40px;
              transition: all 0.3s;

              &:hover {
                color: #667eea;
                transform: translateY(-2px);
              }

              &.is-active {
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
              }
            }
          }
        }
      }
    }
  }
}

// 流光溢彩动画
@keyframes gradientFlow {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

@media screen and (max-width: 768px) {
  .model-library-container {
    .banner-section {
      padding: 24px 16px;

      .banner-content {
        .banner-header {
          flex-direction: column;
          align-items: stretch;
          gap: 24px;

          .banner-left {
            flex-direction: column;
            align-items: flex-start;
            gap: 24px;

            .stats-cards {
              width: 100%;
              flex-wrap: wrap;

              .stat-card {
                flex: 1;
                min-width: 140px;
              }
            }
          }

          .monitor-card {
            width: 100%;
          }
        }
      }
    }

    .main-content {
      padding: 16px 12px;

      .content-wrapper {
        flex-direction: column;
        padding: 0;

        .filter-sidebar {
          width: 0;
          height: 0;
          overflow: hidden;

          &.mobile-active {
            width: auto;
            height: auto;
            overflow: visible;

            .mobile-overlay {
              position: fixed;
              top: 0;
              left: 0;
              right: 0;
              bottom: 0;
              background: rgba(0, 0, 0, 0.5);
              z-index: 1999;
              backdrop-filter: blur(4px);
            }

            .filter-section {
              position: fixed;
              top: 0;
              left: 0;
              bottom: 0;
              width: 80%;
              max-width: 320px;
              z-index: 2000;
              border-radius: 0 16px 16px 0;
              overflow-y: auto;
              animation: slideIn 0.3s ease;
            }
          }

          .filter-section {
            margin: 0;

            .filter-header {
              .filter-header-actions {
                display: flex;
                align-items: center;
                gap: 16px;

                .close-btn {
                  font-size: 20px;
                  cursor: pointer;
                  color: #909399;

                  &:hover {
                    color: #606266;
                  }
                }
              }
            }
          }
        }

        .model-list-section {
          .mobile-filter-bar {
            margin-bottom: 16px;
            position: sticky;
            top: 0;
            z-index: 100;
            background: rgba(245, 247, 250, 0.95);
            backdrop-filter: blur(10px);
            padding: 12px 4px;
            margin: -16px -4px 16px -4px;

            .w-full {
              width: 100%;
              box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            }
          }

          .pagination-wrapper {
            :deep(.el-pagination) {
              .el-pagination__jump {
                display: none !important;
              }
            }
          }

          .model-grid {
            margin-bottom: 24px;

            .model-card {
              padding: 20px; // 增加内边距
              margin-bottom: 16px; // 增加卡片间距
              border-radius: 16px;

              .copy-btn-corner {
                top: 16px;
                right: 16px;
                width: 32px;
                height: 32px;
                font-size: 14px;
              }

              .model-card-header {
                margin-bottom: 16px;
                gap: 16px;

                .model-icon {
                  width: 48px;
                  height: 48px;

                  .icon-placeholder {
                    font-size: 20px;
                    border-radius: 10px;
                  }

                  .icon-img {
                    border-radius: 10px;
                  }
                }

                .model-info {
                  .model-name {
                    font-size: 17px;
                    margin-bottom: 4px;
                    padding-right: 36px; // 移动端预留更多空间给复制按钮
                  }

                  .model-provider {
                    font-size: 13px;
                  }
                }
              }

              .model-id {
                padding: 6px 10px;
                margin-bottom: 12px;

                .model-id-label {
                  font-size: 11px;
                }

                .model-id-value {
                  font-size: 11px;
                }
              }

              .model-description {
                font-size: 13px;
                line-height: 1.5;
                margin-bottom: 12px;
                min-height: auto;
                -webkit-line-clamp: 2;
                max-height: 3em;

                &:hover {
                  /* 移动端取消悬停展开，或者改为点击展开（这里简单处理为取消悬停效果以免遮挡） */
                  -webkit-line-clamp: 2;
                  max-height: 3em;
                  overflow: hidden;
                  position: static;
                  box-shadow: none;
                  background: transparent;
                  padding: 0;
                }
              }

              .model-footer {
                padding-top: 12px;
                gap: 8px;

                .model-tags {
                  gap: 4px;

                  :deep(.el-tag) {
                    height: 20px;
                    padding: 0 6px;
                    font-size: 10px;
                  }
                }

                .model-pricing {
                  padding: 4px 8px;

                  .pricing-value {
                    font-size: 12px;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

@keyframes slideIn {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}

@keyframes heartbeat {
  0% { transform: scale(1); }
  14% { transform: scale(1.3); }
  28% { transform: scale(1); }
  42% { transform: scale(1.3); }
  70% { transform: scale(1); }
}

@keyframes pulse {
  0% { opacity: 1; box-shadow: 0 0 0 0 rgba(103, 194, 58, 0.7); }
  70% { opacity: 0.7; box-shadow: 0 0 0 6px rgba(103, 194, 58, 0); }
  100% { opacity: 1; box-shadow: 0 0 0 0 rgba(103, 194, 58, 0); }
}

// 网格流动
@keyframes gridFlow {
  0%, 100% {
    opacity: 0.15;
    transform: translateX(0);
  }
  50% {
    opacity: 0.3;
    transform: translateX(10px);
  }
}

// 扫描线移动
@keyframes scanMove {
  0% {
    top: 0;
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    top: 100%;
    opacity: 0;
  }
}

// 粒子漂浮
@keyframes particleFloat {
  0% {
    transform: translateY(100%);
    opacity: 0;
  }
  10% {
    opacity: 0.6;
  }
  90% {
    opacity: 0.6;
  }
  100% {
    transform: translateY(-100%);
    opacity: 0;
  }
}

// 边框光效移动
@keyframes borderGlowMove {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

// 点击引导浮动
@keyframes clickHintFloat {
  0%, 100% {
    transform: translate(-50%, -50%);
  }
  50% {
    transform: translate(-50%, -55%);
  }
}

// 手势点击动画
@keyframes handClick {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(0.9);
  }
}

// 脉冲圆环
@keyframes pulseRing {
  0% {
    transform: translate(-50%, -50%) scale(0.8);
    opacity: 0.6;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.4);
    opacity: 0;
  }
}

// 3D立方体旋转
@keyframes cubeRotate {
  0% {
    transform: rotateX(-20deg) rotateY(-20deg);
  }
  100% {
    transform: rotateX(-20deg) rotateY(340deg);
  }
}

// AI神经网络旋转
@keyframes networkRotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

// 中心节点脉冲
@keyframes centerNodePulse {
  0%, 100% {
    transform: scale(1);
    box-shadow:
      0 0 15px rgba(103, 194, 58, 0.8),
      0 0 30px rgba(64, 158, 255, 0.4),
      inset 0 0 8px rgba(255, 255, 255, 0.3);
  }
  50% {
    transform: scale(1.2);
    box-shadow:
      0 0 25px rgba(103, 194, 58, 1),
      0 0 50px rgba(64, 158, 255, 0.6),
      inset 0 0 12px rgba(255, 255, 255, 0.5);
  }
}

// 状态点脉冲
@keyframes statusDotPulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(103, 194, 58, 0.7), 0 0 15px rgba(103, 194, 58, 0.8);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(103, 194, 58, 0), 0 0 25px rgba(103, 194, 58, 1);
  }
}

// 徽章点闪烁
@keyframes badgeDotBlink {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(0.8);
  }
}

// 波形脉冲
@keyframes waveformPulse {
  0%, 100% {
    background: rgba(103, 194, 58, 0.4);
    transform: scaleY(1);
  }
  50% {
    background: rgba(103, 194, 58, 0.8);
    transform: scaleY(1.3);
  }
}

// 外围节点闪烁
@keyframes outerNodeBlink {
  0%, 100% {
    opacity: 0.6;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.3);
  }
}

// 连接线脉冲
@keyframes connectionPulse {
  0%, 100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}

// 数据粒子移动
@keyframes dataParticleMove {
  0% {
    transform: translate(-50%, -50%) translateY(0) scale(0);
    opacity: 0;
  }
  20% {
    opacity: 1;
    transform: translate(-50%, -50%) translateY(-5px) scale(1);
  }
  80% {
    opacity: 1;
    transform: translate(-50%, -50%) translateY(-20px) scale(1);
  }
  100% {
    transform: translate(-50%, -50%) translateY(-25px) scale(0);
    opacity: 0;
  }
}
</style>
