yangjinhaowife vor 6 Tagen
Commit
891ddec88b
11 geänderte Dateien mit 3401 neuen und 0 gelöschten Zeilen
  1. 3 0
      .bolt/config.json
  2. 24 0
      .gitignore
  3. 252 0
      api-adapter.js
  4. 9 0
      counter.js
  5. 2068 0
      index.html
  6. 1 0
      javascript.svg
  7. 24 0
      main.js
  8. 909 0
      package-lock.json
  9. 14 0
      package.json
  10. 1 0
      public/vite.svg
  11. 96 0
      style.css

+ 3 - 0
.bolt/config.json

@@ -0,0 +1,3 @@
+{
+  "template": "vite"
+}

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 252 - 0
api-adapter.js

@@ -0,0 +1,252 @@
+// API基础URL
+const API_BASE_URL = 'http://localhost:3000/api';
+
+// 岗位相关API
+const JobAPI = {
+    // 获取所有岗位
+    getAllJobs: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs`);
+            if (!response.ok) throw new Error('获取岗位列表失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取岗位列表错误:', error);
+            return [];
+        }
+    },
+    
+    // 获取单个岗位详情
+    getJobById: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}`);
+            if (!response.ok) throw new Error('获取岗位详情失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取岗位详情错误:', error);
+            return null;
+        }
+    },
+    
+    // 创建新岗位
+    createJob: async (jobData) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs`, {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify(jobData)
+            });
+            if (!response.ok) throw new Error('创建岗位失败');
+            return await response.json();
+        } catch (error) {
+            console.error('创建岗位错误:', error);
+            throw error;
+        }
+    },
+    
+    // 更新岗位
+    updateJob: async (id, jobData) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}`, {
+                method: 'PUT',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify(jobData)
+            });
+            if (!response.ok) throw new Error('更新岗位失败');
+            return await response.json();
+        } catch (error) {
+            console.error('更新岗位错误:', error);
+            throw error;
+        }
+    },
+    
+    // 删除岗位
+    deleteJob: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}`, {
+                method: 'DELETE'
+            });
+            if (!response.ok) throw new Error('删除岗位失败');
+            return await response.json();
+        } catch (error) {
+            console.error('删除岗位错误:', error);
+            throw error;
+        }
+    },
+    
+    // 启动智能筛选
+    startScreening: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}/screen`, {
+                method: 'POST'
+            });
+            if (!response.ok) throw new Error('启动筛选失败');
+            return await response.json();
+        } catch (error) {
+            console.error('启动筛选错误:', error);
+            throw error;
+        }
+    },
+    
+    // 获取岗位候选人列表
+    getJobCandidates: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}/candidates`);
+            if (!response.ok) throw new Error('获取候选人列表失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取候选人列表错误:', error);
+            return { candidates: [] };
+        }
+    },
+    
+    // 发布草稿岗位
+    publishDraft: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/jobs/${id}/publish`, {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify({})
+            });
+            if (!response.ok) throw new Error('发布岗位失败');
+            return await response.json();
+        } catch (error) {
+            console.error('发布岗位错误:', error);
+            throw error;
+        }
+    }
+};
+
+// 候选人相关API
+const CandidateAPI = {
+    // 获取所有候选人
+    getAllCandidates: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/candidates`);
+            if (!response.ok) throw new Error('获取候选人列表失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取候选人列表错误:', error);
+            return [];
+        }
+    },
+    
+    // 获取单个候选人详情
+    getCandidateDetails: async (id) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/candidates/${id}`);
+            if (!response.ok) throw new Error('获取候选人详情失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取候选人详情错误:', error);
+            return null;
+        }
+    },
+    
+    // 更新候选人状态
+    updateCandidateStatus: async (id, status) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/candidates/${id}/status`, {
+                method: 'PUT',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify({ status })
+            });
+            if (!response.ok) throw new Error('更新候选人状态失败');
+            return await response.json();
+        } catch (error) {
+            console.error('更新候选人状态错误:', error);
+            throw error;
+        }
+    },
+    
+    // 添加候选人
+    addCandidate: async (candidateData) => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/candidates`, {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify(candidateData)
+            });
+            if (!response.ok) throw new Error('添加候选人失败');
+            return await response.json();
+        } catch (error) {
+            console.error('添加候选人错误:', error);
+            throw error;
+        }
+    }
+};
+
+// 统计数据相关API
+const StatisticsAPI = {
+    // 获取招聘总览统计
+    getOverviewStats: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/statistics/overview`);
+            if (!response.ok) throw new Error('获取招聘总览统计失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取招聘总览统计错误:', error);
+            return {
+                totalJobs: 0,
+                totalCandidates: 0,
+                pendingResumes: 0,
+                passedResumes: 0
+            };
+        }
+    },
+    
+    // 获取部门招聘统计
+    getDepartmentStats: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/statistics/departments`);
+            if (!response.ok) throw new Error('获取部门招聘统计失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取部门招聘统计错误:', error);
+            return [];
+        }
+    },
+    
+    // 获取筛选效率统计
+    getScreeningEfficiencyStats: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/statistics/screening-efficiency`);
+            if (!response.ok) throw new Error('获取筛选效率统计失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取筛选效率统计错误:', error);
+            return [];
+        }
+    },
+    
+    // 获取候选人评分分布
+    getScoreDistribution: async () => {
+        try {
+            const response = await fetch(`${API_BASE_URL}/statistics/score-distribution`);
+            if (!response.ok) throw new Error('获取候选人评分分布失败');
+            return await response.json();
+        } catch (error) {
+            console.error('获取候选人评分分布错误:', error);
+            return [];
+        }
+    }
+};
+
+// 导出API
+const API = {
+    Job: JobAPI,
+    Candidate: CandidateAPI,
+    Statistics: StatisticsAPI
+};
+
+// 全局挂载API
+window.API = API; 

+ 9 - 0
counter.js

@@ -0,0 +1,9 @@
+export function setupCounter(element) {
+  let counter = 0
+  const setCounter = (count) => {
+    counter = count
+    element.innerHTML = `count is ${counter}`
+  }
+  element.addEventListener('click', () => setCounter(counter + 1))
+  setCounter(0)
+}

+ 2068 - 0
index.html

@@ -0,0 +1,2068 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>HR招聘管理系统</title>
+    <script src="https://cdn.tailwindcss.com"></script>
+    <script>
+        tailwind.config = {
+            theme: {
+                extend: {
+                    colors: {
+                        primary: '#3B82F6',
+                        success: '#10B981',
+                        warning: '#F59E0B',
+                        danger: '#EF4444',
+                        secondary: '#6B7280'
+                    }
+                }
+            }
+        }
+    </script>
+    <!-- 引入API适配器 -->
+    <script src="api-adapter.js"></script>
+    <style>
+        .page {
+            display: none;
+            animation: slideInRight 0.3s ease-out;
+        }
+        
+        .page.active {
+            display: block;
+        }
+        
+        @keyframes slideInRight {
+            from {
+                transform: translateX(100%);
+                opacity: 0;
+            }
+            to {
+                transform: translateX(0);
+                opacity: 1;
+            }
+        }
+        
+        @keyframes slideInLeft {
+            from {
+                transform: translateX(-100%);
+                opacity: 0;
+            }
+            to {
+                transform: translateX(0);
+                opacity: 1;
+            }
+        }
+        
+        .slide-back {
+            animation: slideInLeft 0.3s ease-out;
+        }
+        
+        .card-hover:active {
+            transform: scale(0.98);
+            transition: transform 0.1s;
+        }
+        
+        .btn-active:active {
+            transform: scale(0.95);
+            transition: transform 0.1s;
+        }
+        
+        .progress-ring {
+            transform: rotate(-90deg);
+        }
+        
+        .progress-ring-bar {
+            transition: stroke-dashoffset 0.5s;
+        }
+        
+        /* 自定义滚动条 */
+        .custom-scrollbar::-webkit-scrollbar {
+            width: 4px;
+        }
+        
+        .custom-scrollbar::-webkit-scrollbar-track {
+            background: #f1f5f9;
+        }
+        
+        .custom-scrollbar::-webkit-scrollbar-thumb {
+            background: #cbd5e1;
+            border-radius: 2px;
+        }
+
+        /* 底部导航栏样式 */
+        .bottom-nav {
+            position: fixed;
+            bottom: 0;
+            left: 0;
+            right: 0;
+            background: white;
+            border-top: 1px solid #e5e7eb;
+            z-index: 50;
+        }
+
+        .nav-item {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            padding: 8px 4px;
+            transition: all 0.2s;
+        }
+
+        .nav-item.active {
+            color: #3B82F6;
+        }
+
+        .nav-item:not(.active) {
+            color: #6B7280;
+        }
+
+        /* 加载动画 */
+        .loading-spinner {
+            border: 2px solid #f3f4f6;
+            border-top: 2px solid #3B82F6;
+            border-radius: 50%;
+            width: 16px;
+            height: 16px;
+            animation: spin 1s linear infinite;
+        }
+
+        @keyframes spin {
+            0% { transform: rotate(0deg); }
+            100% { transform: rotate(360deg); }
+        }
+
+        /* Toast 样式 */
+        .toast {
+            position: fixed;
+            top: 20px;
+            left: 50%;
+            transform: translateX(-50%);
+            background: #1f2937;
+            color: white;
+            padding: 12px 24px;
+            border-radius: 8px;
+            z-index: 100;
+            animation: slideDown 0.3s ease-out;
+        }
+
+        @keyframes slideDown {
+            from {
+                transform: translateX(-50%) translateY(-100%);
+                opacity: 0;
+            }
+            to {
+                transform: translateX(-50%) translateY(0);
+                opacity: 1;
+            }
+        }
+    </style>
+</head>
+<body class="bg-gray-50 min-h-screen">
+    <main class="max-w-md mx-auto bg-white min-h-screen relative pb-16">
+        <!-- 页面一:岗位管理页 -->
+        <div id="page-job-management" class="page active">
+            <!-- 顶部导航 -->
+            <header class="bg-white border-b border-gray-200 px-4 py-3 sticky top-0 z-10">
+                <div class="flex items-center justify-between">
+                    <h1 class="text-lg font-semibold text-gray-900">岗位管理</h1>
+                    <button onclick="createNewJob()" class="w-10 h-10 bg-primary text-white rounded-full flex items-center justify-center btn-active hover:bg-blue-600 transition-colors">
+                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
+                        </svg>
+                    </button>
+                </div>
+            </header>
+            
+            <!-- 岗位列表 -->
+            <div id="job-management-container" class="p-4 space-y-4">
+                <!-- 动态生成岗位卡片 -->
+            </div>
+        </div>
+
+        <!-- 页面二:创建/编辑岗位页 -->
+        <div id="page-create-job" class="page">
+            <!-- 顶部导航 -->
+            <header class="bg-white border-b border-gray-200 px-4 py-3 sticky top-0 z-10">
+                <div class="flex items-center justify-between">
+                    <button onclick="goBack()" class="p-2 -ml-2 text-gray-500 hover:text-gray-700">
+                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
+                        </svg>
+                    </button>
+                    <h1 id="create-job-title" class="text-lg font-semibold text-gray-900">创建新岗位</h1>
+                    <div class="flex space-x-2">
+                        <button onclick="saveJob()" class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-medium btn-active hover:bg-gray-200 transition-colors">
+                            保存草稿
+                        </button>
+                        <button onclick="publishJob()" class="px-4 py-2 bg-primary text-white rounded-lg text-sm font-medium btn-active hover:bg-blue-600 transition-colors">
+                            发布
+                        </button>
+                    </div>
+                </div>
+            </header>
+            
+            <!-- 表单内容 -->
+            <div class="p-4 space-y-6 custom-scrollbar overflow-y-auto" style="height: calc(100vh - 140px);">
+                <!-- 基础信息卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">基础信息</h3>
+                    <div class="space-y-4">
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">岗位名称</label>
+                            <input id="job-title" type="text" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入岗位名称">
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">所属部门</label>
+                            <select id="job-department" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent">
+                                <option value="">请选择部门</option>
+                                <option value="技术部">技术部</option>
+                                <option value="产品部">产品部</option>
+                                <option value="设计部">设计部</option>
+                                <option value="市场部">市场部</option>
+                                <option value="销售部">销售部</option>
+                                <option value="人事部">人事部</option>
+                            </select>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">工作地点</label>
+                            <select id="job-location" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent">
+                                <option value="">请选择工作地点</option>
+                                <option value="北京">北京</option>
+                                <option value="上海">上海</option>
+                                <option value="深圳">深圳</option>
+                                <option value="杭州">杭州</option>
+                                <option value="广州">广州</option>
+                                <option value="远程办公">远程办公</option>
+                            </select>
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 岗位描述卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">岗位描述</h3>
+                    <textarea id="job-description" rows="6" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请详细描述岗位职责、任职要求等信息..."></textarea>
+                </div>
+
+                <!-- 人才基本面卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">人才基本面</h3>
+                    <div class="space-y-4">
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">职位描述</label>
+                            <textarea id="job-position-desc" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请输入职位描述..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">技能和经验要求</label>
+                            <div id="skills-container" class="space-y-2">
+                                <input type="text" class="skill-item w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入技能要求...">
+                            </div>
+                            <button onclick="addSkillItem()" class="mt-2 px-3 py-1 bg-gray-100 text-gray-600 rounded text-sm hover:bg-gray-200 transition-colors">
+                                + 添加技能要求
+                            </button>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">公司文化和价值观</label>
+                            <textarea id="company-culture" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述公司文化和价值观..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">薪酬范围和福利</label>
+                            <textarea id="salary-benefits" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述薪酬范围和福利..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">工作地点和安排</label>
+                            <textarea id="work-arrangement" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述工作地点和安排..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">职业发展机会</label>
+                            <textarea id="career-development" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述职业发展机会..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">特殊要求或条件</label>
+                            <textarea id="special-requirements" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述特殊要求或条件..."></textarea>
+                        </div>
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 mb-2">招聘流程和时间线</label>
+                            <textarea id="recruitment-process" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none" placeholder="请描述招聘流程和时间线..."></textarea>
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 简历评分准则卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">简历评分准则</h3>
+                    <div class="space-y-4">
+                        <!-- 维度权重设置 -->
+                        <div class="p-3 bg-gray-50 rounded-lg">
+                            <h4 class="font-medium text-gray-800 mb-3">维度权重设置</h4>
+                            <div class="space-y-3">
+                                <div class="flex items-center">
+                                    <span class="w-24 text-sm text-gray-700">工作经验:</span>
+                                    <input type="number" id="exp-weight" min="0" max="100" class="w-16 px-2 py-1 border border-gray-300 rounded text-sm mr-1" value="30">
+                                    <span class="text-sm text-gray-700">%</span>
+                                </div>
+                                <div class="flex items-center">
+                                    <span class="w-24 text-sm text-gray-700">技术能力:</span>
+                                    <input type="number" id="tech-weight" min="0" max="100" class="w-16 px-2 py-1 border border-gray-300 rounded text-sm mr-1" value="40">
+                                    <span class="text-sm text-gray-700">%</span>
+                                </div>
+                                <div class="flex items-center">
+                                    <span class="w-24 text-sm text-gray-700">软性技能:</span>
+                                    <input type="number" id="soft-weight" min="0" max="100" class="w-16 px-2 py-1 border border-gray-300 rounded text-sm mr-1" value="20">
+                                    <span class="text-sm text-gray-700">%</span>
+                                </div>
+                                <div class="flex items-center">
+                                    <span class="w-24 text-sm text-gray-700">其他:</span>
+                                    <input type="number" id="other-weight" min="0" max="100" class="w-16 px-2 py-1 border border-gray-300 rounded text-sm mr-1" value="10">
+                                    <span class="text-sm text-gray-700">%</span>
+                                </div>
+                                <div id="weight-error" class="text-xs text-red-500 hidden">总权重必须等于100%</div>
+                            </div>
+                        </div>
+
+                        <!-- 工作经验评分 -->
+                        <div class="p-3 bg-gray-50 rounded-lg">
+                            <div class="flex items-center justify-between mb-2">
+                                <h4 class="font-medium text-gray-800">工作经验</h4>
+                                <button onclick="addExpItem()" class="px-2 py-1 bg-gray-100 text-xs text-gray-600 rounded hover:bg-gray-200 transition-colors">
+                                    + 添加条件
+                                </button>
+                            </div>
+                            <div id="exp-criteria-container" class="space-y-3">
+                                <div class="exp-item">
+                                    <div class="flex items-center mb-1">
+                                        <input type="number" class="exp-years w-12 px-2 py-1 border border-gray-300 rounded text-sm mr-2" value="2">
+                                        <input type="text" class="exp-desc flex-1 px-2 py-1 border border-gray-300 rounded text-sm" value="年以上相关工作经验" placeholder="年以上相关工作经验">
+                                    </div>
+                                    <div class="text-xs text-gray-500 ml-2">(符合:满分30分;不符合:0分)</div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <!-- 技术能力评分 -->
+                        <div class="p-3 bg-gray-50 rounded-lg">
+                            <div class="flex items-center justify-between mb-2">
+                                <h4 class="font-medium text-gray-800">技术能力</h4>
+                                <button onclick="addTechItem()" class="px-2 py-1 bg-gray-100 text-xs text-gray-600 rounded hover:bg-gray-200 transition-colors">
+                                    + 添加技能
+                                </button>
+                            </div>
+                            <div id="tech-criteria-container" class="space-y-3">
+                                <!-- 示例技能项 -->
+                                <div class="tech-item">
+                                    <div class="mb-1">
+                                        <input type="text" class="tech-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称" value="编程语言">
+                                        <input type="text" class="tech-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述" value="熟练掌握Java基础,熟悉常用数据结构与算法">
+                                    </div>
+                                    <div class="flex space-x-2 mt-1">
+                                        <label class="flex items-center text-xs text-gray-700">
+                                            <input type="radio" name="tech-score-1" value="15" checked class="mr-1 tech-score-high"> 优秀(
+                                            <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="15">分)
+                                        </label>
+                                        <label class="flex items-center text-xs text-gray-700">
+                                            <input type="radio" name="tech-score-1" value="10" class="mr-1 tech-score-med"> 良好(
+                                            <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                                        </label>
+                                        <label class="flex items-center text-xs text-gray-700">
+                                            <input type="radio" name="tech-score-1" value="5" class="mr-1 tech-score-low"> 一般(
+                                            <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="5">分)
+                                        </label>
+                                        <button onclick="removeTechItem(this)" class="text-red-500 hover:text-red-700">
+                                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                            </svg>
+                                        </button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <!-- 软性技能评分 -->
+                        <div class="p-3 bg-gray-50 rounded-lg">
+                            <div class="flex items-center justify-between mb-2">
+                                <h4 class="font-medium text-gray-800">软性技能</h4>
+                                <button onclick="addSoftItem()" class="px-2 py-1 bg-gray-100 text-xs text-gray-600 rounded hover:bg-gray-200 transition-colors">
+                                    + 添加技能
+                                </button>
+                            </div>
+                            <div id="soft-criteria-container" class="space-y-3">
+                                <div class="soft-item flex items-center justify-between">
+                                    <div>
+                                        <input type="text" class="soft-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称" value="学习能力">
+                                        <input type="text" class="soft-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述" value="简历或自我评价中体现出较强的学习能力">
+                                    </div>
+                                    <div class="flex items-center ml-4">
+                                        <label class="flex items-center text-sm text-gray-700 mr-4">
+                                            <input type="radio" name="soft-score-1" value="10" checked class="mr-1 soft-score-yes"> 有(
+                                            <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                                        </label>
+                                        <label class="flex items-center text-sm text-gray-700">
+                                            <input type="radio" name="soft-score-1" value="0" class="mr-1 soft-score-no"> 无(0分)
+                                        </label>
+                                        <button onclick="removeSoftItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                            </svg>
+                                        </button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <!-- 其他评分 -->
+                        <div class="p-3 bg-gray-50 rounded-lg">
+                            <div class="flex items-center justify-between mb-2">
+                                <h4 class="font-medium text-gray-800">其他</h4>
+                                <button onclick="addOtherItem()" class="px-2 py-1 bg-gray-100 text-xs text-gray-600 rounded hover:bg-gray-200 transition-colors">
+                                    + 添加条件
+                                </button>
+                            </div>
+                            <div id="other-criteria-container" class="space-y-3">
+                                <div class="other-item flex items-center justify-between">
+                                    <div>
+                                        <input type="text" class="other-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="条件名称" value="教育背景">
+                                        <input type="text" class="other-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="条件描述" value="本科及以上学历">
+                                    </div>
+                                    <div class="flex items-center ml-4">
+                                        <label class="flex items-center text-sm text-gray-700 mr-4">
+                                            <input type="radio" name="other-score-1" value="10" checked class="mr-1 other-score-yes"> 符合(
+                                            <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                                        </label>
+                                        <label class="flex items-center text-sm text-gray-700">
+                                            <input type="radio" name="other-score-1" value="0" class="mr-1 other-score-no"> 不符合(0分)
+                                        </label>
+                                        <button onclick="removeOtherItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                            </svg>
+                                        </button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <!-- 通过标准 -->
+                        <div class="mt-4">
+                            <div class="flex items-center justify-between">
+                                <label class="block font-medium text-gray-800">通过标准:</label>
+                                <div class="flex items-center">
+                                    <input type="number" id="passing-score" class="w-16 px-2 py-1 border border-gray-300 rounded text-sm" value="60">
+                                    <span class="ml-1 text-sm text-gray-700">分以上</span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <!-- AI筛选硬性指标卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <div class="flex items-center justify-between mb-4">
+                        <h3 class="font-semibold text-gray-900">AI筛选硬性指标</h3>
+                        <button onclick="addCriteria()" class="px-3 py-1 bg-primary text-white rounded text-sm btn-active hover:bg-blue-600 transition-colors">
+                            + 添加指标
+                        </button>
+                    </div>
+                    <div id="criteria-container" class="space-y-3">
+                        <!-- 动态生成筛选指标 -->
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- 页面三:候选人列表页 -->
+        <div id="page-candidate-list" class="page">
+            <!-- 顶部导航 -->
+            <header class="bg-white border-b border-gray-200 px-4 py-3 sticky top-0 z-10">
+                <div class="flex items-center">
+                    <button onclick="goBack()" class="p-2 -ml-2 text-gray-500 hover:text-gray-700 mr-2">
+                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
+                        </svg>
+                    </button>
+                    <h1 id="candidate-list-title" class="text-lg font-semibold text-gray-900">候选人列表</h1>
+                </div>
+            </header>
+            
+            <!-- 候选人列表 -->
+            <div id="candidate-list-container" class="p-4 space-y-4">
+                <!-- 动态生成候选人卡片 -->
+            </div>
+        </div>
+
+        <!-- 页面四:简历详情页 -->
+        <div id="page-resume-detail" class="page">
+            <!-- 顶部导航 -->
+            <header class="bg-white border-b border-gray-200 px-4 py-3 sticky top-0 z-10">
+                <div class="flex items-center">
+                    <button onclick="goBack()" class="p-2 -ml-2 text-gray-500 hover:text-gray-700 mr-2">
+                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
+                        </svg>
+                    </button>
+                    <h1 id="resume-detail-title" class="text-lg font-semibold text-gray-900">候选人详情</h1>
+                </div>
+            </header>
+
+            <!-- Tab 切换 -->
+            <nav class="bg-white border-b border-gray-200">
+                <div class="flex">
+                    <button id="tab-ai-analysis" onclick="switchTab('ai-analysis')" class="flex-1 py-3 px-4 text-center font-medium text-primary border-b-2 border-primary">
+                        AI分析
+                    </button>
+                    <button id="tab-resume-content" onclick="switchTab('resume-content')" class="flex-1 py-3 px-4 text-center font-medium text-gray-500 border-b-2 border-transparent">
+                        简历原文
+                    </button>
+                </div>
+            </nav>
+
+            <!-- AI分析内容 -->
+            <div id="content-ai-analysis" class="tab-content p-4 pb-24">
+                <!-- 匹配度仪表盘 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-4 text-center">
+                    <div class="relative inline-block">
+                        <svg class="progress-ring w-24 h-24" viewBox="0 0 100 100">
+                            <circle cx="50" cy="50" r="45" fill="none" stroke="#f1f5f9" stroke-width="8"/>
+                            <circle id="progress-circle" cx="50" cy="50" r="45" fill="none" stroke="#3B82F6" stroke-width="8" 
+                                    stroke-linecap="round" class="progress-ring-bar"
+                                    stroke-dasharray="283" stroke-dashoffset="113"/>
+                        </svg>
+                        <div class="absolute inset-0 flex items-center justify-center">
+                            <span id="score-display" class="text-2xl font-bold text-gray-900">88</span>
+                        </div>
+                    </div>
+                    <p class="text-gray-600 mt-2">匹配度评分</p>
+                </div>
+
+                <!-- AI分析详情 -->
+                <div id="ai-analysis-details" class="space-y-4">
+                    <!-- 动态生成分析内容 -->
+                </div>
+            </div>
+
+            <!-- 简历原文内容 -->
+            <div id="content-resume-content" class="tab-content hidden p-4 pb-24">
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <div id="resume-text" class="text-sm text-gray-700 leading-relaxed custom-scrollbar max-h-96 overflow-y-auto">
+                        <!-- 动态生成简历内容 -->
+                    </div>
+                </div>
+            </div>
+
+            <!-- 底部操作栏 -->
+            <footer class="fixed bottom-16 left-0 right-0 bg-white border-t border-gray-200 p-4 max-w-md mx-auto">
+                <div class="flex space-x-3">
+                    <button onclick="handleReject()" class="flex-1 bg-gray-500 text-white py-3 px-4 rounded-lg font-medium btn-active hover:bg-gray-600 transition-colors">
+                        不合适
+                    </button>
+                    <button onclick="handleApprove()" class="flex-1 bg-success text-white py-3 px-4 rounded-lg font-medium btn-active hover:bg-green-600 transition-colors">
+                        通过初筛
+                    </button>
+                </div>
+            </footer>
+        </div>
+
+        <!-- 页面五:数据统计页 -->
+        <div id="page-statistics" class="page">
+            <!-- 顶部导航 -->
+            <header class="bg-white border-b border-gray-200 px-4 py-3 sticky top-0 z-10">
+                <div class="flex items-center justify-between">
+                    <h1 class="text-lg font-semibold text-gray-900">数据统计</h1>
+                </div>
+            </header>
+            
+            <!-- 统计内容 -->
+            <div class="p-4 space-y-4">
+                <!-- 总览卡片 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">招聘总览</h3>
+                    <div class="grid grid-cols-2 gap-4">
+                        <div class="text-center">
+                            <div class="text-2xl font-bold text-primary" id="total-jobs">0</div>
+                            <div class="text-sm text-gray-600">活跃岗位</div>
+                        </div>
+                        <div class="text-center">
+                            <div class="text-2xl font-bold text-success" id="total-candidates">0</div>
+                            <div class="text-sm text-gray-600">候选人总数</div>
+                        </div>
+                        <div class="text-center">
+                            <div class="text-2xl font-bold text-warning" id="pending-resumes">0</div>
+                            <div class="text-sm text-gray-600">待处理简历</div>
+                        </div>
+                        <div class="text-center">
+                            <div class="text-2xl font-bold text-success" id="passed-resumes">0</div>
+                            <div class="text-sm text-gray-600">已通过初筛</div>
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 部门统计 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-4">部门招聘情况</h3>
+                    <div id="department-stats" class="space-y-3">
+                        <!-- 动态生成部门统计 -->
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- 底部导航栏 -->
+        <nav class="bottom-nav max-w-md mx-auto">
+            <div class="flex">
+                <button onclick="switchPage('page-job-management')" class="flex-1 nav-item active" id="nav-jobs">
+                    <svg class="w-6 h-6 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2-2v2m8 0V6a2 2 0 012 2v6a2 2 0 01-2 2H8a2 2 0 01-2-2V8a2 2 0 012-2V6"></path>
+                    </svg>
+                    <span class="text-xs">岗位管理</span>
+                </button>
+                <button onclick="switchPage('page-candidate-list')" class="flex-1 nav-item" id="nav-candidates">
+                    <svg class="w-6 h-6 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
+                    </svg>
+                    <span class="text-xs">候选人</span>
+                </button>
+                <button onclick="switchPage('page-statistics')" class="flex-1 nav-item" id="nav-stats">
+                    <svg class="w-6 h-6 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
+                    </svg>
+                    <span class="text-xs">数据统计</span>
+                </button>
+            </div>
+        </nav>
+    </main>
+
+    <script>
+        // 模拟数据
+        const mockData = {
+            jobs: [
+                {
+                    id: 1,
+                    title: "资深产品经理",
+                    department: "产品部",
+                    location: "北京",
+                    status: "招聘中",
+                    pendingResumes: 12,
+                    passedResumes: 3,
+                    description: "负责产品规划和设计,具备良好的用户体验意识",
+                    criteria: [
+                        { field: "学历", condition: "大于等于", value: "本科" },
+                        { field: "工作年限", condition: "大于等于", value: "5年" },
+                        { field: "必要技能", condition: "包含", value: "产品设计" }
+                    ],
+                    talentProfile: {
+                        positionDesc: "资深产品经理,负责公司核心产品的规划、设计和迭代优化。",
+                        skills: [
+                            "5年以上产品管理经验",
+                            "熟悉产品设计流程和方法",
+                            "具备数据分析能力",
+                            "良好的沟通协调能力",
+                            "对用户体验有深刻理解"
+                        ],
+                        companyCulture: "积极向上,鼓励创新,注重团队合作,重视个人发展。",
+                        salaryBenefits: "25K-35K,五险一金、带薪年假、定期体检等。",
+                        workArrangement: "北京,全职。",
+                        careerDevelopment: "提供内部培训、晋升通道,鼓励员工不断提升技能。",
+                        specialRequirements: "有B端产品经验优先。",
+                        recruitmentProcess: "简历筛选 -> 笔试 -> 面试 -> 最终录用,预计2周内完成"
+                    },
+                    scoringCriteria: {
+                        expYears: "5",
+                        internshipYears: "1",
+                        javaScore: "10",
+                        frontendScore: "7",
+                        databaseScore: "7",
+                        frameworkScore: "3",
+                        learningAbility: "10",
+                        teamwork: "10",
+                        education: "10",
+                        projectScore: "8",
+                        passingScore: "70"
+                    },
+                    candidates: [
+                        {
+                            id: 101,
+                            name: "张三",
+                            score: 88,
+                            tags: ["SaaS经验", "5年经验", "B端产品"],
+                            status: "pending"
+                        },
+                        {
+                            id: 102,
+                            name: "李四",
+                            score: 92,
+                            tags: ["电商背景", "团队管理", "数据驱动"],
+                            status: "pending"
+                        }
+                    ]
+                },
+                {
+                    id: 2,
+                    title: "前端工程师",
+                    department: "技术部",
+                    location: "上海",
+                    status: "招聘中",
+                    pendingResumes: 8,
+                    passedResumes: 5,
+                    description: "负责前端开发工作,熟练掌握React、Vue等框架",
+                    criteria: [
+                        { field: "学历", condition: "大于等于", value: "大专" },
+                        { field: "工作年限", condition: "大于等于", value: "3年" },
+                        { field: "必要技能", condition: "包含", value: "React" }
+                    ],
+                    talentProfile: {
+                        positionDesc: "前端工程师,负责公司Web应用的开发、维护和优化。",
+                        skills: [
+                            "3年以上前端开发经验",
+                            "熟练掌握HTML5、CSS3、JavaScript",
+                            "熟悉React、Vue等前端框架",
+                            "了解Node.js和常用构建工具",
+                            "有良好的代码风格和团队合作精神"
+                        ],
+                        companyCulture: "开放包容,技术驱动,鼓励创新,重视个人成长。",
+                        salaryBenefits: "15K-25K,五险一金、带薪年假、免费健身等。",
+                        workArrangement: "上海,全职。",
+                        careerDevelopment: "提供技术分享会、内部培训,有晋升为技术专家或管理岗的机会。",
+                        specialRequirements: "有大型Web应用开发经验优先。",
+                        recruitmentProcess: "简历筛选 -> 技术面试 -> HR面试 -> Offer,预计3周内完成"
+                    },
+                    scoringCriteria: {
+                        expYears: "3",
+                        internshipYears: "1",
+                        javaScore: "5",
+                        frontendScore: "15",
+                        databaseScore: "3",
+                        frameworkScore: "5",
+                        learningAbility: "10",
+                        teamwork: "10",
+                        education: "10",
+                        projectScore: "7",
+                        passingScore: "65"
+                    },
+                    candidates: [
+                        {
+                            id: 201,
+                            name: "赵六",
+                            score: 85,
+                            tags: ["React", "Vue", "TypeScript"],
+                            status: "pending"
+                        }
+                    ]
+                },
+                {
+                    id: 3,
+                    title: "Java开发工程师",
+                    department: "技术部",
+                    location: "上海",
+                    status: "招聘中",
+                    pendingResumes: 15,
+                    passedResumes: 4,
+                    description: "负责公司项目的后端开发、维护和优化。",
+                    criteria: [
+                        { field: "学历", condition: "大于等于", value: "本科" },
+                        { field: "工作年限", condition: "大于等于", value: "2年" },
+                        { field: "必要技能", condition: "包含", value: "Java" }
+                    ],
+                    talentProfile: {
+                        positionDesc: "初级Java开发工程师,负责公司项目的开发、维护和优化。",
+                        skills: [
+                            "2年以上Java或Java Web开发经验",
+                            "熟练使用Java后台技术",
+                            "熟练使用HTML5、CSS等前端技术",
+                            "熟练使用SQL语言",
+                            "熟悉SpringMVC、SSM、SpringBoot等Web框架",
+                            "有较强的学习能力",
+                            "有良好的创新精神和团队协作经验"
+                        ],
+                        companyCulture: "积极向上,鼓励创新,注重团队合作,重视个人发展。",
+                        salaryBenefits: "根据经验和能力面议,五险一金、带薪年假、定期体检等。",
+                        workArrangement: "上海,全职。",
+                        careerDevelopment: "提供内部培训、晋升通道,鼓励员工不断提升技能。",
+                        specialRequirements: "无。",
+                        recruitmentProcess: "简历筛选 -> 笔试 -> 面试 -> 最终录用,预计2周内完成"
+                    },
+                    scoringCriteria: {
+                        expYears: "2",
+                        internshipYears: "1",
+                        javaScore: "15",
+                        frontendScore: "10",
+                        databaseScore: "10",
+                        frameworkScore: "5",
+                        learningAbility: "10",
+                        teamwork: "10",
+                        education: "10",
+                        projectScore: "5",
+                        passingScore: "60"
+                    },
+                    candidates: [
+                        {
+                            id: 301,
+                            name: "王五",
+                            score: 78,
+                            tags: ["Java", "Spring", "MySQL"],
+                            status: "pending"
+                        },
+                        {
+                            id: 302,
+                            name: "刘七",
+                            score: 82,
+                            tags: ["Java", "微服务", "Docker"],
+                            status: "pending"
+                        }
+                    ]
+                }
+            ],
+            resumeDetails: {
+                101: {
+                    name: "张三",
+                    score: 88,
+                    summary: "候选人具有丰富的B端产品管理经验,在SaaS领域有深入理解,具备良好的数据分析能力和用户洞察力。",
+                    pros: [
+                        "5年产品管理经验,其中3年专注于B端SaaS产品",
+                        "成功主导过用户量从0到10万的产品项目",
+                        "具备良好的数据敏感度,熟练使用各种分析工具",
+                        "有跨部门协作经验,沟通能力强"
+                    ],
+                    cons: [
+                        "缺乏C端产品经验,对用户增长策略了解有限",
+                        "技术背景相对薄弱,对开发流程理解不够深入"
+                    ],
+                    resumeText: `
+                        姓名:张三
+                        联系电话:138****1234
+                        邮箱:zhangsan@email.com
+                        
+                        教育背景:
+                        2015-2019 北京理工大学 工商管理学士
+                        
+                        工作经历:
+                        2019.7-至今 ABC科技有限公司 产品经理
+                        - 负责B端SaaS产品的规划和设计,用户量从0增长到10万+
+                        - 主导产品需求分析,完成用户调研和竞品分析
+                        - 协调开发、设计、测试团队,确保产品按时交付
+                        
+                        技能特长:
+                        - 熟练使用Axure、Figma等产品设计工具
+                        - 具备SQL数据查询能力,熟悉Google Analytics等分析工具
+                        - 了解前端开发基础,能与技术团队有效沟通
+                    `
+                },
+                102: {
+                    name: "李四",
+                    score: 92,
+                    summary: "优秀的产品管理人才,具有丰富的电商和数据产品经验,团队管理能力突出。",
+                    pros: [
+                        "6年产品管理经验,涵盖电商、数据分析等多个领域",
+                        "有成功的团队管理经验,曾带领15人产品团队",
+                        "具备强大的商业敏感度,主导过多个商业化项目"
+                    ],
+                    cons: [
+                        "主要经验集中在C端产品,B端产品经验相对较少"
+                    ],
+                    resumeText: `
+                        姓名:李四
+                        联系电话:139****5678
+                        邮箱:lisi@email.com
+                        
+                        教育背景:
+                        2014-2018 清华大学 计算机科学与技术学士
+                        
+                        工作经历:
+                        2020.3-至今 DEF电商集团 高级产品经理
+                        - 负责电商平台核心交易流程优化,GMV提升30%
+                        - 带领15人产品团队,负责用户增长和留存策略
+                    `
+                }
+            }
+        };
+
+        // 当前状态
+        let currentJobId = null;
+        let currentCandidateId = null;
+        let pageHistory = [];
+        let editingJobId = null;
+
+        // 页面初始化
+        document.addEventListener('DOMContentLoaded', function() {
+            renderJobManagement();
+            updateStatistics();
+            
+            // 确保新建岗位按钮可点击
+            const addJobBtn = document.querySelector('button[onclick="createNewJob()"]');
+            if (addJobBtn) {
+                addJobBtn.addEventListener('click', createNewJob);
+            }
+        });
+
+        // 页面切换函数
+        function showPage(pageId, isBack = false) {
+            // 隐藏所有页面
+            document.querySelectorAll('.page').forEach(page => {
+                page.classList.remove('active');
+                if (isBack) {
+                    page.classList.add('slide-back');
+                }
+            });
+            
+            // 显示目标页面
+            const targetPage = document.getElementById(pageId);
+            targetPage.classList.add('active');
+            
+            // 更新历史记录
+            if (!isBack) {
+                pageHistory.push(pageId);
+            }
+        }
+
+        // 底部导航切换
+        function switchPage(pageId) {
+            // 更新导航状态
+            document.querySelectorAll('.nav-item').forEach(item => {
+                item.classList.remove('active');
+            });
+            
+            // 根据页面ID设置对应的导航项为活跃状态
+            if (pageId === 'page-job-management') {
+                document.getElementById('nav-jobs').classList.add('active');
+            } else if (pageId === 'page-candidate-list') {
+                document.getElementById('nav-candidates').classList.add('active');
+                renderAllCandidates();
+            } else if (pageId === 'page-statistics') {
+                document.getElementById('nav-stats').classList.add('active');
+                updateStatistics();
+            }
+            
+            // 重置页面历史
+            pageHistory = [pageId];
+            showPage(pageId);
+        }
+
+        // 返回上一页
+        function goBack() {
+            if (pageHistory.length > 1) {
+                pageHistory.pop(); // 移除当前页
+                const previousPage = pageHistory[pageHistory.length - 1];
+                showPage(previousPage, true);
+            }
+        }
+
+        // 渲染岗位管理页面
+        async function renderJobManagement() {
+            const container = document.getElementById('job-management-container');
+            container.innerHTML = '<div class="flex justify-center py-10"><div class="loading-spinner"></div></div>';
+            
+            try {
+                const jobs = await API.Job.getAllJobs();
+                
+                if (jobs.length === 0) {
+                    container.innerHTML = `
+                        <div class="text-center py-10">
+                            <p class="text-gray-500">暂无岗位数据</p>
+                            <button onclick="createNewJob()" class="mt-4 px-4 py-2 bg-primary text-white rounded-lg">
+                                创建新岗位
+                            </button>
+                        </div>
+                    `;
+                    return;
+                }
+                
+                container.innerHTML = jobs.map(job => `
+                    <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                        <div class="flex items-start justify-between mb-3">
+                            <div class="flex-1">
+                                <h3 class="font-semibold text-gray-900">${job.title}</h3>
+                                <p class="text-sm text-gray-600">${job.department} · ${job.location}</p>
+                            </div>
+                            <span class="px-2 py-1 text-xs rounded-full ${getStatusColor(job.status)}">${job.status}</span>
+                        </div>
+                        
+                        <div class="mb-3">
+                            <p class="text-sm text-gray-700 line-clamp-2">${job.talentProfile?.positionDesc || job.description}</p>
+                        </div>
+                        
+                        ${job.talentProfile?.skills ? `
+                        <div class="mb-3">
+                            <div class="flex flex-wrap gap-1 mb-2">
+                                ${job.talentProfile.skills.slice(0, 3).map(skill => `
+                                    <span class="px-2 py-1 text-xs bg-blue-50 text-blue-700 rounded">${skill}</span>
+                                `).join('')}
+                                ${job.talentProfile.skills.length > 3 ? `<span class="px-2 py-1 text-xs bg-gray-50 text-gray-500 rounded">+${job.talentProfile.skills.length - 3}</span>` : ''}
+                            </div>
+                        </div>
+                        ` : ''}
+                        
+                        <div class="mb-4 flex items-center justify-between">
+                            <div>
+                                <div class="text-2xl font-bold text-primary">${job.pendingResumes}</div>
+                                <div class="text-sm text-gray-600">待处理简历</div>
+                            </div>
+                            <div>
+                                <div class="text-2xl font-bold text-success">${job.passedResumes}</div>
+                                <div class="text-sm text-gray-600">已通过初筛</div>
+                            </div>
+                        </div>
+                        
+                        <div class="space-y-2">
+                            ${job.status === '招聘中' ? `
+                            <button onclick="startScreening(${job.id})" 
+                                    class="w-full py-3 px-4 rounded-lg font-medium btn-active transition-colors ${job.pendingResumes > 0 ? 'bg-primary text-white hover:bg-blue-600' : 'bg-gray-100 text-gray-400 cursor-not-allowed'}"
+                                    ${job.pendingResumes === 0 ? 'disabled' : ''}>
+                                ${job.pendingResumes > 0 ? '一键智能筛选' : '暂无待处理简历'}
+                            </button>
+                            ` : `
+                            <button onclick="publishDraft(${job.id})" 
+                                    class="w-full py-3 px-4 rounded-lg font-medium btn-active transition-colors bg-primary text-white hover:bg-blue-600">
+                                发布招聘
+                            </button>
+                            `}
+                            <div class="flex space-x-2">
+                                <button onclick="editJob(${job.id})" class="flex-1 py-2 px-3 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50 btn-active">
+                                    编辑岗位
+                                </button>
+                                ${job.status === '招聘中' ? `
+                                <button onclick="viewJobCandidates(${job.id})" class="flex-1 py-2 px-3 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50 btn-active">
+                                    查看候选人
+                                </button>
+                                ` : `
+                                <button onclick="deleteJob(${job.id})" class="flex-1 py-2 px-3 text-sm text-red-600 border border-red-200 rounded-lg hover:bg-red-50 btn-active">
+                                    删除草稿
+                                </button>
+                                `}
+                            </div>
+                        </div>
+                    </div>
+                `).join('');
+            } catch (error) {
+                console.error('获取岗位列表失败:', error);
+                container.innerHTML = `
+                    <div class="text-center py-10">
+                        <p class="text-red-500">获取岗位数据失败</p>
+                        <button onclick="renderJobManagement()" class="mt-4 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg">
+                            重试
+                        </button>
+                    </div>
+                `;
+            }
+        }
+
+        // 创建新岗位
+        function createNewJob() {
+            editingJobId = null;
+            document.getElementById('create-job-title').textContent = '创建新岗位';
+            clearJobForm();
+            showPage('page-create-job');
+        }
+
+        // 编辑岗位
+        async function editJob(jobId) {
+            editingJobId = jobId;
+            document.getElementById('create-job-title').textContent = '编辑岗位';
+            
+            try {
+                const job = await API.Job.getJobById(jobId);
+                if (job) {
+                    fillJobForm(job);
+                    showPage('page-create-job');
+                } else {
+                    showToast('获取岗位详情失败');
+                }
+            } catch (error) {
+                console.error('获取岗位详情失败:', error);
+                showToast('获取岗位详情失败');
+            }
+        }
+
+        // 清空表单
+        function clearJobForm() {
+            document.getElementById('job-title').value = '';
+            document.getElementById('job-department').value = '';
+            document.getElementById('job-location').value = '';
+            document.getElementById('job-description').value = '';
+            document.getElementById('criteria-container').innerHTML = '';
+            
+            // 清空人才基本面
+            document.getElementById('job-position-desc').value = '';
+            document.getElementById('skills-container').innerHTML = '<input type="text" class="skill-item w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入技能要求...">';
+            document.getElementById('company-culture').value = '';
+            document.getElementById('salary-benefits').value = '';
+            document.getElementById('work-arrangement').value = '';
+            document.getElementById('career-development').value = '';
+            document.getElementById('special-requirements').value = '';
+            document.getElementById('recruitment-process').value = '';
+            
+            // 重置评分准则为默认值
+            // 设置权重
+            document.getElementById('exp-weight').value = '30';
+            document.getElementById('tech-weight').value = '40';
+            document.getElementById('soft-weight').value = '20';
+            document.getElementById('other-weight').value = '10';
+            
+            // 重置通过标准
+            document.getElementById('passing-score').value = '60';
+            
+            // 重置评分标准容器
+            document.getElementById('exp-criteria-container').innerHTML = '';
+            document.getElementById('tech-criteria-container').innerHTML = '';
+            document.getElementById('soft-criteria-container').innerHTML = '';
+            document.getElementById('other-criteria-container').innerHTML = '';
+            
+            // 添加默认项
+            addExpItem();
+            addTechItem();
+            addSoftItem();
+            addOtherItem();
+        }
+
+        // 填充表单
+        function fillJobForm(job) {
+            document.getElementById('job-title').value = job.title;
+            document.getElementById('job-department').value = job.department;
+            document.getElementById('job-location').value = job.location;
+            document.getElementById('job-description').value = job.description;
+            
+            // 填充筛选条件
+            const container = document.getElementById('criteria-container');
+            container.innerHTML = '';
+            job.criteria.forEach(criteria => {
+                addCriteriaRow(criteria);
+            });
+            
+            // 填充人才基本面(如果存在)
+            if (job.talentProfile) {
+                document.getElementById('job-position-desc').value = job.talentProfile.positionDesc || '';
+                
+                // 清空并填充技能要求
+                const skillsContainer = document.getElementById('skills-container');
+                skillsContainer.innerHTML = '';
+                if (job.talentProfile.skills && job.talentProfile.skills.length > 0) {
+                    job.talentProfile.skills.forEach(skill => {
+                        const input = document.createElement('div');
+                        input.className = 'flex items-center';
+                        input.innerHTML = `
+                            <input type="text" class="skill-item flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入技能要求..." value="${skill}">
+                            <button onclick="removeSkillItem(this)" class="ml-2 p-1 text-red-500 hover:text-red-700">
+                                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                </svg>
+                            </button>
+                        `;
+                        skillsContainer.appendChild(input);
+                    });
+                } else {
+                    skillsContainer.innerHTML = '<input type="text" class="skill-item w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入技能要求...">';
+                }
+                
+                document.getElementById('company-culture').value = job.talentProfile.companyCulture || '';
+                document.getElementById('salary-benefits').value = job.talentProfile.salaryBenefits || '';
+                document.getElementById('work-arrangement').value = job.talentProfile.workArrangement || '';
+                document.getElementById('career-development').value = job.talentProfile.careerDevelopment || '';
+                document.getElementById('special-requirements').value = job.talentProfile.specialRequirements || '';
+                document.getElementById('recruitment-process').value = job.talentProfile.recruitmentProcess || '';
+            }
+            
+            // 填充评分准则(如果存在)
+            if (job.scoringCriteria) {
+                // 填充权重设置
+                if (job.scoringCriteria.weights) {
+                    document.getElementById('exp-weight').value = job.scoringCriteria.weights.expWeight || 30;
+                    document.getElementById('tech-weight').value = job.scoringCriteria.weights.techWeight || 40;
+                    document.getElementById('soft-weight').value = job.scoringCriteria.weights.softWeight || 20;
+                    document.getElementById('other-weight').value = job.scoringCriteria.weights.otherWeight || 10;
+                }
+                
+                // 填充工作经验评分项
+                const expContainer = document.getElementById('exp-criteria-container');
+                expContainer.innerHTML = '';
+                if (job.scoringCriteria.expCriteria && job.scoringCriteria.expCriteria.length > 0) {
+                    job.scoringCriteria.expCriteria.forEach(exp => {
+                        const div = document.createElement('div');
+                        div.className = 'exp-item';
+                        div.innerHTML = `
+                            <div class="flex items-center mb-1">
+                                <input type="number" class="exp-years w-12 px-2 py-1 border border-gray-300 rounded text-sm mr-2" value="${exp.years}">
+                                <input type="text" class="exp-desc flex-1 px-2 py-1 border border-gray-300 rounded text-sm" value="${exp.desc}" placeholder="年以上相关工作经验">
+                                <button onclick="removeExpItem(this)" class="ml-2 p-1 text-red-500 hover:text-red-700">
+                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                    </svg>
+                                </button>
+                            </div>
+                            <div class="text-xs text-gray-500 ml-2">(符合:满分30分;不符合:0分)</div>
+                        `;
+                        expContainer.appendChild(div);
+                    });
+                } else {
+                    // 添加默认项
+                    addExpItem();
+                }
+                
+                // 填充技术能力评分项
+                const techContainer = document.getElementById('tech-criteria-container');
+                techContainer.innerHTML = '';
+                if (job.scoringCriteria.techCriteria && job.scoringCriteria.techCriteria.length > 0) {
+                    job.scoringCriteria.techCriteria.forEach((tech, index) => {
+                        const div = document.createElement('div');
+                        div.className = 'tech-item';
+                        div.innerHTML = `
+                            <div class="mb-1">
+                                <input type="text" class="tech-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称" value="${tech.name || ''}">
+                                <input type="text" class="tech-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述" value="${tech.desc || ''}">
+                            </div>
+                            <div class="flex space-x-2 mt-1">
+                                <label class="flex items-center text-xs text-gray-700">
+                                    <input type="radio" name="tech-score-${index+1}" value="${tech.scores?.high || 15}" checked class="mr-1 tech-score-high"> 优秀(
+                                    <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="${tech.scores?.high || 15}">分)
+                                </label>
+                                <label class="flex items-center text-xs text-gray-700">
+                                    <input type="radio" name="tech-score-${index+1}" value="${tech.scores?.medium || 10}" class="mr-1 tech-score-med"> 良好(
+                                    <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="${tech.scores?.medium || 10}">分)
+                                </label>
+                                <label class="flex items-center text-xs text-gray-700">
+                                    <input type="radio" name="tech-score-${index+1}" value="${tech.scores?.low || 5}" class="mr-1 tech-score-low"> 一般(
+                                    <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="${tech.scores?.low || 5}">分)
+                                </label>
+                                <button onclick="removeTechItem(this)" class="text-red-500 hover:text-red-700">
+                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                    </svg>
+                                </button>
+                            </div>
+                        `;
+                        techContainer.appendChild(div);
+                    });
+                } else {
+                    // 保留默认项
+                }
+                
+                // 填充软性技能评分项
+                const softContainer = document.getElementById('soft-criteria-container');
+                softContainer.innerHTML = '';
+                if (job.scoringCriteria.softCriteria && job.scoringCriteria.softCriteria.length > 0) {
+                    job.scoringCriteria.softCriteria.forEach((soft, index) => {
+                        const div = document.createElement('div');
+                        div.className = 'soft-item flex items-center justify-between';
+                        div.innerHTML = `
+                            <div>
+                                <input type="text" class="soft-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称" value="${soft.name || ''}">
+                                <input type="text" class="soft-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述" value="${soft.desc || ''}">
+                            </div>
+                            <div class="flex items-center ml-4">
+                                <label class="flex items-center text-sm text-gray-700 mr-4">
+                                    <input type="radio" name="soft-score-${index+1}" value="${soft.score || 10}" checked class="mr-1 soft-score-yes"> 有(
+                                    <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="${soft.score || 10}">分)
+                                </label>
+                                <label class="flex items-center text-sm text-gray-700">
+                                    <input type="radio" name="soft-score-${index+1}" value="0" class="mr-1 soft-score-no"> 无(0分)
+                                </label>
+                                <button onclick="removeSoftItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                    </svg>
+                                </button>
+                            </div>
+                        `;
+                        softContainer.appendChild(div);
+                    });
+                } else {
+                    // 保留默认项
+                }
+                
+                // 填充其他评分项
+                const otherContainer = document.getElementById('other-criteria-container');
+                otherContainer.innerHTML = '';
+                if (job.scoringCriteria.otherCriteria && job.scoringCriteria.otherCriteria.length > 0) {
+                    job.scoringCriteria.otherCriteria.forEach((other, index) => {
+                        const div = document.createElement('div');
+                        div.className = 'other-item flex items-center justify-between';
+                        div.innerHTML = `
+                            <div>
+                                <input type="text" class="other-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="条件名称" value="${other.name || ''}">
+                                <input type="text" class="other-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="条件描述" value="${other.desc || ''}">
+                            </div>
+                            <div class="flex items-center ml-4">
+                                <label class="flex items-center text-sm text-gray-700 mr-4">
+                                    <input type="radio" name="other-score-${index+1}" value="${other.score || 10}" checked class="mr-1 other-score-yes"> 符合(
+                                    <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="${other.score || 10}">分)
+                                </label>
+                                <label class="flex items-center text-sm text-gray-700">
+                                    <input type="radio" name="other-score-${index+1}" value="0" class="mr-1 other-score-no"> 不符合(0分)
+                                </label>
+                                <button onclick="removeOtherItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                                    </svg>
+                                </button>
+                            </div>
+                        `;
+                        otherContainer.appendChild(div);
+                    });
+                } else {
+                    // 保留默认项
+                }
+                
+                // 设置通过标准
+                document.getElementById('passing-score').value = job.scoringCriteria.passingScore || '60';
+            }
+        }
+
+        // 保存岗位为草稿
+        async function saveJob(shouldPublish = false) {
+            // 验证权重总和是否为100%
+            if (!checkWeightTotals()) {
+                showToast('评分维度权重总和必须为100%');
+                return;
+            }
+            
+            const title = document.getElementById('job-title').value.trim();
+            const department = document.getElementById('job-department').value;
+            const location = document.getElementById('job-location').value;
+            const description = document.getElementById('job-description').value.trim();
+            
+            if (!title || !department || !location) {
+                showToast('请填写完整的基础信息');
+                return;
+            }
+            
+            // 收集筛选条件
+            const criteria = [];
+            const criteriaRows = document.querySelectorAll('.criteria-row');
+            criteriaRows.forEach(row => {
+                const field = row.querySelector('.criteria-field').value;
+                const condition = row.querySelector('.criteria-condition').value;
+                const value = row.querySelector('.criteria-value').value.trim();
+                
+                if (field && condition && value) {
+                    criteria.push({ field, condition, value });
+                }
+            });
+            
+            // 收集权重设置
+            const scoringWeights = {
+                expWeight: document.getElementById('exp-weight').value,
+                techWeight: document.getElementById('tech-weight').value,
+                softWeight: document.getElementById('soft-weight').value,
+                otherWeight: document.getElementById('other-weight').value
+            };
+            
+            // 收集工作经验评分项
+            const expCriteria = [];
+            document.querySelectorAll('.exp-item').forEach(item => {
+                const years = item.querySelector('.exp-years').value;
+                const desc = item.querySelector('.exp-desc').value;
+                if (years && desc) {
+                    expCriteria.push({ years, desc });
+                }
+            });
+            
+            // 收集技术能力评分项
+            const techCriteria = [];
+            document.querySelectorAll('.tech-item').forEach((item, index) => {
+                const name = item.querySelector('.tech-name').value;
+                const desc = item.querySelector('.tech-desc').value;
+                const highScore = item.querySelector('.tech-score-high').parentNode.querySelector('input[type="number"]').value;
+                const medScore = item.querySelector('.tech-score-med').parentNode.querySelector('input[type="number"]').value;
+                const lowScore = item.querySelector('.tech-score-low').parentNode.querySelector('input[type="number"]').value;
+                
+                if (name) {
+                    techCriteria.push({ 
+                        name, 
+                        desc, 
+                        scores: {
+                            high: highScore,
+                            medium: medScore,
+                            low: lowScore
+                        }
+                    });
+                }
+            });
+            
+            // 收集软性技能评分项
+            const softCriteria = [];
+            document.querySelectorAll('.soft-item').forEach((item, index) => {
+                const name = item.querySelector('.soft-name').value;
+                const desc = item.querySelector('.soft-desc').value;
+                const score = item.querySelector('.soft-score-yes').parentNode.querySelector('input[type="number"]').value;
+                
+                if (name) {
+                    softCriteria.push({ name, desc, score });
+                }
+            });
+            
+            // 收集其他评分项
+            const otherCriteria = [];
+            document.querySelectorAll('.other-item').forEach((item, index) => {
+                const name = item.querySelector('.other-name').value;
+                const desc = item.querySelector('.other-desc').value;
+                const score = item.querySelector('.other-score-yes').parentNode.querySelector('input[type="number"]').value;
+                
+                if (name) {
+                    otherCriteria.push({ name, desc, score });
+                }
+            });
+            
+            // 收集人才基本面信息
+            const skillItems = document.querySelectorAll('.skill-item');
+            const skills = [];
+            skillItems.forEach(item => {
+                if (item.value.trim()) {
+                    skills.push(item.value.trim());
+                }
+            });
+            
+            const talentProfile = {
+                positionDesc: document.getElementById('job-position-desc').value.trim(),
+                skills: skills,
+                companyCulture: document.getElementById('company-culture').value.trim(),
+                salaryBenefits: document.getElementById('salary-benefits').value.trim(),
+                workArrangement: document.getElementById('work-arrangement').value.trim(),
+                careerDevelopment: document.getElementById('career-development').value.trim(),
+                specialRequirements: document.getElementById('special-requirements').value.trim(),
+                recruitmentProcess: document.getElementById('recruitment-process').value.trim()
+            };
+            
+            // 收集评分准则
+            const scoringCriteria = {
+                weights: scoringWeights,
+                expCriteria,
+                techCriteria,
+                softCriteria,
+                otherCriteria,
+                passingScore: document.getElementById('passing-score').value
+            };
+            
+            const jobData = {
+                title,
+                department,
+                location,
+                description,
+                criteria,
+                talentProfile,
+                scoringCriteria,
+                status: shouldPublish ? '招聘中' : '草稿'
+            };
+            
+            try {
+                let response;
+                
+                if (editingJobId) {
+                    // 编辑现有岗位
+                    response = await API.Job.updateJob(editingJobId, jobData);
+                } else {
+                    // 创建新岗位
+                    response = await API.Job.createJob(jobData);
+                }
+                
+                showToast(response.message || (shouldPublish ? '岗位已成功发布' : '岗位已保存为草稿'));
+                renderJobManagement();
+                updateStatistics();
+                goBack();
+            } catch (error) {
+                console.error('保存岗位失败:', error);
+                showToast(shouldPublish ? '发布岗位失败,请重试' : '保存岗位失败,请重试');
+            }
+        }
+
+        // 发布岗位
+        function publishJob() {
+            saveJob(true);
+        }
+
+        // 添加筛选条件
+        function addCriteria() {
+            addCriteriaRow();
+        }
+
+        // 添加筛选条件行
+        function addCriteriaRow(criteria = null) {
+            const container = document.getElementById('criteria-container');
+            const row = document.createElement('div');
+            row.className = 'criteria-row flex items-center space-x-2 p-3 bg-gray-50 rounded-lg';
+            
+            row.innerHTML = `
+                <select class="criteria-field flex-1 px-2 py-1 border border-gray-300 rounded text-sm">
+                    <option value="">选择指标</option>
+                    <option value="学历" ${criteria?.field === '学历' ? 'selected' : ''}>学历</option>
+                    <option value="工作年限" ${criteria?.field === '工作年限' ? 'selected' : ''}>工作年限</option>
+                    <option value="必要技能" ${criteria?.field === '必要技能' ? 'selected' : ''}>必要技能</option>
+                    <option value="语言要求" ${criteria?.field === '语言要求' ? 'selected' : ''}>语言要求</option>
+                </select>
+                <select class="criteria-condition flex-1 px-2 py-1 border border-gray-300 rounded text-sm">
+                    <option value="">选择条件</option>
+                    <option value="等于" ${criteria?.condition === '等于' ? 'selected' : ''}>等于</option>
+                    <option value="大于等于" ${criteria?.condition === '大于等于' ? 'selected' : ''}>大于等于</option>
+                    <option value="包含" ${criteria?.condition === '包含' ? 'selected' : ''}>包含</option>
+                    <option value="不包含" ${criteria?.condition === '不包含' ? 'selected' : ''}>不包含</option>
+                </select>
+                <input type="text" class="criteria-value flex-1 px-2 py-1 border border-gray-300 rounded text-sm" 
+                       placeholder="输入值" value="${criteria?.value || ''}">
+                <button onclick="removeCriteria(this)" class="p-1 text-red-500 hover:text-red-700">
+                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                    </svg>
+                </button>
+            `;
+            
+            container.appendChild(row);
+        }
+
+        // 删除筛选条件
+        function removeCriteria(button) {
+            button.closest('.criteria-row').remove();
+        }
+
+        // 添加技能要求项
+        function addSkillItem() {
+            const container = document.getElementById('skills-container');
+            const input = document.createElement('div');
+            input.className = 'flex items-center';
+            input.innerHTML = `
+                <input type="text" class="skill-item flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入技能要求...">
+                <button onclick="removeSkillItem(this)" class="ml-2 p-1 text-red-500 hover:text-red-700">
+                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                    </svg>
+                </button>
+            `;
+            container.appendChild(input);
+        }
+
+        // 删除技能要求项
+        function removeSkillItem(button) {
+            button.closest('.flex').remove();
+        }
+
+        // 开始筛选
+        async function startScreening(jobId) {
+            const button = event.target;
+            const originalText = button.textContent;
+            
+            // 显示加载状态
+            button.innerHTML = '<div class="loading-spinner inline-block mr-2"></div>筛选中...';
+            button.disabled = true;
+            
+            try {
+                const response = await API.Job.startScreening(jobId);
+                
+                showToast(response.message || '筛选完成!');
+                renderJobManagement();
+                updateStatistics();
+            } catch (error) {
+                console.error('启动筛选失败:', error);
+                showToast('启动筛选失败,请重试');
+                // 恢复按钮状态
+                button.textContent = originalText;
+                button.disabled = false;
+            }
+        }
+
+        // 查看岗位候选人
+        async function viewJobCandidates(jobId) {
+            currentJobId = jobId;
+            document.getElementById('candidate-list-title').textContent = '加载中...';
+            showPage('page-candidate-list');
+            
+            try {
+                const response = await API.Job.getJobCandidates(jobId);
+                document.getElementById('candidate-list-title').textContent = response.jobTitle;
+                renderCandidateList(response.candidates);
+            } catch (error) {
+                console.error('获取候选人列表失败:', error);
+                document.getElementById('candidate-list-container').innerHTML = `
+                    <div class="text-center py-10">
+                        <p class="text-red-500">获取候选人数据失败</p>
+                        <button onclick="viewJobCandidates(${jobId})" class="mt-4 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg">
+                            重试
+                        </button>
+                    </div>
+                `;
+            }
+        }
+
+        // 渲染所有候选人
+        async function renderAllCandidates() {
+            document.getElementById('candidate-list-title').textContent = '加载中...';
+            showPage('page-candidate-list');
+            
+            try {
+                const candidates = await API.Candidate.getAllCandidates();
+                document.getElementById('candidate-list-title').textContent = '全部候选人';
+                renderCandidateList(candidates, true);
+            } catch (error) {
+                console.error('获取候选人列表失败:', error);
+                document.getElementById('candidate-list-container').innerHTML = `
+                    <div class="text-center py-10">
+                        <p class="text-red-500">获取候选人数据失败</p>
+                        <button onclick="renderAllCandidates()" class="mt-4 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg">
+                            重试
+                        </button>
+                    </div>
+                `;
+            }
+        }
+
+        // 渲染候选人列表
+        function renderCandidateList(candidates, showJobTitle = false) {
+            const container = document.getElementById('candidate-list-container');
+            if (candidates.length === 0) {
+                container.innerHTML = `
+                    <div class="text-center py-12">
+                        <svg class="w-16 h-16 text-gray-300 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
+                        </svg>
+                        <p class="text-gray-500">暂无候选人</p>
+                    </div>
+                `;
+                return;
+            }
+            
+            container.innerHTML = candidates.map(candidate => `
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4 card-hover cursor-pointer" onclick="viewResumeDetail(${candidate.id})">
+                    <div class="flex items-start justify-between mb-3">
+                        <div>
+                            <h3 class="font-semibold text-gray-900">${candidate.name}</h3>
+                            ${showJobTitle ? `<p class="text-sm text-gray-600">${candidate.jobTitle}</p>` : ''}
+                            <div class="flex items-center mt-1">
+                                <span class="text-2xl font-bold text-primary mr-2">${candidate.score}</span>
+                                <span class="text-sm text-gray-600">匹配度</span>
+                            </div>
+                        </div>
+                        <div class="w-3 h-3 rounded-full ${getStatusDot(candidate.status)}"></div>
+                    </div>
+                    
+                    <div class="flex flex-wrap gap-2 mb-3">
+                        ${candidate.tags.map(tag => `
+                            <span class="px-2 py-1 text-xs bg-blue-50 text-blue-700 rounded">${tag}</span>
+                        `).join('')}
+                    </div>
+                    
+                    <div class="flex items-center justify-end">
+                        <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
+                        </svg>
+                    </div>
+                </div>
+            `).join('');
+        }
+
+        // 查看简历详情
+        async function viewResumeDetail(candidateId) {
+            currentCandidateId = candidateId;
+            document.getElementById('resume-detail-title').textContent = '加载中...';
+            showPage('page-resume-detail');
+            
+            try {
+                const detail = await API.Candidate.getCandidateDetails(candidateId);
+                if (detail) {
+                    document.getElementById('resume-detail-title').textContent = detail.name;
+                    renderResumeDetail(detail);
+                } else {
+                    document.getElementById('ai-analysis-details').innerHTML = `
+                        <div class="text-center py-10">
+                            <p class="text-red-500">未找到候选人数据</p>
+                            <button onclick="goBack()" class="mt-4 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg">
+                                返回
+                            </button>
+                        </div>
+                    `;
+                }
+            } catch (error) {
+                console.error('获取候选人详情失败:', error);
+                document.getElementById('ai-analysis-details').innerHTML = `
+                    <div class="text-center py-10">
+                        <p class="text-red-500">获取候选人详情失败</p>
+                        <button onclick="viewResumeDetail(${candidateId})" class="mt-4 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg">
+                            重试
+                        </button>
+                    </div>
+                `;
+            }
+        }
+
+        // 渲染简历详情
+        function renderResumeDetail(detail) {
+            // 更新匹配度圆环
+            updateProgressRing(detail.score);
+            
+            // 渲染AI分析详情
+            const analysisContainer = document.getElementById('ai-analysis-details');
+            analysisContainer.innerHTML = `
+                <!-- 综合评语 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-2 flex items-center">
+                        <svg class="w-5 h-5 text-blue-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"></path>
+                        </svg>
+                        综合评语
+                    </h3>
+                    <p class="text-gray-700 text-sm leading-relaxed">${detail.summary}</p>
+                </div>
+                
+                <!-- 亮点 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-3 flex items-center">
+                        <svg class="w-5 h-5 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
+                        </svg>
+                        优势亮点
+                    </h3>
+                    <ul class="space-y-2">
+                        ${detail.pros.map(pro => `
+                            <li class="flex items-start text-sm text-gray-700">
+                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
+                                </svg>
+                                ${pro}
+                            </li>
+                        `).join('')}
+                    </ul>
+                </div>
+                
+                <!-- 待考察点 -->
+                <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
+                    <h3 class="font-semibold text-gray-900 mb-3 flex items-center">
+                        <svg class="w-5 h-5 text-orange-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
+                        </svg>
+                        待考察点
+                    </h3>
+                    <ul class="space-y-2">
+                        ${detail.cons.map(con => `
+                            <li class="flex items-start text-sm text-gray-700">
+                                <svg class="w-4 h-4 text-orange-500 mr-2 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
+                                </svg>
+                                ${con}
+                            </li>
+                        `).join('')}
+                    </ul>
+                </div>
+            `;
+            
+            // 更新简历原文
+            document.getElementById('resume-text').innerHTML = detail.resumeText.replace(/\n/g, '<br>');
+        }
+
+        // 更新进度环
+        function updateProgressRing(score) {
+            const circle = document.getElementById('progress-circle');
+            const scoreDisplay = document.getElementById('score-display');
+            const circumference = 2 * Math.PI * 45;
+            const offset = circumference - (score / 100) * circumference;
+            
+            circle.style.strokeDashoffset = offset;
+            scoreDisplay.textContent = score;
+        }
+
+        // Tab切换
+        function switchTab(tabName) {
+            // 更新tab按钮状态
+            document.querySelectorAll('[id^="tab-"]').forEach(tab => {
+                tab.classList.remove('text-primary', 'border-primary');
+                tab.classList.add('text-gray-500', 'border-transparent');
+            });
+            
+            document.getElementById(`tab-${tabName}`).classList.remove('text-gray-500', 'border-transparent');
+            document.getElementById(`tab-${tabName}`).classList.add('text-primary', 'border-primary');
+            
+            // 切换内容
+            document.querySelectorAll('.tab-content').forEach(content => {
+                content.classList.add('hidden');
+            });
+            
+            document.getElementById(`content-${tabName}`).classList.remove('hidden');
+        }
+
+        // 处理拒绝
+        function handleReject() {
+            if (currentCandidateId) {
+                updateCandidateStatus(currentCandidateId, 'rejected');
+                showToast('已标记为不合适');
+                setTimeout(() => goBack(), 1000);
+            }
+        }
+
+        // 处理通过
+        function handleApprove() {
+            if (currentCandidateId) {
+                updateCandidateStatus(currentCandidateId, 'approved');
+                showToast('已通过初筛');
+                setTimeout(() => goBack(), 1000);
+            }
+        }
+
+        // 更新候选人状态
+        function updateCandidateStatus(candidateId, status) {
+            mockData.jobs.forEach(job => {
+                const candidate = job.candidates.find(c => c.id === candidateId);
+                if (candidate) {
+                    candidate.status = status;
+                    if (status === 'approved') {
+                        job.passedResumes++;
+                    }
+                }
+            });
+            updateStatistics();
+        }
+
+        // 更新统计数据
+        async function updateStatistics() {
+            try {
+                // 获取总览数据
+                const overviewStats = await API.Statistics.getOverviewStats();
+                document.getElementById('total-jobs').textContent = overviewStats.totalJobs;
+                document.getElementById('total-candidates').textContent = overviewStats.totalCandidates;
+                document.getElementById('pending-resumes').textContent = overviewStats.pendingResumes;
+                document.getElementById('passed-resumes').textContent = overviewStats.passedResumes;
+                
+                // 获取部门统计
+                const departmentStats = await API.Statistics.getDepartmentStats();
+                const departmentContainer = document.getElementById('department-stats');
+                
+                if (departmentStats.length === 0) {
+                    departmentContainer.innerHTML = `
+                        <div class="text-center py-4">
+                            <p class="text-gray-500">暂无部门数据</p>
+                        </div>
+                    `;
+                    return;
+                }
+                
+                departmentContainer.innerHTML = departmentStats.map(dept => `
+                    <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
+                        <div>
+                            <div class="font-medium text-gray-900">${dept.department || '未分类'}</div>
+                            <div class="text-sm text-gray-600">${dept.jobs}个岗位 · ${dept.candidates}名候选人</div>
+                        </div>
+                        <div class="text-right">
+                            <div class="text-sm text-warning">${dept.pending}待处理</div>
+                            <div class="text-sm text-success">${dept.passed}已通过</div>
+                        </div>
+                    </div>
+                `).join('');
+            } catch (error) {
+                console.error('获取统计数据失败:', error);
+            }
+        }
+
+        // 获取状态颜色
+        function getStatusColor(status) {
+            switch(status) {
+                case '招聘中': return 'bg-green-100 text-green-800';
+                case '已暂停': return 'bg-gray-100 text-gray-800';
+                case '草稿': return 'bg-blue-100 text-blue-800';
+                default: return 'bg-gray-100 text-gray-800';
+            }
+        }
+
+        // 获取状态指示点颜色
+        function getStatusDot(status) {
+            switch(status) {
+                case 'pending': return 'bg-yellow-400';
+                case 'approved': return 'bg-green-400';
+                case 'rejected': return 'bg-red-400';
+                default: return 'bg-gray-400';
+            }
+        }
+
+        // 显示Toast消息
+        function showToast(message) {
+            const toast = document.createElement('div');
+            toast.className = 'toast';
+            toast.textContent = message;
+            document.body.appendChild(toast);
+            
+            setTimeout(() => {
+                toast.remove();
+            }, 3000);
+        }
+
+        // 检查维度权重总和是否为100%
+        function checkWeightTotals() {
+            const expWeight = parseInt(document.getElementById('exp-weight').value) || 0;
+            const techWeight = parseInt(document.getElementById('tech-weight').value) || 0;
+            const softWeight = parseInt(document.getElementById('soft-weight').value) || 0;
+            const otherWeight = parseInt(document.getElementById('other-weight').value) || 0;
+            
+            const total = expWeight + techWeight + softWeight + otherWeight;
+            const errorElement = document.getElementById('weight-error');
+            
+            if (total !== 100) {
+                errorElement.classList.remove('hidden');
+                return false;
+            } else {
+                errorElement.classList.add('hidden');
+                return true;
+            }
+        }
+
+        // 监听权重变化
+        document.addEventListener('DOMContentLoaded', function() {
+            const weightInputs = ['exp-weight', 'tech-weight', 'soft-weight', 'other-weight'];
+            weightInputs.forEach(id => {
+                const input = document.getElementById(id);
+                if (input) {
+                    input.addEventListener('change', checkWeightTotals);
+                }
+            });
+        });
+
+        // 添加工作经验条件
+        function addExpItem() {
+            const container = document.getElementById('exp-criteria-container');
+            const index = container.children.length + 1;
+            const div = document.createElement('div');
+            div.className = 'exp-item';
+            div.innerHTML = `
+                <div class="flex items-center mb-1">
+                    <input type="number" class="exp-years w-12 px-2 py-1 border border-gray-300 rounded text-sm mr-2" value="1">
+                    <input type="text" class="exp-desc flex-1 px-2 py-1 border border-gray-300 rounded text-sm" value="" placeholder="年以上相关工作经验">
+                    <button onclick="removeExpItem(this)" class="ml-2 p-1 text-red-500 hover:text-red-700">
+                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                        </svg>
+                    </button>
+                </div>
+                <div class="text-xs text-gray-500 ml-2">(符合:满分30分;不符合:0分)</div>
+            `;
+            container.appendChild(div);
+        }
+
+        // 删除工作经验条件
+        function removeExpItem(button) {
+            button.closest('.exp-item').remove();
+        }
+
+        // 添加技术能力项
+        function addTechItem() {
+            const container = document.getElementById('tech-criteria-container');
+            const index = container.children.length + 1;
+            const div = document.createElement('div');
+            div.className = 'tech-item';
+            div.innerHTML = `
+                <div class="mb-1">
+                    <input type="text" class="tech-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称">
+                    <input type="text" class="tech-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述">
+                </div>
+                <div class="flex space-x-2 mt-1">
+                    <label class="flex items-center text-xs text-gray-700">
+                        <input type="radio" name="tech-score-${index}" value="15" checked class="mr-1 tech-score-high"> 优秀(
+                        <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="15">分)
+                    </label>
+                    <label class="flex items-center text-xs text-gray-700">
+                        <input type="radio" name="tech-score-${index}" value="10" class="mr-1 tech-score-med"> 良好(
+                        <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                    </label>
+                    <label class="flex items-center text-xs text-gray-700">
+                        <input type="radio" name="tech-score-${index}" value="5" class="mr-1 tech-score-low"> 一般(
+                        <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="5">分)
+                    </label>
+                    <button onclick="removeTechItem(this)" class="text-red-500 hover:text-red-700">
+                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                        </svg>
+                    </button>
+                </div>
+            `;
+            container.appendChild(div);
+        }
+
+        // 删除技术能力项
+        function removeTechItem(button) {
+            button.closest('.tech-item').remove();
+        }
+
+        // 添加软性技能项
+        function addSoftItem() {
+            const container = document.getElementById('soft-criteria-container');
+            const index = container.children.length + 1;
+            const div = document.createElement('div');
+            div.className = 'soft-item flex items-center justify-between';
+            div.innerHTML = `
+                <div>
+                    <input type="text" class="soft-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="技能名称">
+                    <input type="text" class="soft-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="技能描述">
+                </div>
+                <div class="flex items-center ml-4">
+                    <label class="flex items-center text-sm text-gray-700 mr-4">
+                        <input type="radio" name="soft-score-${index}" value="10" checked class="mr-1 soft-score-yes"> 有(
+                        <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                    </label>
+                    <label class="flex items-center text-sm text-gray-700">
+                        <input type="radio" name="soft-score-${index}" value="0" class="mr-1 soft-score-no"> 无(0分)
+                    </label>
+                    <button onclick="removeSoftItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                        </svg>
+                    </button>
+                </div>
+            `;
+            container.appendChild(div);
+        }
+
+        // 删除软性技能项
+        function removeSoftItem(button) {
+            button.closest('.soft-item').remove();
+        }
+
+        // 添加其他评分条件
+        function addOtherItem() {
+            const container = document.getElementById('other-criteria-container');
+            const index = container.children.length + 1;
+            const div = document.createElement('div');
+            div.className = 'other-item flex items-center justify-between';
+            div.innerHTML = `
+                <div>
+                    <input type="text" class="other-name w-full px-2 py-1 border border-gray-300 rounded text-sm mb-1" placeholder="条件名称">
+                    <input type="text" class="other-desc w-full px-2 py-1 border border-gray-300 rounded text-sm" placeholder="条件描述">
+                </div>
+                <div class="flex items-center ml-4">
+                    <label class="flex items-center text-sm text-gray-700 mr-4">
+                        <input type="radio" name="other-score-${index}" value="10" checked class="mr-1 other-score-yes"> 符合(
+                        <input type="number" class="w-8 px-1 border border-gray-300 rounded text-xs mx-1" value="10">分)
+                    </label>
+                    <label class="flex items-center text-sm text-gray-700">
+                        <input type="radio" name="other-score-${index}" value="0" class="mr-1 other-score-no"> 不符合(0分)
+                    </label>
+                    <button onclick="removeOtherItem(this)" class="ml-2 text-red-500 hover:text-red-700">
+                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H8a1 1 0 00-1 1v3M4 7h16"></path>
+                        </svg>
+                    </button>
+                </div>
+            `;
+            container.appendChild(div);
+        }
+
+        // 删除其他评分条件
+        function removeOtherItem(button) {
+            button.closest('.other-item').remove();
+        }
+
+        // 发布草稿
+        async function publishDraft(jobId) {
+            try {
+                const response = await API.Job.publishDraft(jobId);
+                showToast(response.message || '岗位已成功发布');
+                renderJobManagement();
+                updateStatistics();
+            } catch (error) {
+                console.error('发布岗位失败:', error);
+                showToast('发布岗位失败,请重试');
+            }
+        }
+
+        // 删除岗位草稿
+        async function deleteJob(jobId) {
+            try {
+                const response = await API.Job.deleteJob(jobId);
+                showToast(response.message || '岗位草稿已删除');
+                renderJobManagement();
+                updateStatistics();
+            } catch (error) {
+                console.error('删除岗位失败:', error);
+                showToast('删除岗位失败,请重试');
+            }
+        }
+    </script>
+</body>
+</html>

+ 1 - 0
javascript.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#F7DF1E" d="M0 0h256v256H0V0Z"></path><path d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574"></path></svg>

+ 24 - 0
main.js

@@ -0,0 +1,24 @@
+import './style.css'
+import javascriptLogo from './javascript.svg'
+import viteLogo from '/vite.svg'
+import { setupCounter } from './counter.js'
+
+document.querySelector('#app').innerHTML = `
+  <div>
+    <a href="https://vitejs.dev" target="_blank">
+      <img src="${viteLogo}" class="logo" alt="Vite logo" />
+    </a>
+    <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" target="_blank">
+      <img src="${javascriptLogo}" class="logo vanilla" alt="JavaScript logo" />
+    </a>
+    <h1>Hello Vite!</h1>
+    <div class="card">
+      <button id="counter" type="button"></button>
+    </div>
+    <p class="read-the-docs">
+      Click on the Vite logo to learn more
+    </p>
+  </div>
+`
+
+setupCounter(document.querySelector('#counter'))

+ 909 - 0
package-lock.json

@@ -0,0 +1,909 @@
+{
+  "name": "vite-starter",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "vite-starter",
+      "version": "0.0.0",
+      "devDependencies": {
+        "vite": "^5.4.2"
+      }
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz",
+      "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz",
+      "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz",
+      "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz",
+      "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz",
+      "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz",
+      "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz",
+      "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz",
+      "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz",
+      "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz",
+      "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz",
+      "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz",
+      "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz",
+      "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-musl": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz",
+      "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz",
+      "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz",
+      "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz",
+      "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz",
+      "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz",
+      "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz",
+      "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+      "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/esbuild": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.21.5",
+        "@esbuild/android-arm": "0.21.5",
+        "@esbuild/android-arm64": "0.21.5",
+        "@esbuild/android-x64": "0.21.5",
+        "@esbuild/darwin-arm64": "0.21.5",
+        "@esbuild/darwin-x64": "0.21.5",
+        "@esbuild/freebsd-arm64": "0.21.5",
+        "@esbuild/freebsd-x64": "0.21.5",
+        "@esbuild/linux-arm": "0.21.5",
+        "@esbuild/linux-arm64": "0.21.5",
+        "@esbuild/linux-ia32": "0.21.5",
+        "@esbuild/linux-loong64": "0.21.5",
+        "@esbuild/linux-mips64el": "0.21.5",
+        "@esbuild/linux-ppc64": "0.21.5",
+        "@esbuild/linux-riscv64": "0.21.5",
+        "@esbuild/linux-s390x": "0.21.5",
+        "@esbuild/linux-x64": "0.21.5",
+        "@esbuild/netbsd-x64": "0.21.5",
+        "@esbuild/openbsd-x64": "0.21.5",
+        "@esbuild/sunos-x64": "0.21.5",
+        "@esbuild/win32-arm64": "0.21.5",
+        "@esbuild/win32-ia32": "0.21.5",
+        "@esbuild/win32-x64": "0.21.5"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.11",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/postcss": {
+      "version": "8.5.6",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+      "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.11",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "4.44.1",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz",
+      "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.8"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.44.1",
+        "@rollup/rollup-android-arm64": "4.44.1",
+        "@rollup/rollup-darwin-arm64": "4.44.1",
+        "@rollup/rollup-darwin-x64": "4.44.1",
+        "@rollup/rollup-freebsd-arm64": "4.44.1",
+        "@rollup/rollup-freebsd-x64": "4.44.1",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.44.1",
+        "@rollup/rollup-linux-arm-musleabihf": "4.44.1",
+        "@rollup/rollup-linux-arm64-gnu": "4.44.1",
+        "@rollup/rollup-linux-arm64-musl": "4.44.1",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.44.1",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1",
+        "@rollup/rollup-linux-riscv64-gnu": "4.44.1",
+        "@rollup/rollup-linux-riscv64-musl": "4.44.1",
+        "@rollup/rollup-linux-s390x-gnu": "4.44.1",
+        "@rollup/rollup-linux-x64-gnu": "4.44.1",
+        "@rollup/rollup-linux-x64-musl": "4.44.1",
+        "@rollup/rollup-win32-arm64-msvc": "4.44.1",
+        "@rollup/rollup-win32-ia32-msvc": "4.44.1",
+        "@rollup/rollup-win32-x64-msvc": "4.44.1",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "5.4.19",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
+      "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.21.3",
+        "postcss": "^8.4.43",
+        "rollup": "^4.20.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || >=20.0.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "sass-embedded": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    }
+  }
+}

+ 14 - 0
package.json

@@ -0,0 +1,14 @@
+{
+  "name": "vite-starter",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "devDependencies": {
+    "vite": "^5.4.2"
+  }
+}

+ 1 - 0
public/vite.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

+ 96 - 0
style.css

@@ -0,0 +1,96 @@
+:root {
+  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  font-weight: 400;
+
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  display: flex;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+#app {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+}
+
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
+}
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vanilla:hover {
+  filter: drop-shadow(0 0 2em #f7df1eaa);
+}
+
+.card {
+  padding: 2em;
+}
+
+.read-the-docs {
+  color: #888;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}