diff --git a/index.html b/index.html index 0b50396..ec60d81 100644 --- a/index.html +++ b/index.html @@ -1,72 +1,451 @@ - + - 个人网站 + 熠辉 — 全栈工程师 + + + -
- -
-

之岸渐

-
-

「以金融脉动丈量经济浪潮,借玄学视角洞见生命熵减,用双碳实践编织可持续未来。」

-

—— 在理性与灵性间平衡商业与生态的摆渡人

+
+ +
+ - - - -
-
-
-
-

你好!我是之岸渐的AI助手,有什么我可以帮你的吗?

+
+
+

+ 02 + 工作经历 +

+
+
+
+
+
+
+

高级全栈工程师

+

星辰科技有限公司

+
+ 2022 — 至今 +
+
    +
  • 主导微服务架构迁移,将单体应用拆分为 12 个独立服务,系统可用性提升至 99.99%
  • +
  • 设计并实现高并发实时数据处理管线,日处理数据量达 5000 万条
  • +
  • 构建内部组件库和开发工具链,团队开发效率提升 40%
  • +
  • 指导 5 名初级工程师的技术成长,建立代码评审和技术分享机制
  • +
+
+ ReactGoKubernetesPostgreSQLKafka +
-
- - +
+
+
+
+
+

全栈开发工程师

+

云帆网络科技

+
+ 2020 — 2022 +
+
    +
  • 负责 SaaS 平台核心模块开发,服务超过 200 家企业客户
  • +
  • 实现前端性能优化,首屏加载时间从 4.2s 降至 1.1s
  • +
  • 设计 RESTful API 和 GraphQL 接口,支撑多端统一数据访问
  • +
  • 搭建自动化测试体系,代码覆盖率从 35% 提升至 85%
  • +
+
+ Vue 3Node.jsMongoDBDockerGraphQL +
+
+
+
+
+
+
+
+

前端开发工程师

+

灵犀数字科技

+
+ 2019 — 2020 +
+
    +
  • 参与电商平台前端架构设计,支撑日均百万 PV 的流量
  • +
  • 开发可视化数据大屏系统,为管理层提供实时业务洞察
  • +
  • 封装 20+ 高复用业务组件,推动团队组件化开发规范
  • +
+
+ ReactTypeScriptD3.jsWebpack +
+
-
+
+
+ +
+
+

+ 03 + 开源项目 +

+
+
+
+ + + + +
+

FlowEngine

+

高性能工作流引擎,支持可视化流程编排、条件分支和并行执行。基于事件驱动架构,已在多个生产环境中稳定运行。

+
+ TypeScriptReactGoRedis +
+
+ ⭐ 420 + 🍴 68 +
+
+
+
+ + + + +
+

DataPulse

+

实时数据监控与告警平台,提供自定义仪表盘、智能异常检测和多渠道通知。支持百万级数据点的秒级渲染。

+
+ Vue 3PythonClickHouseWebSocket +
+
+ ⭐ 316 + 🍴 45 +
+
+
+
+ + + + +
+

PixelForge

+

基于 WebGL 的在线图像处理工具,支持滤镜、图层、矢量绘制等功能。利用 WebWorker 实现非阻塞的图像计算。

+
+ TypeScriptWebGLRust(WASM) +
+
+ ⭐ 280 + 🍴 39 +
+
+
+
+
+ +
+
+

+ 04 + 教育背景 +

+
+
+
🎓
+
+

计算机科学与技术 · 硕士

+

浙江大学

+

2017 — 2019

+

研究方向:分布式系统与云计算

+
+
+
+
📚
+
+

软件工程 · 学士

+

华中科技大学

+

2013 — 2017

+

GPA: 3.8/4.0,优秀毕业生

+
+
+
+
+
+ +
+
+

+ 05 + 联系我 +

+

无论是合作机会、技术交流还是开源项目讨论,欢迎随时联系我。

