<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 - 页面未找到</title>
<script src="http://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<style>
  :root {
    --bg: #0a0a14;
    --accent: #6c5ce7;
    --accent2: #a29bfe;
    --text: #e0e0f0;
    --muted: #8888a8;
  }

  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    background: var(--bg);
    font-family: 'Georgia', 'Noto Serif SC', 'STSong', 'Songti SC', serif;
    color: var(--text);
    overflow: hidden;
    height: 100vh;
    width: 100vw;
  }

  #app {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    position: relative;
  }

  /* 星轨背景容器 */
  .starfield {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
  }

  /* 主内容层 */
  .error-container {
    position: relative;
    z-index: 1;
    text-align: center;
    padding: 2rem;
    animation: fadeInUp 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  @keyframes fadeInUp {
    from {
      opacity: 0;
      transform: translateY(40px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  /* 404数字 */
  .error-code {
    font-family: 'Georgia', 'Times New Roman', serif;
    font-size: clamp(8rem, 20vw, 16rem);
    font-weight: 700;
    line-height: 1;
    background: linear-gradient(
      135deg,
      #a29bfe 0%,
      #6c5ce7 25%,
      #fd79a8 50%,
      #6c5ce7 75%,
      #a29bfe 100%
    );
    background-size: 300% 300%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: gradientShift 6s ease-in-out infinite;
    letter-spacing: -0.02em;
    filter: drop-shadow(0 0 40px rgba(108, 92, 231, 0.4));
  }

  @keyframes gradientShift {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
  }

  /* 标题 */
  .error-title {
    font-size: clamp(1.3rem, 3vw, 1.8rem);
    font-weight: 400;
    color: var(--accent2);
    margin-top: 0.5rem;
    letter-spacing: 0.3em;
    animation: fadeInUp 1.2s 0.2s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  /* 分割线 */
  .divider {
    width: 60px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
    margin: 1.8rem auto;
    animation: fadeInUp 1.2s 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  /* 描述文字 */
  .error-desc {
    font-size: clamp(0.9rem, 1.5vw, 1.05rem);
    color: var(--muted);
    line-height: 1.8;
    max-width: 420px;
    margin: 0 auto;
    animation: fadeInUp 1.2s 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  /* 返回按钮 */
  .btn-home {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 2.5rem;
    padding: 0.85rem 2.5rem;
    font-family: inherit;
    font-size: 1rem;
    color: var(--text);
    background: transparent;
    border: 1px solid rgba(108, 92, 231, 0.5);
    border-radius: 50px;
    cursor: pointer;
    letter-spacing: 0.08em;
    text-decoration: none;
    transition: all 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
    position: relative;
    overflow: hidden;
    animation: fadeInUp 1.2s 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  .btn-home::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--accent);
    opacity: 0;
    transition: opacity 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
    z-index: -1;
    border-radius: 50px;
  }

  .btn-home:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow: 0 8px 32px rgba(108, 92, 231, 0.3);
  }

  .btn-home:hover::before {
    opacity: 1;
  }

  .btn-home:active {
    transform: translateY(0);
  }

  .btn-arrow {
    display: inline-block;
    transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
    font-size: 1.1rem;
  }

  .btn-home:hover .btn-arrow {
    transform: translateX(4px);
  }

  /* 浮动光晕 */
  .glow-orb {
    position: fixed;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.12;
    pointer-events: none;
    z-index: 0;
    animation: orbFloat 10s ease-in-out infinite;
  }

  @keyframes orbFloat {
    0%, 100% { transform: translate(0, 0) scale(1); }
    25% { transform: translate(30px, -20px) scale(1.08); }
    50% { transform: translate(-10px, 15px) scale(0.95); }
    75% { transform: translate(-25px, -10px) scale(1.05); }
  }

  /* 响应式 */
  @media (max-width: 480px) {
    .error-container {
      padding: 1.2rem;
    }
    .divider {
      margin: 1.2rem auto;
    }
  }
</style>
</head>
<body>
<div id="app">
  <!-- 浮动光晕 -->
  <div class="glow-orb" :style="orbStyle1"></div>
  <div class="glow-orb" :style="orbStyle2"></div>

  <!-- 星轨背景 -->
  <canvas ref="starCanvas" class="starfield"></canvas>

  <!-- 主内容 -->
  <div class="error-container">
    <div class="error-code">404</div>
    <div class="error-title">{{ title }}</div>
    <div class="divider"></div>
    <div class="error-desc">{{ description }}</div>
    <button class="btn-home" @click="goHome">
      {{ btnText }}<span class="btn-arrow">→</span>
    </button>
  </div>
</div>

<script>
const { createApp, ref, reactive, onMounted, onUnmounted } = Vue;

createApp({
  setup() {
    const starCanvas = ref(null);
    let animFrameId = null;
    let stars = [];
    let mouseX = 0;
    let mouseY = 0;
    let canvasW = 0;
    let canvasH = 0;

    const title = ref('页面未找到');
    const description = ref('您访问的页面不存在或已被移除，请检查链接地址是否正确。');
    const btnText = ref('返回首页');

    const orbStyle1 = reactive({
      width: '350px',
      height: '350px',
      background: '#6c5ce7',
      top: '15%',
      left: '10%',
    });

    const orbStyle2 = reactive({
      width: '280px',
      height: '280px',
      background: '#fd79a8',
      bottom: '20%',
      right: '12%',
      animationDelay: '-5s',
    });

    /** 星空初始化 */
    function initStars(width, height) {
      const count = Math.floor((width * height) / 2800);
      stars = [];
      for (let i = 0; i < count; i++) {
        stars.push({
          x: Math.random() * width,
          y: Math.random() * height,
          r: Math.random() * 1.5 + 0.4,
          twinkleSpeed: Math.random() * 0.015 + 0.005,
          twinkleOffset: Math.random() * Math.PI * 2,
          alpha: Math.random() * 0.6 + 0.4,
        });
      }
    }

    /** 绘制星空 */
    function drawStars(ctx, time) {
      ctx.clearRect(0, 0, canvasW, canvasH);

      const parallaxX = (mouseX - canvasW / 2) * 0.015;
      const parallaxY = (mouseY - canvasH / 2) * 0.015;

      for (const s of stars) {
        const dx = s.x + parallaxX * s.r;
        const dy = s.y + parallaxY * s.r;
        const alpha = s.alpha + Math.sin(time * s.twinkleSpeed + s.twinkleOffset) * 0.3;

        ctx.beginPath();
        ctx.arc(dx, dy, s.r, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(200,200,240,${Math.max(0.1, alpha)})`;
        ctx.fill();

        // 较大星星添加光晕
        if (s.r > 1.1) {
          const glow = ctx.createRadialGradient(dx, dy, 0, dx, dy, s.r * 3);
          glow.addColorStop(0, `rgba(160,155,240,${alpha * 0.35})`);
          glow.addColorStop(1, 'rgba(160,155,240,0)');
          ctx.beginPath();
          ctx.arc(dx, dy, s.r * 3, 0, Math.PI * 2);
          ctx.fillStyle = glow;
          ctx.fill();
        }
      }
    }

    /** 动画循环 */
    function animate(time) {
      if (!starCanvas.value) return;
      const ctx = starCanvas.value.getContext('2d');
      drawStars(ctx, time);
      animFrameId = requestAnimationFrame(animate);
    }

    /** 处理窗口大小变化 */
    function handleResize() {
      if (!starCanvas.value) return;
      const dpr = window.devicePixelRatio || 1;
      canvasW = window.innerWidth;
      canvasH = window.innerHeight;
      starCanvas.value.width = canvasW * dpr;
      starCanvas.value.height = canvasH * dpr;
      starCanvas.value.style.width = canvasW + 'px';
      starCanvas.value.style.height = canvasH + 'px';
      const ctx = starCanvas.value.getContext('2d');
      ctx.scale(dpr, dpr);
      initStars(canvasW, canvasH);
    }

    /** 鼠标移动 */
    function handleMouseMove(e) {
      mouseX = e.clientX;
      mouseY = e.clientY;
    }

    /** 返回首页 */
    function goHome() {
      window.location.href = '/';
    }

    onMounted(() => {
      handleResize();
      animFrameId = requestAnimationFrame(animate);
      window.addEventListener('resize', handleResize);
      window.addEventListener('mousemove', handleMouseMove);
    });

    onUnmounted(() => {
      if (animFrameId) cancelAnimationFrame(animFrameId);
      window.removeEventListener('resize', handleResize);
      window.removeEventListener('mousemove', handleMouseMove);
    });

    return {
      starCanvas,
      title,
      description,
      btnText,
      orbStyle1,
      orbStyle2,
      goHome,
    };
  },
}).mount('#app');
</script>
</body>
</html>
