diff --git a/about.html b/about.html index afe7099..4c1ec62 100644 --- a/about.html +++ b/about.html @@ -10,7 +10,7 @@ - + @@ -263,7 +263,7 @@ - + \ No newline at end of file diff --git a/css/about.css b/css/about.css index cae785b..9600656 100644 --- a/css/about.css +++ b/css/about.css @@ -28,7 +28,7 @@ --dock-bg: rgba(255, 255, 255, 0.85); --radius: 24px; - + /* 渐变色彩 */ --gradient-1: linear-gradient(135deg, #a1c4fd, #6c5ce7); --gradient-2: linear-gradient(135deg, #c2e9fb, #00cec9); @@ -63,8 +63,18 @@ } /* Global Reset */ -* { box-sizing: border-box; margin: 0; padding: 0; outline: none; -webkit-tap-highlight-color: transparent; } -html { font-size: 16px; } +* { + box-sizing: border-box; + margin: 0; + padding: 0; + outline: none; + -webkit-tap-highlight-color: transparent; +} + +html { + font-size: 16px; +} + body { font-family: var(--font-main); background: var(--bg-base); @@ -77,19 +87,53 @@ body { /* Ambient Background */ .aurora-canvas { - position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; + position: fixed; + inset: 0; + z-index: -1; + overflow: hidden; + pointer-events: none; } + .glow-spot { - position: absolute; border-radius: 50%; filter: blur(80px); opacity: 0.5; + position: absolute; + border-radius: 50%; + filter: blur(80px); + opacity: 0.5; animation: float 20s infinite alternate; } -.spot-1 { top: -10%; left: -10%; width: 50vw; height: 50vw; background: var(--bg-grad-1); } -.spot-2 { bottom: -10%; right: -10%; width: 60vw; height: 60vw; background: var(--bg-grad-2); animation-delay: -5s; } + +.spot-1 { + top: -10%; + left: -10%; + width: 50vw; + height: 50vw; + background: var(--bg-grad-1); +} + +.spot-2 { + bottom: -10%; + right: -10%; + width: 60vw; + height: 60vw; + background: var(--bg-grad-2); + animation-delay: -5s; +} + .noise-layer { - position: absolute; inset: 0; opacity: 0.03; + position: absolute; + inset: 0; + opacity: 0.03; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); } -@keyframes float { 0% { transform: translate(0,0); } 100% { transform: translate(30px, 50px); } } + +@keyframes float { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(30px, 50px); + } +} /* ========================================= 2. Universal Glass Components @@ -106,19 +150,40 @@ body { .bento-card:hover, .glass-panel:hover { transform: translateY(-4px); - box-shadow: 0 20px 50px rgba(0,0,0,0.1); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.1); border-color: var(--accent); } /* Typography Effects */ .gradient-text { background: linear-gradient(135deg, var(--text-primary), var(--accent)); - -webkit-background-clip: text; background-clip: text; color: transparent; + -webkit-background-clip: text; + background-clip: text; + color: transparent; } -[data-theme="night"] .gradient-text { text-shadow: 0 0 20px var(--accent-glow); } -.neon-font { font-family: var(--font-mono); font-weight: 700; color: var(--text-primary); } -[data-theme="night"] .neon-font { color: #fff; text-shadow: 0 0 10px var(--accent); } +[data-theme="night"] .gradient-text { + text-shadow: 0 0 20px var(--accent-glow); +} + +[data-theme="night"] .tech-tag-3d { + text-shadow: 0 0 6px rgba(255, 255, 255, 0.12), 0 0 12px var(--accent-glow); +} + +[data-theme="night"] .tech-tag-mobile { + text-shadow: 0 0 6px rgba(255, 255, 255, 0.12), 0 0 12px var(--accent-glow); +} + +.neon-font { + font-family: var(--font-mono); + font-weight: 700; + color: var(--text-primary); +} + +[data-theme="night"] .neon-font { + color: #fff; + text-shadow: 0 0 10px var(--accent); +} .glow-title { font-size: 1.3rem; @@ -136,65 +201,124 @@ body { /* Desktop Nav */ @media (min-width: 769px) { .glass-nav { - position: fixed; top: 20px; left: 50%; transform: translateX(-50%); - width: 90%; max-width: 1200px; height: 68px; padding: 0 30px; z-index: 1000; + position: fixed; + top: 20px; + left: 50%; + transform: translateX(-50%); + width: 90%; + max-width: 1200px; + height: 68px; + padding: 0 30px; + z-index: 1000; border-radius: 100px; } - .nav-inner { display: flex; justify-content: space-between; align-items: center; height: 100%; } - .logo-brand { font-family: var(--font-serif); font-size: 1.5rem; font-weight: 700; color: var(--text-primary); text-decoration: none; } - .logo-accent { color: var(--accent); font-size: 2rem; line-height: 0; } + .nav-inner { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + } + + .logo-brand { + font-family: var(--font-serif); + font-size: 1.5rem; + font-weight: 700; + color: var(--text-primary); + text-decoration: none; + } + + .logo-accent { + color: var(--accent); + font-size: 2rem; + line-height: 0; + } + + .nav-menu { + display: flex; + align-items: center; + gap: 24px; + } - .nav-menu { display: flex; align-items: center; gap: 24px; } .nav-item { - display: flex; align-items: center; gap: 6px; color: var(--text-secondary); - text-decoration: none; font-weight: 500; font-size: 0.95rem; transition: color 0.3s; + display: flex; + align-items: center; + gap: 6px; + color: var(--text-secondary); + text-decoration: none; + font-weight: 500; + font-size: 0.95rem; + transition: color 0.3s; padding: 8px 16px; border-radius: 20px; } - .nav-item:hover, .nav-item.active { - color: var(--text-primary); + + .nav-item:hover, .nav-item.active { + color: var(--text-primary); background: rgba(108, 92, 231, 0.1); } - .nav-item i { font-size: 1.2rem; } - .nav-divider { width: 1px; height: 20px; background: var(--text-tertiary); opacity: 0.3; } - + .nav-item i { + font-size: 1.2rem; + } + + .nav-divider { + width: 1px; + height: 20px; + background: var(--text-tertiary); + opacity: 0.3; + } + /* 增强主题和语言切换按钮样式 */ - .action-btn { - display: flex; align-items: center; gap: 4px; - color: var(--text-primary); - font-size: 0.9rem; - opacity: 0.8; + .action-btn { + display: flex; + align-items: center; + gap: 4px; + color: var(--text-primary); + font-size: 0.9rem; + opacity: 0.8; transition: all 0.3s; padding: 8px 16px; border-radius: 20px; - background: rgba(128,128,128,0.1); + background: rgba(128, 128, 128, 0.1); border: none; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } - .action-btn:hover { - opacity: 1; + + .action-btn:hover { + opacity: 1; background: var(--accent); color: white; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(108, 92, 231, 0.3); } + .action-btn:active { transform: translateY(0); } - [data-theme="day"] .icon-sun { display: none; } - [data-theme="night"] .icon-moon { display: none; } + + [data-theme="day"] .icon-sun { + display: none; + } + + [data-theme="night"] .icon-moon { + display: none; + } } /* ========================================= 4. Layout: Bento Grid (Responsive) ========================================= */ -.main-container { max-width: 1200px; margin: 120px auto 60px; padding: 0 30px; } +.main-container { + max-width: 1200px; + margin: 120px auto 60px; + padding: 0 30px; +} .bento-grid { - display: grid; gap: 24px; + display: grid; + gap: 24px; /* PC: 3 Col, 2 Row Main */ grid-template-columns: 320px 1fr 260px; grid-template-rows: 240px 220px auto; @@ -205,81 +329,297 @@ body { } /* --- Areas --- */ -.area-profile { grid-area: profile; } -.area-bio { grid-area: bio; } -.area-stats { grid-area: stats; } -.area-mbti { grid-area: mbti; } -.area-tech { grid-area: tech; } -.area-interests { grid-area: interests; } -.mobile-social { display: none; } +.area-profile { + grid-area: profile; +} + +.area-bio { + grid-area: bio; +} + +.area-stats { + grid-area: stats; +} + +.area-mbti { + grid-area: mbti; +} + +.area-tech { + grid-area: tech; +} + +.area-interests { + grid-area: interests; +} + +.mobile-social { + display: none; +} /* --- Profile Card --- */ -.area-profile { padding: 30px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; text-align: center; } -.avatar-ring { - position: relative; width: 120px; height: 120px; border-radius: 50%; - padding: 4px; border: 1px solid var(--text-tertiary); +.area-profile { + padding: 30px; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + text-align: center; } -.avatar-img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; } -.status-dot { - position: absolute; bottom: 0; right: 0; background: #2ecc71; color: #fff; - font-size: 0.65rem; padding: 2px 8px; border-radius: 10px; border: 2px solid var(--bg-base); -} -.hero-name { font-size: 2rem; font-family: var(--font-serif); margin: 15px 0 5px; font-weight: 800; color: var(--text-primary); } -.hero-role { font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 10px; } -.location-tag { font-size: 0.85rem; color: var(--text-tertiary); display: flex; align-items: center; justify-content: center; gap: 4px; } -.social-dock { display: flex; gap: 12px; margin-top: 20px; } -.s-icon { - width: 36px; height: 36px; border-radius: 50%; background: rgba(128,128,128,0.1); - display: flex; align-items: center; justify-content: center; color: var(--text-secondary); - transition: all 0.3s; text-decoration: none; +.avatar-ring { + position: relative; + width: 120px; + height: 120px; + border-radius: 50%; + padding: 4px; + border: 1px solid var(--text-tertiary); +} + +.avatar-img { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +} + +.status-dot { + position: absolute; + bottom: 0; + right: 0; + background: #2ecc71; + color: #fff; + font-size: 0.65rem; + padding: 2px 8px; + border-radius: 10px; + border: 2px solid var(--bg-base); +} + +.hero-name { + font-size: 2rem; + font-family: var(--font-serif); + margin: 15px 0 5px; + font-weight: 800; + color: var(--text-primary); +} + +.hero-role { + font-size: 0.9rem; + color: var(--text-secondary); + margin-bottom: 10px; +} + +.location-tag { + font-size: 0.85rem; + color: var(--text-tertiary); + display: flex; + align-items: center; + justify-content: center; + gap: 4px; +} + +.social-dock { + display: flex; + gap: 12px; + margin-top: 20px; +} + +.s-icon { + width: 36px; + height: 36px; + border-radius: 50%; + background: rgba(128, 128, 128, 0.1); + display: flex; + align-items: center; + justify-content: center; + color: var(--text-secondary); + transition: all 0.3s; + text-decoration: none; +} + +.s-icon:hover { + background: var(--accent); + color: #fff; + transform: translateY(-3px); } -.s-icon:hover { background: var(--accent); color: #fff; transform: translateY(-3px); } /* --- Bio Card --- */ -.area-bio { padding: 35px; display: flex; flex-direction: column; justify-content: center; position: relative; } -.card-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px; color: var(--text-tertiary); margin-bottom: 15px; } -.bio-text { font-size: 1rem; color: var(--text-primary); margin-bottom: 20px; text-align: justify; } -.quote-box { border-left: 3px solid var(--accent); padding-left: 15px; font-style: italic; color: var(--text-secondary); font-size: 0.9rem; } +.area-bio { + padding: 35px; + display: flex; + flex-direction: column; + justify-content: center; + position: relative; +} + +.card-label { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 2px; + color: var(--text-tertiary); + margin-bottom: 15px; +} + +.bio-text { + font-size: 1rem; + color: var(--text-primary); + margin-bottom: 20px; +} + +.quote-box { + border-left: 3px solid var(--accent); + padding-left: 15px; + font-style: italic; + color: var(--text-secondary); + font-size: 0.9rem; +} /* --- Stats --- */ -.area-stats { display: flex; flex-direction: column; justify-content: space-around; padding: 20px 30px; } -.stat-item { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(128,128,128,0.1); padding: 10px 0; } -.stat-item:last-child { border-bottom: none; } -.stat-val { font-size: 1.5rem; } -.stat-key { font-size: 0.8rem; color: var(--text-tertiary); text-transform: uppercase; } +.area-stats { + display: flex; + flex-direction: column; + justify-content: space-around; + padding: 20px 30px; +} + +.stat-item { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid rgba(128, 128, 128, 0.1); + padding: 10px 0; +} + +.stat-item:last-child { + border-bottom: none; +} + +.stat-val { + font-size: 1.5rem; +} + +.stat-key { + font-size: 0.8rem; + color: var(--text-tertiary); + text-transform: uppercase; +} /* --- MBTI --- */ -.area-mbti { padding: 30px; display: flex; align-items: center; } -.mbti-inner { width: 100%; } -.mbti-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; } -.mbti-code { font-size: 2.2rem; font-weight: 900; font-family: var(--font-mono); } -.mbti-name { font-weight: 600; color: var(--text-secondary); } -.mbti-icon { font-size: 1.5rem; } -.mbti-desc { font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 15px; line-height: 1.5; } -.mbti-tags { display: flex; gap: 3px; flex-wrap: wrap; } -.tag { font-size: 0.75rem; background: rgba(128,128,128,0.1); padding: 4px 10px; border-radius: 6px; color: var(--text-secondary); } +.area-mbti { + padding: 30px; + display: flex; + align-items: center; +} + +.mbti-inner { + width: 100%; +} + +.mbti-head { + display: flex; + align-items: baseline; + gap: 10px; + margin-bottom: 10px; +} + +.mbti-code { + font-size: 2.2rem; + font-weight: 900; + font-family: var(--font-mono); +} + +.mbti-name { + font-weight: 600; + color: var(--text-secondary); +} + +.mbti-icon { + font-size: 1.5rem; +} + +.mbti-desc { + font-size: 0.7rem; + color: var(--text-secondary); + margin-bottom: 15px; + line-height: 1.3; + font-style: italic +} + +.mbti-tags { + display: flex; + gap: 3px; + flex-wrap: wrap; +} + +.tag { + font-size: 0.75rem; + background: rgba(128, 128, 128, 0.1); + padding: 4px 10px; + border-radius: 6px; + color: var(--text-secondary); +} /* --- Tech Stack (PC) --- */ -.area-tech { display: flex; flex-direction: column; position: relative; overflow: visible; } -.card-header { padding: 20px 25px; border-bottom: 1px solid rgba(128,128,128,0.1); } -.card-header h3 { font-size: 1.1rem; color: var(--text-primary); margin: 0; } -/* PC 3D Container */ -.tech-wrapper { flex: 1; position: relative; min-height: 250px; width: 100%; overflow: visible; } -.tech-tag-3d { - position: absolute; - font-size: 0.85rem; - font-weight: 600; +.area-tech { + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; +} + +.card-header { + padding: 20px 25px; + border-bottom: 1px solid rgba(128, 128, 128, 0.1); +} + +.card-header h3 { + font-size: 1.1rem; color: var(--text-primary); - padding: 6px 12px; + margin: 0; +} + +.card-header h3 { + background: var(--gradient-2); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +[data-theme="night"] .card-header h3 { + text-shadow: 0 0 10px var(--accent-glow); +} + +.card-header h3 { + background: var(--gradient-2); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +/* PC 3D Container */ +.tech-wrapper { + flex: 1; + position: relative; + min-height: 280px; + width: 100%; + overflow: hidden; +} + +.tech-tag-3d { + position: absolute; + font-size: 0.85rem; + font-weight: 600; + color: var(--text-primary); + padding: 6px 12px; border-radius: 6px; - user-select: none; + user-select: none; white-space: nowrap; backface-visibility: hidden; will-change: transform; - /* 只保留文字渐变效果 */ - background: none; border: none; + outline: none; + box-shadow: none; + background-color: transparent !important; -webkit-background-clip: text; background-clip: text; color: transparent; @@ -322,12 +662,42 @@ body { background-clip: text; color: transparent; } + /* 扩展更多渐变方案 */ -.tech-tag-3d.tag-color-6, .tech-tag-mobile.tag-color-6 { background: var(--gradient-6); } -.tech-tag-3d.tag-color-7, .tech-tag-mobile.tag-color-7 { background: var(--gradient-7); } -.tech-tag-3d.tag-color-8, .tech-tag-mobile.tag-color-8 { background: var(--gradient-8); } -.tech-tag-3d.tag-color-9, .tech-tag-mobile.tag-color-9 { background: var(--gradient-9); } -.tech-tag-3d.tag-color-10, .tech-tag-mobile.tag-color-10 { background: var(--gradient-10); } +.tech-tag-3d.tag-color-6, .tech-tag-mobile.tag-color-6 { + background: var(--gradient-6); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.tech-tag-3d.tag-color-7, .tech-tag-mobile.tag-color-7 { + background: var(--gradient-7); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.tech-tag-3d.tag-color-8, .tech-tag-mobile.tag-color-8 { + background: var(--gradient-8); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.tech-tag-3d.tag-color-9, .tech-tag-mobile.tag-color-9 { + background: var(--gradient-9); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.tech-tag-3d.tag-color-10, .tech-tag-mobile.tag-color-10 { + background: var(--gradient-10); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} /* 渐变文字兼容处理:支持时启用文字渐变,不支持时使用纯色 */ @supports not ((-webkit-background-clip: text) or (background-clip: text)) { @@ -336,198 +706,274 @@ body { background: none !important; color: var(--text-primary) !important; } + .tech-tag-3d.tag-color-1, .tech-tag-3d.tag-color-2, .tech-tag-3d.tag-color-3, .tech-tag-3d.tag-color-4, .tech-tag-3d.tag-color-5, + .tech-tag-3d.tag-color-6, + .tech-tag-3d.tag-color-7, + .tech-tag-3d.tag-color-8, + .tech-tag-3d.tag-color-9, + .tech-tag-3d.tag-color-10, .tech-tag-mobile.tag-color-1, .tech-tag-mobile.tag-color-2, .tech-tag-mobile.tag-color-3, .tech-tag-mobile.tag-color-4, - .tech-tag-mobile.tag-color-5 { + .tech-tag-mobile.tag-color-5, + .tech-tag-mobile.tag-color-6, + .tech-tag-mobile.tag-color-7, + .tech-tag-mobile.tag-color-8, + .tech-tag-mobile.tag-color-9, + .tech-tag-mobile.tag-color-10 { background: none !important; color: var(--text-primary) !important; } } /* --- Interests --- */ -.area-interests { padding: 20px; } -.interest-list { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 15px; +.area-interests { + padding: 20px; +} + +.interest-list { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 15px; /*height: 100%; */ margin-top: 1rem; align-content: center; } -.interest-item { - background: rgba(128,128,128,0.05); + +.interest-item { + background: rgba(128, 128, 128, 0.05); padding: 5px; border-radius: 2px; - display: flex; - align-items: center; + display: flex; + align-items: center; gap: 2px; transition: background 0.3s; } -.interest-item:hover { background: rgba(128,128,128,0.1); } -.i-emoji { font-size: 1.2rem; } -.i-text { display: flex; flex-direction: column; min-width: 0; } /* 添加 min-width: 0 防止溢出 */ -.i-text strong { - font-size: 0.9rem; + +.interest-item:hover { + background: rgba(128, 128, 128, 0.1); +} + +.i-emoji { + font-size: 1.2rem; +} + +.i-text { + display: flex; + flex-direction: column; + min-width: 0; +} + +/* 添加 min-width: 0 防止溢出 */ +.i-text strong { + font-size: 0.9rem; color: var(--text-primary); /* 为兴趣标签添加渐变色彩 */ background: var(--gradient-1); -webkit-background-clip: text; background-clip: text; color: transparent; + -webkit-text-fill-color: transparent; } -.i-text span { - font-size: 0.75rem; + +.i-text span { + font-size: 0.75rem; color: var(--text-tertiary); /* 为兴趣描述添加渐变色彩 */ background: var(--gradient-2); -webkit-background-clip: text; background-clip: text; color: transparent; + -webkit-text-fill-color: transparent; } /* ========================================= 5. Content Sections (Blog/Github) ========================================= */ -.content-section { - display: flex; - flex-direction: column; - gap: 24px; - margin-top: 40px; +.content-section { + display: flex; + flex-direction: column; + gap: 24px; + margin-top: 40px; } -.col-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; + +.col-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; } -.glow-title { - font-size: 1.3rem; - font-weight: 700; - display: flex; - align-items: center; - gap: 8px; - color: var(--text-primary); + +.glow-title { + font-size: 1.3rem; + font-weight: 700; + display: flex; + align-items: center; + gap: 8px; + color: var(--text-primary); } -.more-link { - font-size: 0.9rem; - color: var(--accent); - font-weight: 600; + +.more-link { + font-size: 0.9rem; + color: var(--accent); + font-weight: 600; text-decoration: none; } -.glass-panel { - padding: 20px; - min-height: 300px; +.glass-panel { + padding: 20px; + min-height: 300px; } /* Github Lists */ -.projects-list { - margin-top: 15px; - display: flex; - flex-direction: column; - gap: 10px; - max-height: 400px; - overflow-y: auto; +.projects-list { + margin-top: 15px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 14px; } + .repo-card { - padding: 15px; - background: rgba(128,128,128,0.05); - border-radius: 12px; + padding: 14px; + background: rgba(128, 128, 128, 0.05); + border-radius: 12px; cursor: pointer; - border: 1px solid transparent; - transition: border 0.3s; + border: 1px solid transparent; + transition: border 0.3s, transform 0.2s ease; } -.repo-card:hover { - border-color: var(--accent); + +.repo-card:hover { + border-color: var(--accent); + transform: translateY(-2px); } -.repo-head { - display: flex; - justify-content: space-between; - font-weight: 700; - color: var(--text-primary); - font-size: 0.95rem; + +.repo-head { + display: flex; + justify-content: space-between; + font-weight: 700; + color: var(--text-primary); + font-size: 0.95rem; } -.repo-desc { - font-size: 0.8rem; - color: var(--text-secondary); - margin-top: 6px; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; + +.repo-desc { + font-size: 0.8rem; + color: var(--text-secondary); + margin-top: 8px; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; } /* Blog List */ -.blog-list { - display: flex; - flex-direction: column; - gap: 12px; +.blog-list { + display: flex; + flex-direction: column; + gap: 12px; } + .blog-item { - padding: 12px 16px; - border-radius: 12px; - background: rgba(128,128,128,0.03); - display: flex; - justify-content: space-between; - align-items: center; - cursor: pointer; + padding: 12px 16px; + border-radius: 12px; + background: rgba(128, 128, 128, 0.03); + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; transition: background 0.3s; } -.blog-item:hover { - background: rgba(128,128,128,0.08); + +.blog-item:hover { + background: rgba(128, 128, 128, 0.08); } -.b-info { - flex: 1; - min-width: 0; - margin-right: 15px; + +.b-info { + flex: 1; + min-width: 0; + margin-right: 15px; } -.b-title { - font-weight: 600; - font-size: 0.95rem; - color: var(--text-primary); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + +.b-title { + font-weight: 600; + font-size: 0.95rem; + color: var(--text-primary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.b-date { - font-size: 0.75rem; - color: var(--text-tertiary); + +.b-date { + font-size: 0.75rem; + color: var(--text-tertiary); } -.b-cat { - font-size: 0.75rem; - color: var(--accent); - background: rgba(128,128,128,0.1); - padding: 2px 8px; - border-radius: 4px; - white-space: nowrap; + +.b-cat { + font-size: 0.75rem; + color: var(--accent); + background: none; + padding: 0; + border-radius: 0; + white-space: nowrap; +} + +.b-title { + background: var(--gradient-3); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.b-cat { + background: var(--gradient-4); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.b-date { + background: var(--gradient-5); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +[data-theme="night"] .b-title, [data-theme="night"] .b-cat, [data-theme="night"] .b-date { + text-shadow: 0 0 12px var(--accent-glow); } /* Loading Skeleton */ -.skeleton-card { - height: 60px; - background: rgba(128,128,128,0.1); - border-radius: 10px; - animation: pulse 1.5s infinite; +.skeleton-card { + height: 60px; + background: rgba(128, 128, 128, 0.1); + border-radius: 10px; + animation: pulse 1.5s infinite; } -@keyframes pulse { - 0% { opacity: 0.6; } - 50% { opacity: 1; } - 100% { opacity: 0.6; } + +@keyframes pulse { + 0% { + opacity: 0.6; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0.6; + } } /* Comments */ -.comments-wrapper { - margin: 40px 0 80px; +.comments-wrapper { + margin: 40px 0 80px; } -.comment-box { - padding: 30px; + +.comment-box { + padding: 30px; } /* ========================================= @@ -544,29 +990,34 @@ body { "interests interests"; grid-template-rows: auto; } - .area-profile { flex-direction: row; gap: 20px; } - .content-section { - display: flex; - flex-direction: column; + + .area-profile { + flex-direction: row; + gap: 20px; } - + + .content-section { + display: flex; + flex-direction: column; + } + /* 修复平板模式下兴趣模块的高度问题 */ .interest-list { grid-template-columns: 1fr 1fr; - max-height: 150px; /* 限制高度 */ + max-height: 150px; /* 限制高度 */ overflow: hidden; } - + .i-text { flex-direction: row; align-items: center; gap: 8px; } - + .i-text strong, .i-text span { white-space: nowrap; } - + /* 兴趣模块文本渐变色彩 */ .i-text strong { background: var(--gradient-1); @@ -574,7 +1025,7 @@ body { background-clip: text; color: transparent; } - + .i-text span { background: var(--gradient-2); -webkit-background-clip: text; @@ -587,139 +1038,160 @@ body { 7. Mobile Layout (< 768px) ========================================= */ @media (max-width: 768px) { - .main-container { - margin: 20px auto 100px; - padding: 0 16px; + .main-container { + margin: 20px auto 100px; + padding: 0 16px; } /* Bottom Dock */ .glass-nav { - position: fixed; - top: auto; - bottom: 0; - left: 0; - width: 100%; + position: fixed; + top: auto; + bottom: 0; + left: 0; + width: 100%; height: auto; - border-radius: 0; - background: var(--dock-bg); + border-radius: 0; + background: var(--dock-bg); backdrop-filter: blur(12px) saturate(120%); -webkit-backdrop-filter: blur(12px) saturate(120%); - border-top: 1px solid rgba(128,128,128,0.1); + border-top: 1px solid rgba(128, 128, 128, 0.1); padding-bottom: env(safe-area-inset-bottom); z-index: 1000; } - .logo-brand, .nav-divider { - display: none; + + .logo-brand, .nav-divider { + display: none; } - .nav-menu { - width: 100%; - justify-content: space-around; - padding: 10px 0; + + .nav-menu { + width: 100%; + justify-content: space-around; + padding: 10px 0; display: flex; } - .nav-item { - flex-direction: column; - gap: 2px; - font-size: 0.7rem; + + .nav-item { + flex-direction: column; + gap: 2px; + font-size: 0.7rem; padding: 8px 0; color: var(--text-secondary); } - .nav-item i { - font-size: 1.4rem; + + .nav-item i { + font-size: 1.4rem; } - .nav-label { - font-size: 10px; + + .nav-label { + font-size: 10px; color: var(--text-primary); } - .nav-item.active { + + .nav-item.active { color: var(--text-primary); } - .action-btn .btn-text { - display: none; + + .action-btn .btn-text { + display: none; } - .action-btn { - font-size: 1.2rem; - padding: 8px; - background: rgba(128,128,128,0.08); + + .action-btn { + font-size: 1.2rem; + padding: 8px; + background: rgba(128, 128, 128, 0.08); border-radius: 12px; transition: all 0.2s ease; } + .action-btn.is-active { background: rgba(108, 92, 231, 0.25); color: #fff; } /* Stacking Bento */ - .bento-grid { - display: flex; - flex-direction: column; - gap: 16px; + .bento-grid { + display: flex; + flex-direction: column; + gap: 16px; } /* Profile Mobile */ - .area-profile { - padding: 20px; - flex-direction: row; - gap: 15px; - align-items: center; - text-align: left; + .area-profile { + padding: 20px; + flex-direction: row; + gap: 15px; + align-items: center; + text-align: left; } - .avatar-ring { - width: 80px; - height: 80px; - padding: 2px; - margin: 0; + + .avatar-ring { + width: 80px; + height: 80px; + padding: 2px; + margin: 0; } - .status-dot { - right: 0; - bottom: 0; - width: 12px; - height: 12px; - font-size: 0; - padding: 0; + + .status-dot { + right: 0; + bottom: 0; + width: 12px; + height: 12px; + font-size: 0; + padding: 0; } - .hero-name { - margin: 0 0 4px; - font-size: 1.5rem; + + .hero-name { + margin: 0 0 4px; + font-size: 1.5rem; } - .hero-role { - font-size: 0.8rem; - margin-bottom: 6px; + + .hero-role { + font-size: 0.8rem; + margin-bottom: 6px; } - .location-tag { - justify-content: flex-start; + + .location-tag { + justify-content: flex-start; } - .desktop-social { - display: none; + + .desktop-social { + display: none; } /* Mobile Stats */ - .area-stats { - flex-direction: row; - padding: 15px; + .area-stats { + flex-direction: row; + padding: 15px; } - .stat-item { - flex-direction: column; - border-bottom: none; - border-right: 1px solid rgba(128,128,128,0.1); - padding: 0 10px; - flex: 1; - text-align: center; + + .stat-item { + flex-direction: column; + border-bottom: none; + border-right: 1px solid rgba(128, 128, 128, 0.1); + padding: 0 10px; + flex: 1; + text-align: center; } - .stat-item:last-child { - border-right: none; + + .stat-item:last-child { + border-right: none; } - .stat-val { - font-size: 1.2rem; + + .stat-val { + font-size: 1.2rem; } /* Mobile Tech Scroll (Horizontal) */ - .area-tech { - height: auto; + .area-tech { + height: auto; } - .tech-wrapper { - display: none; - } /* Hide PC wrapper */ + + .tech-wrapper { + display: none; + } + + /* Hide PC wrapper */ .tech-wrapper.mobile-scroll { display: grid; height: auto; @@ -732,88 +1204,107 @@ body { scroll-snap-type: x mandatory; /* 添加淡入淡出效果 */ mask-image: linear-gradient( - to right, - transparent 0%, - black 10%, - black 90%, - transparent 100% + to right, + transparent 0%, + black 10%, + black 90%, + transparent 100% ); -webkit-mask-image: linear-gradient( - to right, - transparent 0%, - black 10%, - black 90%, - transparent 100% + to right, + transparent 0%, + black 10%, + black 90%, + transparent 100% ); } - -.tech-tag-mobile { - scroll-snap-align: start; - padding: 6px 12px; - border-radius: 20px; - font-size: 0.8rem; - font-family: var(--font-mono); - white-space: nowrap; - border: none; - font-weight: bold; - /* 添加文字渐变效果 */ - background: var(--gradient-1); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - pointer-events: none; - z-index: 10; -} + + .tech-tag-mobile { + scroll-snap-align: start; + padding: 6px 12px; + border-radius: 20px; + font-size: 0.8rem; + font-family: var(--font-mono); + white-space: nowrap; + border: none; + outline: none; + box-shadow: none; + background-color: transparent !important; + font-weight: bold; + /* 渐变由 tag-color-* 提供 */ + -webkit-background-clip: text; + background-clip: text; + color: transparent; + -webkit-text-fill-color: transparent; + pointer-events: none; + z-index: 10; + } /* Mobile Social */ - .mobile-social { - display: flex; - justify-content: space-around; - padding: 20px; - } - .ms-btn { - width: 40px; - height: 40px; - border-radius: 50%; - background: rgba(128,128,128,0.1); - display: flex; - align-items: center; - justify-content: center; - color: var(--text-secondary); - font-size: 1.4rem; + .mobile-social { + display: flex; + justify-content: space-around; + padding: 20px; } - .content-section { - display: flex; - flex-direction: column; + .ms-btn { + width: 40px; + height: 40px; + border-radius: 50%; + background: rgba(128, 128, 128, 0.1); + display: flex; + align-items: center; + justify-content: center; + color: var(--text-secondary); + font-size: 1.4rem; } - + + .content-section { + display: flex; + flex-direction: column; + } + /* 修复兴趣模块在移动端的溢出问题 */ .interest-list { grid-template-columns: 1fr; max-height: none; } - + .interest-item { min-width: 0; } - + .i-text { min-width: 0; } - + /* 修复移动端兴趣模块标签和描述在同一行 */ .i-text { flex-direction: row; align-items: center; gap: 8px; flex-wrap: wrap; + overflow: hidden; } - + .i-text strong, .i-text span { white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } - + + .interest-item { + padding: 12px; + } + + .i-emoji { + flex-shrink: 0; + } + + .i-text { + min-width: 0; + } + /* 兴趣模块文本渐变色彩 */ .i-text strong { background: var(--gradient-1); @@ -821,7 +1312,7 @@ body { background-clip: text; color: transparent; } - + .i-text span { background: var(--gradient-2); -webkit-background-clip: text; @@ -834,45 +1325,75 @@ body { 8. Modal & Footer ========================================= */ .modal-overlay { - position: fixed; - inset: 0; - z-index: 2000; - background: rgba(0,0,0,0.6); + position: fixed; + inset: 0; + z-index: 2000; + background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(8px); - display: none; - align-items: center; + display: none; + align-items: center; justify-content: center; } -.modal-glass { - width: 300px; - padding: 30px; - text-align: center; - position: relative; -} -.modal-close { - position: absolute; - top: 15px; - right: 15px; - font-size: 1.5rem; - color: var(--text-secondary); -} -.qr-box { - margin: 20px 0; -} -.qr-box img { - width: 100%; - border-radius: 12px; -} -.qr-fallback { - padding: 40px; - background: #eee; - border-radius: 12px; - font-size: 0.8rem; + +.modal-glass { + width: 300px; + padding: 30px; + text-align: center; + position: relative; } -.site-footer { - text-align: center; - color: var(--text-tertiary); - font-size: 0.75rem; - padding-bottom: 100px; +.modal-close { + position: absolute; + top: 15px; + right: 15px; + font-size: 1.5rem; + color: var(--text-secondary); +} + +.qr-box { + margin: 20px 0; +} + +.qr-box img { + width: 100%; + border-radius: 12px; +} + +.qr-fallback { + padding: 40px; + background: #eee; + border-radius: 12px; + font-size: 0.8rem; +} + +.site-footer { + text-align: center; + color: var(--text-tertiary); + font-size: 0.75rem; + padding-bottom: 100px; +} + +.b-title { + background: var(--gradient-3); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.b-cat { + background: var(--gradient-4); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.b-date { + background: var(--gradient-5); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +[data-theme="night"] .b-title, [data-theme="night"] .b-cat, [data-theme="night"] .b-date { + text-shadow: 0 0 8px var(--accent-glow); } \ No newline at end of file diff --git a/js/about.js b/js/about.js index ed9b083..73a643f 100644 --- a/js/about.js +++ b/js/about.js @@ -117,20 +117,6 @@ class ThemeManager { =========================== */ class DataManager { constructor() { - // Fallback Data if APIs fail - this.defaults = { - repos: [ - {name: "yunxiao-LLM-reviewer", desc: "AI Code Reviewer based on LLM", stars: 9, url: "#"}, - {name: "hexo-theme-stellar", desc: "Comprehensive Hexo theme", stars: 5, url: "#"}, - {name: "Universal-IoT-Java", desc: "IoT Platform Demo", stars: 2, url: "#"} - ], - posts: [ - {title: "Vector Database Guide", date: "2025-01-02", cat: "Tech", url: "#"}, - {title: "Spring Boot 3.0 Features", date: "2024-12-30", cat: "Java", url: "#"}, - {title: "Microservices Patterns", date: "2024-12-28", cat: "Arch", url: "#"} - ], - user: { repos: 165, followers: 6, created: "2018-05-14" } - }; this.init(); } @@ -142,7 +128,7 @@ class DataManager { // 优先缓存 -> API -> 默认值 async fetchGithub() { const user = (window.SiteConfig?.github?.username) || 'listener-He'; - const cacheKey = (window.SiteConfig?.github?.cache?.cacheKey) || 'gh_data_v2'; + const cacheKey = (window.SiteConfig?.cacheKeys?.github?.key) || 'gh_data_v2'; const cached = JSON.parse(localStorage.getItem(cacheKey)); const now = Date.now(); @@ -160,8 +146,8 @@ class DataManager { fetch(`https://api.github.com/users/${user}/repos?sort=stars&per_page=100`) ]); - const userData = uRes.status === 'fulfilled' ? await uRes.value.json() : this.defaults.user; - let repoData = rRes.status === 'fulfilled' ? await rRes.value.json() : this.defaults.repos; + const userData = uRes.status === 'fulfilled' ? await uRes.value.json() : (window.SiteConfig?.defaults?.user); + let repoData = rRes.status === 'fulfilled' ? await rRes.value.json() : (window.SiteConfig?.defaults?.repos); // 过滤掉fork项目并按星数排序 if (Array.isArray(repoData)) { @@ -180,38 +166,39 @@ class DataManager { } catch (e) { console.warn("GH API Fail", e); - this.renderUser(this.defaults.user); - this.renderRepos(this.defaults.repos); + this.renderUser(window.SiteConfig?.defaults?.user); + this.renderRepos(window.SiteConfig?.defaults?.repos); } } renderUser(data) { - const years = new Date().getFullYear() - new Date(data.created_at || this.defaults.user.created).getFullYear(); + const years = new Date().getFullYear() - new Date(data.created_at || (window.SiteConfig?.defaults?.user?.created)).getFullYear(); $('#coding-years').text(years + "+"); - $('#github-repos').text(data.public_repos || this.defaults.user.repos); - $('#github-followers').text(data.followers || this.defaults.user.followers); + $('#github-repos').text(data.public_repos || (window.SiteConfig?.defaults?.user?.repos)); + $('#github-followers').text(data.followers || (window.SiteConfig?.defaults?.user?.followers)); } renderRepos(list) { - if(!Array.isArray(list)) list = this.defaults.repos; + if(!Array.isArray(list)) list = window.SiteConfig?.defaults?.repos; let html = ''; - list.slice(0, 5).forEach(repo => { + list.slice(0, 12).forEach(repo => { // Fix: API field compatibility const stars = repo.stargazers_count !== undefined ? repo.stargazers_count : (repo.stars || 0); const forks = repo.forks_count !== undefined ? repo.forks_count : (repo.forks || 0); const desc = repo.description || repo.desc || 'No description.'; const url = repo.html_url || repo.url || '#'; + const dShort = (desc || '').length > 120 ? (desc.slice(0, 117) + '...') : desc; html += `
- ${repo.name} + ${repo.name} ${stars} ${forks}
-
${desc}
+
${dShort}
`; }); $('#projects-container').html(html); @@ -220,7 +207,7 @@ class DataManager { // 从RSS获取博客文章 async fetchBlog() { const rssUrl = window.SiteConfig?.blog?.rssUrl || 'https://blog.hehouhui.cn/api/rss'; - const cacheKey = window.SiteConfig?.blog?.cache?.key || 'blog_data_v2'; + const cacheKey = (window.SiteConfig?.cacheKeys?.blog?.key) || 'blog_data_v2'; const cached = JSON.parse(localStorage.getItem(cacheKey)); const now = Date.now(); @@ -279,7 +266,7 @@ class DataManager { this.renderBlog(data); } catch (e2) { console.warn("Local JSON Fail", e2); - this.renderBlog(this.defaults.posts); + this.renderBlog(window.SiteConfig?.defaults?.posts); } } } @@ -371,10 +358,7 @@ class UIManager { const container = document.getElementById('tech-container'); if(!container) return; - const techStackRaw = window.SiteConfig?.techStack || [ - {name:'Java'},{name:'Spring'},{name:'Docker'},{name:'K8s'},{name:'Python'},{name:'Redis'}, - {name:'React'},{name:'Vue'},{name:'MySQL'},{name:'MongoDB'},{name:'Linux'},{name:'Git'} - ]; + const techStackRaw = window.SiteConfig?.techStack || []; const techStack = techStackRaw.map((item, idx) => { const name = item.name || ''; const hash = Array.from(name).reduce((a,c)=>a+c.charCodeAt(0),0); @@ -395,14 +379,10 @@ class UIManager { extendedTechStack.forEach((item, index) => { const el = document.createElement('span'); el.className = 'tech-tag-mobile'; - // 添加不同颜色的渐变类 - const colorClass = `tag-color-${(index % 5) + 1}`; + const colorClass = `tag-color-${item.gradientId || ((index % 10) + 1)}`; el.classList.add(colorClass); el.innerText = item.name; - // 确保只显示文字,没有背景和边框 - el.style.background = 'none'; el.style.border = 'none'; - el.style.color = 'transparent'; container.appendChild(el); }); } else { @@ -415,20 +395,16 @@ class UIManager { techStack.forEach((item, index) => { const el = document.createElement('a'); el.className = 'tech-tag-3d'; - // 添加不同颜色的渐变类 - const colorClass = `tag-color-${(index % 5) + 1}`; + const colorClass = `tag-color-${item.gradientId || ((index % 10) + 1)}`; el.classList.add(colorClass); el.innerText = item.name; - // 移除背景和边框样式,只保留文字 - el.style.background = 'none'; el.style.border = 'none'; - el.style.color = 'transparent'; container.appendChild(el); tags.push({ el, x:0, y:0, z:0 }); }); - // 增大球体半径以避免标签重叠 - let radius = 300; + // 动态半径,避免容器溢出 + let radius = Math.max(160, Math.min(container.offsetWidth, container.offsetHeight) / 2 - 24); const dtr = Math.PI/180; let lasta=1, lastb=1; let active=false, mouseX=0, mouseY=0; @@ -471,7 +447,8 @@ class UIManager { let rx2=rx1*cb + rz1*sb, ry2=ry1, rz2=rx1*-sb + rz1*cb; tag.x=rx2; tag.y=ry2; tag.z=rz2; - let scale = (tag.z + radius)/(2*radius) + 0.5; + let scale = (tag.z + radius)/(2*radius) + 0.45; + scale = Math.min(Math.max(scale, 0.7), 1.15); let opacity = (tag.z + radius)/(2*radius) + 0.2; tag.el.style.opacity = Math.min(Math.max(opacity, 0.1), 1); diff --git a/js/config.js b/js/config.js index 98c0418..f3a37fe 100644 --- a/js/config.js +++ b/js/config.js @@ -62,6 +62,12 @@ const SiteConfig = { expirationDays: 1 } }, + + // 通用缓存键与TTL(毫秒) + cacheKeys: { + github: { key: 'gh_data_v2', ttlMs: 3600000 }, + blog: { key: 'blog_data_v2', ttlMs: 3600000 } + }, techStack: [ { name: 'Java', category: 'core', weight: 5 }, @@ -103,6 +109,21 @@ const SiteConfig = { { name: 'ClickHouse', category: 'data', weight: 1 }, { name: 'Postgresql', category: 'data', weight: 1 } ], + + // 默认数据(当API或RSS不可用时使用) + defaults: { + repos: [ + {name: "yunxiao-LLM-reviewer", desc: "AI Code Reviewer based on LLM", stars: 9, url: "#"}, + {name: "hexo-theme-stellar", desc: "Comprehensive Hexo theme", stars: 5, url: "#"}, + {name: "Universal-IoT-Java", desc: "IoT Platform Demo", stars: 2, url: "#"} + ], + posts: [ + {title: "Vector Database Guide", date: "2025-01-02", cat: "Tech", url: "#"}, + {title: "Spring Boot 3.0 Features", date: "2024-12-30", cat: "Java", url: "#"}, + {title: "Microservices Patterns", date: "2024-12-28", cat: "Arch", url: "#"} + ], + user: { repos: 165, followers: 6, created: "2018-05-14" } + }, socialCards: { rings: [130, 180, 230], @@ -136,13 +157,26 @@ const SiteConfig = { }; if (Array.isArray(SiteConfig.techStack)) { - SiteConfig.techStack = SiteConfig.techStack.map((item, idx) => { + const categoryGradientMap = { + core: 7, + backend: 4, + data: 9, + ops: 10, + ai: 3 + }; + const vividSet = [1, 4, 7, 8]; + + SiteConfig.techStack = SiteConfig.techStack.map((item) => { const name = item.name || ''; const hash = Array.from(name).reduce((a, c) => a + c.charCodeAt(0), 0); - const gid = (item.gradientId && Number.isFinite(Number(item.gradientId))) - ? Math.max(1, Math.min(10, Number(item.gradientId))) - : (hash % 10) + 1; - return { ...item, gradientId: gid }; + if (item.gradientId && Number.isFinite(Number(item.gradientId))) { + return { ...item, gradientId: Math.max(1, Math.min(10, Number(item.gradientId))) }; + } + let base = categoryGradientMap[item.category] || ((hash % 10) + 1); + if (Number(item.weight) >= 5) { + base = vividSet[hash % vividSet.length]; + } + return { ...item, gradientId: base }; }); }