+ +
+
+ + - - + - - - - \ No newline at end of file + diff --git a/script.js b/script.js index c2c5225..a3478a7 100644 --- a/script.js +++ b/script.js @@ -1,167 +1,133 @@ document.addEventListener('DOMContentLoaded', () => { - // 轮播相关代码 - const galleryImg = document.querySelector('.gallery-item img'); - let currentImageIndex = 0; - const images = [ - 'imgs/4K黄昏.png', - 'imgs/a lonely winte.png', - 'imgs/Artic Sunset.png' - ]; - - // 图片加载错误处理 - galleryImg.onerror = function() { - console.error('图片加载失败:', this.src); - this.src = 'https://picsum.photos/1200/675'; - }; - // 切换图片函数 - function changeImage() { - galleryImg.style.opacity = '0'; - setTimeout(() => { - galleryImg.src = images[currentImageIndex]; - galleryImg.style.opacity = '1'; - currentImageIndex = (currentImageIndex + 1) % images.length; - }, 500); - } + // Mobile nav toggle + const navToggle = document.querySelector('.nav-toggle'); + const navLinks = document.querySelector('.nav-links'); - // 设置自动轮播间隔(5秒) - setInterval(changeImage, 5000); - - // 初始加载第一张图片 - galleryImg.src = images[0]; - - // AI聊天相关代码 - const chatMessages = document.querySelector('.chat-messages'); - const userInput = document.getElementById('userInput'); - const sendButton = document.querySelector('.send-btn'); - - const MOONSHOT_API_KEY = 'sk-SsnAJdkcdjfnDI40o4YfKfsY1jvNorGCmJTTM1Xx971j4wHd'; // 临时保留,但需要注意安全性 - const API_URL = 'https://api.moonshot.cn/v1/chat/completions'; - - async function getAIResponse(userMessage) { - try { - const response = await fetch(API_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${MOONSHOT_API_KEY}` - }, - body: JSON.stringify({ - model: "moonshot-v1-8k", - messages: [ - { - role: "system", - content: `你是之岸渐的AI助手,主人是一位独特的跨界人才:金融从业者、玄学爱好者和双碳领域的探索者。请遵循以下规则: - - 1. 专业领域介绍: - - 金融领域:擅长分析经济趋势和市场脉动 - - 玄学研究:对生命哲学和东方玄学有独特见解 - - 双碳探索:致力于可持续发展和环境保护实践 - - 2. 回答特点: - - 在金融话题上展现专业洞见 - - 在玄学讨论中体现深度思考 - - 在环保议题上分享实践经验 - - 善于将这三个领域进行跨界连接 - - 3. 回答风格: - - 用友好且专业的语气 - - 回答简洁,通常不超过三句话 - - 适当使用表情符号增加亲和力 - - 在专业术语后适时添加通俗解释 - - 4. 互动指南: - - 鼓励访客探索作品集中的创作 - - 对不确定的问题建议直接咨询之岸渐 - - 在合适时机推荐相关领域的探讨 - - 对负面言论保持礼貌但坚定的回应 - - 5. 核心价值观: - - 强调理性思维与玄学智慧的结合 - - 突出金融与环保的可持续发展理念 - - 展现对生命和自然的敬畏之心 - - 传递积极向上的人生态度` - }, - { - role: "user", - content: userMessage - } - ], - temperature: 0.7, - max_tokens: 800, - stream: false - }) - }); + if (navToggle) { + navToggle.addEventListener('click', () => { + navLinks.classList.toggle('active'); + }); - const data = await response.json(); - return data.choices[0].message.content; - } catch (error) { - console.error('AI响应错误:', error); - return '抱歉,我现在遇到了一些问题,请稍后再试。'; - } + document.querySelectorAll('.nav-links a').forEach(link => { + link.addEventListener('click', () => { + navLinks.classList.remove('active'); + }); + }); } - function addMessage(text, isUser = false) { - const messageDiv = document.createElement('div'); - messageDiv.className = `message ${isUser ? 'user' : 'assistant'}`; - messageDiv.innerHTML = `

${text}

`; - chatMessages.appendChild(messageDiv); - chatMessages.scrollTop = chatMessages.scrollHeight; - return messageDiv; // 返回消息元素以便后续可能的移除操作 + // Counter animation for hero stats + function animateCounters() { + const counters = document.querySelectorAll('.stat-number'); + counters.forEach(counter => { + const target = parseInt(counter.getAttribute('data-target')); + const duration = 2000; + const start = performance.now(); + + function update(currentTime) { + const elapsed = currentTime - start; + const progress = Math.min(elapsed / duration, 1); + const eased = 1 - Math.pow(1 - progress, 3); + counter.textContent = Math.floor(target * eased); + + if (progress < 1) { + requestAnimationFrame(update); + } else { + counter.textContent = target; + } + } + + requestAnimationFrame(update); + }); } - async function handleSend() { - const text = userInput.value.trim(); - if (text === '') return; - - // 添加用户消息 - addMessage(text, true); - - // 显示加载状态 - const loadingMessage = addMessage('思考中...', false); - - try { - // 获取AI回复 - const response = await getAIResponse(text); - - // 移除加载消息 - loadingMessage.remove(); - - // 添加AI回复 - addMessage(response); - } catch (error) { - // 移除加载消息 - loadingMessage.remove(); - - // 显示错误消息 - addMessage('抱歉,我遇到了一些问题,请稍后再试。'); - } - - // 清空输入框 - userInput.value = ''; + // Skill level bars animation + function animateSkillBars() { + const bars = document.querySelectorAll('.level-bar'); + bars.forEach(bar => { + const level = bar.getAttribute('data-level'); + bar.style.width = level + '%'; + }); } - // 点击发送按钮发送消息 - sendButton.addEventListener('click', handleSend); + // Intersection Observer for scroll animations + const observerOptions = { + threshold: 0.15, + rootMargin: '0px 0px -50px 0px' + }; - // 按回车键发送消息 - userInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - handleSend(); - } + const fadeObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + fadeObserver.unobserve(entry.target); + } + }); + }, observerOptions); + + // Apply fade-in to major sections + document.querySelectorAll( + '.skill-card, .timeline-item, .project-card, .edu-card, .contact-card' + ).forEach(el => { + el.classList.add('fade-in'); + fadeObserver.observe(el); }); - // 在 DOMContentLoaded 事件处理函数中添加 - const emailLink = document.querySelector('.social-link.email'); - const emailAddress = '380022215@qq.com'; - - emailLink.addEventListener('click', (e) => { - e.preventDefault(); - navigator.clipboard.writeText(emailAddress).then(() => { - emailLink.classList.add('copied'); - setTimeout(() => { - emailLink.classList.remove('copied'); - }, 5000); + // Trigger counter animation when hero is in view + const heroObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + animateCounters(); + heroObserver.unobserve(entry.target); + } + }); + }, { threshold: 0.3 }); + + const heroStats = document.querySelector('.hero-stats'); + if (heroStats) heroObserver.observe(heroStats); + + // Trigger skill bars when section is in view + const skillObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + animateSkillBars(); + skillObserver.unobserve(entry.target); + } + }); + }, { threshold: 0.2 }); + + const skillsSection = document.querySelector('.skills-section'); + if (skillsSection) skillObserver.observe(skillsSection); + + // Back to top button + const backToTop = document.querySelector('.back-to-top'); + + if (backToTop) { + window.addEventListener('scroll', () => { + if (window.scrollY > 400) { + backToTop.classList.add('visible'); + } else { + backToTop.classList.remove('visible'); + } + }, { passive: true }); + + backToTop.addEventListener('click', () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }); + } + + // Smooth anchor navigation with offset for fixed navbar + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + const href = this.getAttribute('href'); + if (href === '#') return; + + const target = document.querySelector(href); + if (target) { + e.preventDefault(); + target.scrollIntoView({ behavior: 'smooth' }); + } }); }); -}); \ No newline at end of file + +}); diff --git a/styles.css b/styles.css index cd73136..84f4362 100644 --- a/styles.css +++ b/styles.css @@ -1,8 +1,31 @@ +/* ======================================== + NEOBRUTALISM RESUME — 熠辉 + ======================================== */ + :root { - --color-primary: #FAFAFA; - --color-secondary: #E0E0E0; - --color-accent: #8AAAE5; - --color-text: #424242; + --black: #1a1a2e; + --white: #fffdf7; + --yellow: #FFD803; + --pink: #FF6B9D; + --blue: #4ECDC4; + --purple: #A855F7; + --green: #22C55E; + --orange: #FF8A50; + --red: #EF4444; + --gray-light: #f5f3ee; + --gray: #e8e5de; + --gray-dark: #6b7280; + + --border: 3px solid var(--black); + --shadow: 6px 6px 0px var(--black); + --shadow-sm: 4px 4px 0px var(--black); + --shadow-lg: 8px 8px 0px var(--black); + + --font-mono: 'Space Mono', 'Noto Sans SC', monospace; + --font-sans: 'Inter', 'Noto Sans SC', -apple-system, BlinkMacSystemFont, sans-serif; + + --radius: 0px; + --transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1); } * { @@ -11,281 +34,1044 @@ box-sizing: border-box; } +html { + scroll-behavior: smooth; + scroll-padding-top: 80px; +} + body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - background: var(--color-primary); - color: var(--color-text); - line-height: 1.6; + font-family: var(--font-sans); + background: var(--white); + color: var(--black); + line-height: 1.7; + overflow-x: hidden; +} + +::selection { + background: var(--yellow); + color: var(--black); +} + +/* ========== NAVBAR ========== */ +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + background: var(--white); + border-bottom: var(--border); + transition: transform var(--transition); } -.container { +.nav-inner { max-width: 1200px; margin: 0 auto; - padding: 0 20px; + padding: 0 24px; + height: 70px; + display: flex; + align-items: center; + justify-content: space-between; } -/* 顶部区域 */ -.header { - padding: 60px 0; - text-align: center; +.nav-logo { + font-family: var(--font-mono); + font-size: 1.5rem; + font-weight: 700; + color: var(--black); + text-decoration: none; + padding: 6px 16px; + background: var(--yellow); + border: var(--border); + box-shadow: var(--shadow-sm); + transition: all var(--transition); } -.logo { - font-size: 2.5rem; - color: var(--color-text); - margin-bottom: 1.5rem; +.nav-logo:hover { + transform: translate(2px, 2px); + box-shadow: 2px 2px 0px var(--black); +} + +.nav-links { + display: flex; + gap: 8px; +} + +.nav-links a { + font-family: var(--font-mono); + font-size: 0.9rem; + font-weight: 700; + color: var(--black); + text-decoration: none; + padding: 8px 16px; + border: 2px solid transparent; + transition: all var(--transition); +} + +.nav-links a:hover { + background: var(--yellow); + border-color: var(--black); + box-shadow: var(--shadow-sm); + transform: translate(-2px, -2px); } -.intro { - max-width: 800px; +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + background: none; + border: var(--border); + padding: 8px; + cursor: pointer; + box-shadow: var(--shadow-sm); + background: var(--yellow); +} + +.nav-toggle span { + display: block; + width: 24px; + height: 3px; + background: var(--black); + transition: all var(--transition); +} + +/* ========== HERO ========== */ +.hero { + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + padding: 100px 24px 40px; + background: var(--white); + position: relative; +} + +.hero-content { + max-width: 1200px; margin: 0 auto; - padding: 0 20px; + width: 100%; + display: grid; + grid-template-columns: 1.2fr 0.8fr; + gap: 60px; + align-items: center; } -.intro-quote { +.hero-badge { + display: inline-block; + font-family: var(--font-mono); + font-size: 0.9rem; + font-weight: 700; + padding: 8px 20px; + background: var(--blue); + border: var(--border); + box-shadow: var(--shadow-sm); + margin-bottom: 24px; + letter-spacing: 0.05em; +} + +.hero-greeting { + display: block; + font-family: var(--font-mono); font-size: 1.2rem; + font-weight: 400; + color: var(--gray-dark); + margin-bottom: 8px; +} + +.hero-name { + font-family: var(--font-sans); + font-size: 5rem; + font-weight: 900; + line-height: 1.1; + margin-bottom: 24px; + letter-spacing: -0.02em; +} + +.hero-desc { + font-size: 1.15rem; line-height: 1.8; - color: var(--color-text); - margin-bottom: 0.8rem; - font-weight: 300; + color: var(--gray-dark); + max-width: 560px; + margin-bottom: 32px; +} + +.hero-actions { + display: flex; + gap: 16px; + margin-bottom: 48px; } -.intro-author { +.btn { + font-family: var(--font-mono); font-size: 1rem; - color: var(--color-text); - opacity: 0.8; - font-style: italic; + font-weight: 700; + padding: 14px 32px; + text-decoration: none; + border: var(--border); + cursor: pointer; + transition: all var(--transition); + display: inline-block; } -/* 相册区域 */ -.gallery { - margin: 40px auto; - max-width: 600px; - width: 50%; +.btn-primary { + background: var(--yellow); + color: var(--black); + box-shadow: var(--shadow); } -.gallery-title { - text-align: center; - margin-bottom: 20px; - font-size: 1.8rem; - color: var(--color-text); - font-weight: 500; +.btn-primary:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); } -.gallery-container { - aspect-ratio: 16 / 9; /* 设置固定的宽高比 */ - border-radius: 12px; - overflow: hidden; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); +.btn-primary:active { + transform: translate(6px, 6px); + box-shadow: none; } -.gallery-item { - width: 100%; - height: 100%; +.btn-secondary { + background: var(--white); + color: var(--black); + box-shadow: var(--shadow); } -.gallery-item img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; - transition: transform 0.3s ease, opacity 0.5s ease-in-out; +.btn-secondary:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); + background: var(--pink); + color: var(--black); } -.gallery-item:hover img { - transform: scale(1.02); /* 鼠标悬停时轻微放大效果 */ +.btn-secondary:active { + transform: translate(6px, 6px); + box-shadow: none; } -/* 社交链接 */ -.social-links { +.hero-stats { + display: flex; + gap: 40px; +} + +.stat-item { + text-align: center; +} + +.stat-number { + font-family: var(--font-mono); + font-size: 2.5rem; + font-weight: 700; + color: var(--black); + display: inline; +} + +.stat-suffix { + font-family: var(--font-mono); + font-size: 1.5rem; + font-weight: 700; + color: var(--pink); +} + +.stat-label { + display: block; + font-size: 0.85rem; + color: var(--gray-dark); + margin-top: 4px; + font-weight: 500; +} + +/* Avatar */ +.hero-visual { display: flex; justify-content: center; - gap: 30px; - margin: 40px 0; + align-items: center; } -.social-link { - width: 40px; - height: 40px; +.avatar-wrapper { + position: relative; + width: 320px; + height: 320px; +} + +.avatar-box { + width: 100%; + height: 100%; + border: var(--border); + box-shadow: var(--shadow-lg); + background: var(--gray-light); + overflow: hidden; display: flex; align-items: center; justify-content: center; - border-radius: 50%; - transition: transform 0.3s ease; + transition: all var(--transition); } -.social-link:hover { - transform: scale(1.1); +.avatar-box:hover { + transform: translate(4px, 4px); + box-shadow: 4px 4px 0px var(--black); } -.icon { - width: 24px; - height: 24px; - fill: var(--color-text); +.avatar-placeholder svg { + width: 200px; + height: 200px; } -.bilibili:hover .icon { - fill: #00A1D6; /* 哔哩哔哩的品牌色 */ +.floating-tag { + position: absolute; + font-family: var(--font-mono); + font-size: 0.85rem; + font-weight: 700; + padding: 8px 16px; + border: var(--border); + box-shadow: var(--shadow-sm); + animation: float 3s ease-in-out infinite; + white-space: nowrap; } -.weibo:hover .icon { - fill: #E6162D; /* 微博的品牌色 */ +.tag-1 { + top: -10px; + right: -20px; + background: var(--blue); + animation-delay: 0s; } -/* 底栏 */ -.footer { - text-align: center; - padding: 20px 0; - margin-top: 40px; - border-top: 1px solid var(--color-secondary); +.tag-2 { + bottom: 40px; + right: -40px; + background: var(--green); + animation-delay: 0.5s; } -/* 响应式设计 */ -@media (max-width: 768px) { - .social-links { - flex-wrap: wrap; - } - - .logo { - font-size: 2rem; - } +.tag-3 { + top: 40px; + left: -30px; + background: var(--pink); + animation-delay: 1s; +} - .gallery { - width: 90%; - } +.tag-4 { + bottom: -10px; + left: -10px; + background: var(--purple); + color: var(--white); + animation-delay: 1.5s; +} - .intro-quote { - font-size: 1rem; - line-height: 1.6; - } - - .intro-author { - font-size: 0.9rem; - } +@keyframes float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } } -/* AI助手对话区 */ -.ai-chat { - max-width: 800px; - margin: 40px auto; - background: white; - border-radius: 12px; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); - padding: 20px; +.scroll-hint { + position: absolute; + bottom: 30px; + left: 50%; + transform: translateX(-50%); + text-align: center; + font-family: var(--font-mono); + font-size: 0.8rem; + color: var(--gray-dark); } -.chat-container { +.scroll-arrow { + font-size: 1.2rem; + animation: bounce 2s infinite; + margin-top: 4px; +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } + 40% { transform: translateY(-8px); } + 60% { transform: translateY(-4px); } +} + +/* ========== SECTIONS COMMON ========== */ +.section-inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 24px; +} + +.section-title { + font-family: var(--font-sans); + font-size: 2.8rem; + font-weight: 900; + margin-bottom: 48px; display: flex; - flex-direction: column; - gap: 20px; + align-items: center; + gap: 16px; +} + +.section-num { + font-family: var(--font-mono); + font-size: 1rem; + font-weight: 700; + padding: 6px 14px; + background: var(--yellow); + border: var(--border); + box-shadow: var(--shadow-sm); +} + +/* ========== SKILLS ========== */ +.skills-section { + padding: 100px 0; + background: var(--gray-light); + border-top: var(--border); + border-bottom: var(--border); } -.chat-messages { - min-height: 100px; - max-height: 300px; - overflow-y: auto; - padding: 10px; +.skills-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24px; } -.message { - margin-bottom: 15px; - padding: 10px 15px; - border-radius: 8px; - max-width: 80%; +.skill-card { + padding: 32px; + border: var(--border); + box-shadow: var(--shadow); + background: var(--white); + transition: all var(--transition); } -.message.assistant { - background: var(--color-accent); - color: white; - margin-right: auto; +.skill-card:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); +} + +.skill-icon { + width: 48px; + height: 48px; + margin-bottom: 16px; +} + +.skill-icon svg { + width: 100%; + height: 100%; } -.message.user { - background: var(--color-secondary); - margin-left: auto; +.skill-frontend .skill-icon { color: var(--blue); } +.skill-backend .skill-icon { color: var(--green); } +.skill-database .skill-icon { color: var(--orange); } +.skill-devops .skill-icon { color: var(--purple); } + +.skill-card h3 { + font-family: var(--font-sans); + font-size: 1.3rem; + font-weight: 800; + margin-bottom: 16px; } -.chat-input { +.skill-tags { display: flex; - gap: 10px; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 20px; } -.chat-input input { - flex: 1; - padding: 10px; - border: 1px solid var(--color-secondary); - border-radius: 6px; - font-size: 1rem; +.skill-tag { + font-family: var(--font-mono); + font-size: 0.8rem; + font-weight: 700; + padding: 6px 12px; + background: var(--gray-light); + border: 2px solid var(--black); + transition: all var(--transition); } -.send-btn { - padding: 10px 20px; - background: var(--color-accent); - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - transition: background 0.3s ease; +.skill-frontend .skill-tag:hover { background: var(--blue); } +.skill-backend .skill-tag:hover { background: var(--green); } +.skill-database .skill-tag:hover { background: var(--orange); } +.skill-devops .skill-tag:hover { background: var(--purple); color: var(--white); } + +.skill-level { + height: 12px; + background: var(--gray); + border: 2px solid var(--black); + overflow: hidden; } -.send-btn:hover { - background: #7090d0; +.level-bar { + height: 100%; + width: 0; + transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1); } -/* 邮箱图标相关样式 */ -.email { +.skill-frontend .level-bar { background: var(--blue); } +.skill-backend .level-bar { background: var(--green); } +.skill-database .level-bar { background: var(--orange); } +.skill-devops .level-bar { background: var(--purple); } + +/* ========== EXPERIENCE ========== */ +.experience-section { + padding: 100px 0; + background: var(--white); +} + +.timeline { position: relative; + padding-left: 40px; } -.email-tooltip { +.timeline::before { + content: ''; position: absolute; - bottom: -40px; - left: 50%; - transform: translateX(-50%); - background: var(--color-text); - color: white; - padding: 8px 12px; - border-radius: 6px; - font-size: 14px; - opacity: 0; - visibility: hidden; - transition: opacity 0.3s ease, visibility 0.3s ease; - white-space: nowrap; - pointer-events: none; + left: 12px; + top: 0; + bottom: 0; + width: 4px; + background: var(--black); } -.email-tooltip::before { - content: ''; +.timeline-item { + position: relative; + margin-bottom: 40px; +} + +.timeline-item:last-child { + margin-bottom: 0; +} + +.timeline-dot { position: absolute; - top: -6px; - left: 50%; - transform: translateX(-50%); - border-width: 0 6px 6px 6px; - border-style: solid; - border-color: transparent transparent var(--color-text) transparent; + left: -34px; + top: 24px; + width: 20px; + height: 20px; + background: var(--yellow); + border: var(--border); + z-index: 1; } -.email:hover .email-tooltip { - opacity: 1; - visibility: visible; +.timeline-card { + padding: 32px; + border: var(--border); + box-shadow: var(--shadow); + background: var(--white); + transition: all var(--transition); +} + +.timeline-card:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); +} + +.card-accent-blue { border-left: 8px solid var(--blue); } +.card-accent-green { border-left: 8px solid var(--green); } +.card-accent-purple { border-left: 8px solid var(--purple); } + +.timeline-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 16px; + flex-wrap: wrap; + gap: 12px; +} + +.timeline-header h3 { + font-size: 1.3rem; + font-weight: 800; } -.email:hover .icon { - fill: #4A7CF6; /* QQ邮箱的品牌色 */ +.company { + font-family: var(--font-mono); + font-size: 0.95rem; + color: var(--gray-dark); + margin-top: 4px; +} + +.timeline-date { + font-family: var(--font-mono); + font-size: 0.85rem; + font-weight: 700; + padding: 6px 14px; + background: var(--yellow); + border: 2px solid var(--black); + white-space: nowrap; +} + +.timeline-details { + list-style: none; + margin-bottom: 16px; +} + +.timeline-details li { + position: relative; + padding-left: 20px; + margin-bottom: 8px; + font-size: 0.95rem; + line-height: 1.7; + color: var(--gray-dark); } -/* 点击复制效果 */ -.email.copied .email-tooltip::after { - content: '已复制!'; +.timeline-details li::before { + content: '▸'; position: absolute; - top: 0; left: 0; - width: 100%; - height: 100%; + color: var(--black); + font-weight: 700; +} + +.timeline-tech { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.timeline-tech span { + font-family: var(--font-mono); + font-size: 0.75rem; + font-weight: 700; + padding: 4px 10px; + background: var(--gray-light); + border: 2px solid var(--black); +} + +/* ========== PROJECTS ========== */ +.projects-section { + padding: 100px 0; + background: var(--gray-light); + border-top: var(--border); + border-bottom: var(--border); +} + +.projects-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.project-card { + padding: 32px; + border: var(--border); + box-shadow: var(--shadow); + transition: all var(--transition); + display: flex; + flex-direction: column; +} + +.project-card:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); +} + +.project-color-1 { background: #e0f7fa; } +.project-color-2 { background: #fff3e0; } +.project-color-3 { background: #fce4ec; } + +.project-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 20px; +} + +.project-icon { + width: 40px; + height: 40px; + color: var(--black); +} + +.project-links { + display: flex; + gap: 12px; +} + +.project-links a { + color: var(--black); + opacity: 0.6; + transition: all var(--transition); +} + +.project-links a:hover { + opacity: 1; + transform: translateY(-2px); +} + +.project-links a svg { + width: 22px; + height: 22px; +} + +.project-name { + font-size: 1.4rem; + font-weight: 800; + margin-bottom: 12px; +} + +.project-desc { + font-size: 0.92rem; + line-height: 1.7; + color: var(--gray-dark); + margin-bottom: 20px; + flex: 1; +} + +.project-tech { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 16px; +} + +.project-tech span { + font-family: var(--font-mono); + font-size: 0.75rem; + font-weight: 700; + padding: 4px 10px; + background: rgba(255, 255, 255, 0.7); + border: 2px solid var(--black); +} + +.project-stats { + display: flex; + gap: 16px; + font-family: var(--font-mono); + font-size: 0.85rem; + font-weight: 700; + padding-top: 16px; + border-top: 2px dashed var(--black); +} + +/* ========== EDUCATION ========== */ +.education-section { + padding: 100px 0; + background: var(--white); +} + +.edu-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24px; +} + +.edu-card { + display: flex; + gap: 24px; + padding: 32px; + border: var(--border); + box-shadow: var(--shadow); + background: var(--white); + transition: all var(--transition); +} + +.edu-card:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); +} + +.edu-icon { + font-size: 2.5rem; + flex-shrink: 0; + width: 60px; + height: 60px; display: flex; align-items: center; justify-content: center; - background: var(--color-accent); - border-radius: 6px; - animation: fadeOut 5s forwards; -} \ No newline at end of file + background: var(--yellow); + border: var(--border); +} + +.edu-info h3 { + font-size: 1.15rem; + font-weight: 800; + margin-bottom: 4px; +} + +.edu-school { + font-family: var(--font-mono); + font-weight: 700; + color: var(--black); + margin-bottom: 4px; +} + +.edu-year { + font-family: var(--font-mono); + font-size: 0.85rem; + color: var(--gray-dark); + margin-bottom: 8px; +} + +.edu-detail { + font-size: 0.9rem; + color: var(--gray-dark); +} + +/* ========== CONTACT ========== */ +.contact-section { + padding: 100px 0; + background: var(--yellow); + border-top: var(--border); + border-bottom: var(--border); +} + +.contact-intro { + font-size: 1.15rem; + color: var(--black); + margin-bottom: 40px; + max-width: 560px; +} + +.contact-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; +} + +.contact-card { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 12px; + padding: 32px 20px; + border: var(--border); + box-shadow: var(--shadow); + background: var(--white); + text-decoration: none; + color: var(--black); + transition: all var(--transition); +} + +.contact-card:hover { + transform: translate(3px, 3px); + box-shadow: 3px 3px 0px var(--black); +} + +.contact-email:hover { background: #dbeafe; } +.contact-github:hover { background: #f3e8ff; } +.contact-wechat:hover { background: #dcfce7; } +.contact-blog:hover { background: #fef3c7; } + +.contact-icon { + width: 48px; + height: 48px; +} + +.contact-icon svg { + width: 100%; + height: 100%; +} + +.contact-label { + font-family: var(--font-mono); + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--gray-dark); +} + +.contact-value { + font-family: var(--font-mono); + font-size: 0.85rem; + font-weight: 700; +} + +/* ========== FOOTER ========== */ +.footer { + padding: 40px 24px; + background: var(--black); + color: var(--white); + text-align: center; +} + +.footer-inner { + max-width: 1200px; + margin: 0 auto; +} + +.footer-text { + font-family: var(--font-mono); + font-size: 1rem; + margin-bottom: 8px; + color: var(--yellow); +} + +.footer-copyright { + font-size: 0.85rem; + opacity: 0.6; +} + +/* ========== BACK TO TOP ========== */ +.back-to-top { + position: fixed; + bottom: 30px; + right: 30px; + width: 50px; + height: 50px; + font-size: 1.4rem; + font-weight: 700; + background: var(--yellow); + border: var(--border); + box-shadow: var(--shadow-sm); + cursor: pointer; + opacity: 0; + pointer-events: none; + transition: all var(--transition); + z-index: 900; +} + +.back-to-top.visible { + opacity: 1; + pointer-events: auto; +} + +.back-to-top:hover { + transform: translate(2px, 2px); + box-shadow: 2px 2px 0px var(--black); +} + +/* ========== ANIMATIONS ========== */ +.fade-in { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +.fade-in.visible { + opacity: 1; + transform: translateY(0); +} + +/* ========== RESPONSIVE ========== */ +@media (max-width: 1024px) { + .hero-content { + grid-template-columns: 1fr; + gap: 40px; + text-align: center; + } + + .hero-desc { + max-width: 100%; + } + + .hero-actions { + justify-content: center; + } + + .hero-stats { + justify-content: center; + } + + .hero-visual { + order: -1; + } + + .avatar-wrapper { + width: 250px; + height: 250px; + } + + .projects-grid { + grid-template-columns: repeat(2, 1fr); + } + + .contact-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .nav-links { + display: none; + position: absolute; + top: 70px; + left: 0; + right: 0; + background: var(--white); + border-bottom: var(--border); + flex-direction: column; + padding: 16px; + } + + .nav-links.active { + display: flex; + } + + .nav-toggle { + display: flex; + } + + .hero-name { + font-size: 3rem; + } + + .section-title { + font-size: 2rem; + } + + .skills-grid { + grid-template-columns: 1fr; + } + + .projects-grid { + grid-template-columns: 1fr; + } + + .edu-grid { + grid-template-columns: 1fr; + } + + .edu-card { + flex-direction: column; + align-items: flex-start; + } + + .contact-grid { + grid-template-columns: 1fr; + } + + .hero-stats { + flex-direction: column; + gap: 16px; + } + + .timeline { + padding-left: 30px; + } + + .timeline-dot { + left: -24px; + width: 16px; + height: 16px; + } + + .timeline::before { + left: 8px; + } + + .floating-tag { + font-size: 0.75rem; + padding: 6px 12px; + } + + .tag-2 { right: -20px; } + .tag-3 { left: -15px; } +} + +@media (max-width: 480px) { + .hero-name { + font-size: 2.4rem; + } + + .hero-actions { + flex-direction: column; + align-items: center; + } + + .btn { + width: 100%; + text-align: center; + } + + .avatar-wrapper { + width: 200px; + height: 200px; + } + + .avatar-placeholder svg { + width: 140px; + height: 140px; + } +}