diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 0000000..5ae3e1a
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,23 @@
+/**
+ * App 根组件
+ */
+
+import React from 'react'
+import { RouterProvider } from 'react-router-dom'
+import { ConfigProvider, App as AntApp } from 'antd'
+import zhCN from 'antd/locale/zh_CN'
+import router from './router'
+import { heritageTheme } from '@theme/index'
+import '@styles/global.css'
+
+const App: React.FC = () => {
+ return (
+
+
+
+
+
+ )
+}
+
+export default App
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 0000000..83294a8
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,13 @@
+/**
+ * 应用入口文件
+ */
+
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App'
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+)
diff --git a/src/router/index.tsx b/src/router/index.tsx
new file mode 100644
index 0000000..740c464
--- /dev/null
+++ b/src/router/index.tsx
@@ -0,0 +1,96 @@
+/**
+ * 路由配置
+ */
+
+import React from 'react'
+import { createBrowserRouter, Navigate } from 'react-router-dom'
+import MainLayout from '@layout/MainLayout'
+import Home from '@pages/Home'
+import HeritageList from '@pages/Heritage/List'
+import HeritageDetail from '@pages/Heritage/Detail'
+import InheritorsList from '@pages/Inheritors/List'
+import InheritorDetail from '@pages/Inheritor/Detail'
+import NewsPage from '@pages/News'
+import NewsDetail from '@pages/News/Detail'
+import EventDetail from '@pages/News/EventDetail'
+import Login from '@pages/User/Login'
+import Register from '@pages/User/Register'
+import UserCenter from '@pages/User/Center'
+import SearchPage from '@pages/Search'
+import DataVisualization from '@pages/Data'
+import About from '@pages/About'
+
+const router = createBrowserRouter([
+ {
+ path: '/',
+ element: ,
+ children: [
+ {
+ index: true,
+ element: ,
+ },
+ {
+ path: 'heritage',
+ element: ,
+ },
+ {
+ path: 'heritage/categories/:category',
+ element: ,
+ },
+ {
+ path: 'heritage/:id',
+ element: ,
+ },
+ {
+ path: 'inheritors',
+ element: ,
+ },
+ {
+ path: 'inheritor/:id',
+ element: ,
+ },
+ {
+ path: 'search',
+ element: ,
+ },
+ {
+ path: 'data',
+ element: ,
+ },
+ {
+ path: 'user/center',
+ element: ,
+ },
+ {
+ path: 'about',
+ element: ,
+ },
+ {
+ path: 'news',
+ element: ,
+ },
+ {
+ path: 'news/:id',
+ element: ,
+ },
+ {
+ path: 'events/:id',
+ element: ,
+ },
+ {
+ path: '*',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: '/login',
+ element: ,
+ },
+ {
+ path: '/register',
+ element: ,
+ },
+])
+
+export default router
diff --git a/src/styles/global.css b/src/styles/global.css
new file mode 100644
index 0000000..108e55f
--- /dev/null
+++ b/src/styles/global.css
@@ -0,0 +1,547 @@
+/**
+ * 非遗文化传承网站 - 全局样式
+ * 包含渐变背景、动画效果、响应式断点、传统纹样装饰等
+ */
+
+/* ===== 全局重置与基础样式 ===== */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 16px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ text-rendering: optimizeLegibility;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
+ 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', 'Noto Sans SC',
+ 'Microsoft YaHei';
+ font-size: 14px;
+ line-height: 1.5715;
+ color: #2c2c2c;
+ background-color: #fafaf8;
+ overflow-x: hidden;
+}
+
+#root {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+/* ===== 滚动条美化 ===== */
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: #f5f0e8;
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #d4a574;
+ border-radius: 4px;
+ transition: background 0.3s ease;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #c8363d;
+}
+
+/* ===== 选中文本样式 ===== */
+::selection {
+ background-color: rgba(200, 54, 61, 0.2);
+ color: #2c2c2c;
+}
+
+::-moz-selection {
+ background-color: rgba(200, 54, 61, 0.2);
+ color: #2c2c2c;
+}
+
+/* ===== 渐变背景工具类 ===== */
+.gradient-bg-primary {
+ background: linear-gradient(135deg, #c8363d 0%, #8b252b 100%);
+}
+
+.gradient-bg-warm {
+ background: linear-gradient(135deg, #fff9f0 0%, #f5f0e8 100%);
+}
+
+.gradient-bg-elegant {
+ background: linear-gradient(135deg, #fafaf8 0%, #ffffff 50%, #f5f0e8 100%);
+}
+
+.gradient-text-primary {
+ background: linear-gradient(135deg, #c8363d 0%, #d4a574 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+/* ===== 传统纹样装饰 ===== */
+.pattern-cloud {
+ position: relative;
+}
+
+.pattern-cloud::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 80px;
+ background-image: url("data:image/svg+xml,%3Csvg width='100' height='80' viewBox='0 0 100 80' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 40 Q 20 20, 30 40 T 50 40 T 70 40 T 90 40' stroke='%23E8E3DB' fill='none' stroke-width='1' opacity='0.3'/%3E%3C/svg%3E");
+ background-repeat: repeat-x;
+ background-size: 100px 80px;
+ pointer-events: none;
+}
+
+.pattern-wave {
+ position: relative;
+}
+
+.pattern-wave::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 60px;
+ background-image: url("data:image/svg+xml,%3Csvg width='100%25' height='60' viewBox='0 0 1200 60' preserveAspectRatio='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0,30 Q300,0 600,30 T1200,30 L1200,60 L0,60 Z' fill='%23F5F0E8'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-size: cover;
+ pointer-events: none;
+}
+
+/* ===== 卡片阴影层级 ===== */
+.shadow-sm {
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+}
+
+.shadow-md {
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+}
+
+.shadow-lg {
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
+}
+
+.shadow-xl {
+ box-shadow: 0 12px 48px rgba(0, 0, 0, 0.2);
+}
+
+/* 纸张层叠效果 */
+.shadow-paper {
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 4px 8px rgba(0, 0, 0, 0.06),
+ 0 1px 2px rgba(0, 0, 0, 0.04);
+}
+
+/* ===== 玻璃态效果 ===== */
+.glass-effect {
+ background: rgba(255, 255, 255, 0.85);
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ border: 1px solid rgba(232, 227, 219, 0.3);
+}
+
+.glass-effect-dark {
+ background: rgba(44, 44, 44, 0.8);
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+/* ===== 动画效果 ===== */
+
+/* 渐显动画 */
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeInDown {
+ from {
+ opacity: 0;
+ transform: translateY(-30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* 缩放动画 */
+@keyframes scaleIn {
+ from {
+ opacity: 0;
+ transform: scale(0.9);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+/* 滑入动画 */
+@keyframes slideInLeft {
+ from {
+ opacity: 0;
+ transform: translateX(-50px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes slideInRight {
+ from {
+ opacity: 0;
+ transform: translateX(50px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+/* 脉冲动画 */
+@keyframes pulse {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.5;
+ }
+}
+
+/* 浮动动画 */
+@keyframes float {
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(-10px);
+ }
+}
+
+/* 动画工具类 */
+.animate-fade-in {
+ animation: fadeIn 0.6s ease-out;
+}
+
+.animate-fade-in-up {
+ animation: fadeInUp 0.8s ease-out;
+}
+
+.animate-fade-in-down {
+ animation: fadeInDown 0.8s ease-out;
+}
+
+.animate-scale-in {
+ animation: scaleIn 0.5s ease-out;
+}
+
+.animate-slide-in-left {
+ animation: slideInLeft 0.8s ease-out;
+}
+
+.animate-slide-in-right {
+ animation: slideInRight 0.8s ease-out;
+}
+
+.animate-pulse {
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+}
+
+.animate-float {
+ animation: float 3s ease-in-out infinite;
+}
+
+/* ===== 过渡效果 ===== */
+.transition-smooth {
+ transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+}
+
+.transition-fast {
+ transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+}
+
+.transition-slow {
+ transition: all 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
+}
+
+/* ===== 悬停效果 ===== */
+.hover-lift {
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+
+.hover-lift:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+}
+
+.hover-glow {
+ transition: box-shadow 0.3s ease;
+}
+
+.hover-glow:hover {
+ box-shadow: 0 0 20px rgba(200, 54, 61, 0.3);
+}
+
+.hover-scale {
+ transition: transform 0.3s ease;
+}
+
+.hover-scale:hover {
+ transform: scale(1.05);
+}
+
+/* ===== 文本样式 ===== */
+.text-serif {
+ font-family: 'Noto Serif SC', 'Songti SC', Georgia, serif;
+}
+
+.text-gradient-primary {
+ background: linear-gradient(135deg, #c8363d 0%, #d4a574 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ font-weight: 600;
+}
+
+.text-shadow-sm {
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.text-shadow-md {
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
+}
+
+/* ===== 容器与布局 ===== */
+.container-full {
+ width: 100%;
+ padding-left: 24px;
+ padding-right: 24px;
+ margin: 0 auto;
+}
+
+.container {
+ width: 100%;
+ max-width: 1200px;
+ padding-left: 24px;
+ padding-right: 24px;
+ margin: 0 auto;
+}
+
+.container-wide {
+ width: 100%;
+ max-width: 1440px;
+ padding-left: 24px;
+ padding-right: 24px;
+ margin: 0 auto;
+}
+
+.section-spacing {
+ padding: 80px 0;
+}
+
+.section-spacing-lg {
+ padding: 120px 0;
+}
+
+.section-spacing-sm {
+ padding: 60px 0;
+}
+
+/* ===== 响应式断点 ===== */
+
+/* 平板 */
+@media (max-width: 992px) {
+ .container,
+ .container-wide,
+ .container-full {
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+
+ .section-spacing {
+ padding: 60px 0;
+ }
+
+ .section-spacing-lg {
+ padding: 80px 0;
+ }
+
+ .section-spacing-sm {
+ padding: 40px 0;
+ }
+}
+
+/* 移动设备 */
+@media (max-width: 768px) {
+ html {
+ font-size: 14px;
+ }
+
+ .container,
+ .container-wide,
+ .container-full {
+ padding-left: 16px;
+ padding-right: 16px;
+ }
+
+ .section-spacing {
+ padding: 40px 0;
+ }
+
+ .section-spacing-lg {
+ padding: 60px 0;
+ }
+
+ .section-spacing-sm {
+ padding: 32px 0;
+ }
+}
+
+/* 小屏移动设备 */
+@media (max-width: 576px) {
+ .section-spacing {
+ padding: 32px 0;
+ }
+
+ .section-spacing-lg {
+ padding: 48px 0;
+ }
+
+ .section-spacing-sm {
+ padding: 24px 0;
+ }
+}
+
+/* ===== 工具类 ===== */
+.text-center {
+ text-align: center;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.flex {
+ display: flex;
+}
+
+.flex-center {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.flex-between {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.flex-column {
+ display: flex;
+ flex-direction: column;
+}
+
+.relative {
+ position: relative;
+}
+
+.absolute {
+ position: absolute;
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.cursor-pointer {
+ cursor: pointer;
+}
+
+/* ===== 图片优化 ===== */
+img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+}
+
+.img-cover {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.img-contain {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+/* ===== 骨架屏优化 ===== */
+.skeleton-loading {
+ background: linear-gradient(
+ 90deg,
+ #f5f0e8 25%,
+ rgba(245, 240, 232, 0.5) 50%,
+ #f5f0e8 75%
+ );
+ background-size: 200% 100%;
+ animation: skeleton-loading 1.5s ease-in-out infinite;
+}
+
+@keyframes skeleton-loading {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+}
+
+/* ===== 打印样式 ===== */
+@media print {
+ body {
+ background: white;
+ }
+
+ .no-print {
+ display: none !important;
+ }
+}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1 @@
+///