App.vue 2 KB
<template>
  <a-config-provider :theme="themeConfig">
    <router-view />
  </a-config-provider>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useAppStore } from '@/stores/app'

const app = useAppStore()

const themeConfig = computed(() => ({
  token: {
    colorPrimary: '#8c7cf0',
    borderRadius: 12,
    fontFamily: 'Outfit, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif',
    ...(app.isDarkMode
      ? {
          colorBgBase: '#14111d',
          colorBgLayout: '#14111d',
          colorBgContainer: '#1e1a2e',
          colorBgElevated: '#28243c',
          colorTextBase: '#eeecf1',
          colorText: '#eeecf1',
          colorTextSecondary: '#c7c3d5',
          colorTextTertiary: '#a4a0b8',
          colorTextQuaternary: '#8a869b',
          colorTextHeading: '#ffffff',
          colorTextDescription: '#a4a0b8',
          colorTextPlaceholder: '#8a869b',
          colorTextDisabled: '#7f7a93',
          colorIcon: '#d9d6e5',
          colorIconHover: '#ffffff',
          colorBorder: 'rgba(255, 255, 255, 0.14)',
          colorBorderSecondary: 'rgba(255, 255, 255, 0.1)',
          colorFill: 'rgba(255, 255, 255, 0.16)',
          colorFillSecondary: 'rgba(255, 255, 255, 0.12)',
          colorFillTertiary: 'rgba(255, 255, 255, 0.08)',
          colorFillQuaternary: 'rgba(255, 255, 255, 0.06)',
          colorFillAlter: 'rgba(255, 255, 255, 0.06)',
        }
      : {}),
  },
}))
</script>

<style>
body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  background: linear-gradient(90deg, #8c7cf0, #f1bfd8);
  z-index: 9999;
  width: 0;
  transition: width 0.3s ease;
}

body.loading::before {
  width: 80%;
  animation: loading-pulse 2s infinite linear;
}

@keyframes loading-pulse {
  0% { width: 0%; opacity: 1; }
  50% { width: 70%; opacity: 0.8; }
  100% { width: 90%; opacity: 0.6; }
}

body:not(.loading)::before {
  width: 100%;
  opacity: 0;
  transition: width 0.3s ease, opacity 0.3s 0.2s ease;
}
</style>