Initial commit: 重新出發
This commit is contained in:
BIN
avatar.png
Normal file
BIN
avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
66
config.js
Normal file
66
config.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* nudoragon / LCY94 Linktree Configuration
|
||||||
|
*
|
||||||
|
* 只需要修改這裡的內容,頁面就會自動更新。
|
||||||
|
*/
|
||||||
|
const CONFIG = {
|
||||||
|
profile: {
|
||||||
|
name: "nudoragon",
|
||||||
|
bio: "設計與開發的探索者 | 建立數位世界的連結",
|
||||||
|
avatar: "avatar.png", // 已從部落格擷取
|
||||||
|
copyrightYear: 2026
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
title: "個人部落格",
|
||||||
|
desc: "分享技術開發與生活紀錄",
|
||||||
|
url: "https://blog.nudoragon.com",
|
||||||
|
icon: "fas fa-blog",
|
||||||
|
delay: "0.1s",
|
||||||
|
category: "content",
|
||||||
|
visible: true,
|
||||||
|
order: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Gitea",
|
||||||
|
desc: "查看我的開源專案與代碼",
|
||||||
|
url: "https://code.nudoragon.com",
|
||||||
|
icon: "fas fa-code-branch",
|
||||||
|
delay: "0.2s",
|
||||||
|
category: "development",
|
||||||
|
visible: true,
|
||||||
|
order: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Stickers 模組",
|
||||||
|
desc: "我開發的貼圖服務系統",
|
||||||
|
url: "https://stickers.example.com",
|
||||||
|
icon: "fas fa-code",
|
||||||
|
delay: "0.3s",
|
||||||
|
category: "development",
|
||||||
|
visible: false,
|
||||||
|
order: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "聯絡我",
|
||||||
|
desc: "透過電子郵件與我聯繫",
|
||||||
|
url: "mailto:a@z.nudoragon.com",
|
||||||
|
icon: "fas fa-envelope",
|
||||||
|
delay: "0.4s",
|
||||||
|
category: "contact",
|
||||||
|
visible: true,
|
||||||
|
order: 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
socials: [
|
||||||
|
{ name: "Instagram", url: "https://www.instagram.com/nudoragon/", icon: "fab fa-instagram", visible: true, order: 1 },
|
||||||
|
{ name: "Threads", url: "https://www.threads.net/@nudoragon", icon: "fas fa-at", visible: true, order: 2, note: "使用 @ 符號替代" },
|
||||||
|
{ name: "Facebook", url: "https://www.facebook.com/nudoragon/", icon: "fab fa-facebook", visible: true, order: 3 },
|
||||||
|
{ name: "Twitter", url: "https://twitter.com/nudoragon", icon: "fab fa-twitter", visible: true, order: 4 },
|
||||||
|
{ name: "Bluesky", url: "https://bsky.app/profile/nudoragon", icon: "fas fa-cloud", visible: true, order: 5, note: "使用雲朵圖標替代" },
|
||||||
|
{ name: "Discord", url: "https://discord.gg/nHjUJJXGVG", icon: "fab fa-discord", visible: true, order: 6 },
|
||||||
|
{ name: "Line", url: "#", icon: "fab fa-line", visible: false, order: 7 },
|
||||||
|
{ name: "Telegram", url: "#", icon: "fab fa-telegram", visible: false, order: 8 },
|
||||||
|
{ name: "Mail", url: "mailto:a@z.nudoragon.com", icon: "fas fa-envelope", visible: true, order: 9 }
|
||||||
|
]
|
||||||
|
};
|
||||||
91
index.html
Normal file
91
index.html
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-TW">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>nudoragon | 個人連結</title>
|
||||||
|
<meta name="description" content="nudoragon 的個人品牌與社交連結入口。包含部落格、專案與聯絡資訊。">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<!-- Google Fonts -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Outfit:wght@400;600;800&display=swap"
|
||||||
|
rel="stylesheet">
|
||||||
|
<!-- Font Awesome -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="background-blobs">
|
||||||
|
<div class="blob blob-1"></div>
|
||||||
|
<div class="blob blob-2"></div>
|
||||||
|
<div class="blob blob-3"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main class="container">
|
||||||
|
<header class="profile animate-fade-in" id="profile-header">
|
||||||
|
<!-- Dynamically populated -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="links-container" id="links-container">
|
||||||
|
<!-- Dynamically populated -->
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer class="footer animate-fade-in" id="footer-section">
|
||||||
|
<div class="social-icons" id="social-icons">
|
||||||
|
<!-- Dynamically populated -->
|
||||||
|
</div>
|
||||||
|
<p class="copyright" id="copyright-text"></p>
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script src="config.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Render Profile
|
||||||
|
const header = document.getElementById('profile-header');
|
||||||
|
header.innerHTML = `
|
||||||
|
<div class="avatar-container">
|
||||||
|
<img src="${CONFIG.profile.avatar}" alt="${CONFIG.profile.name} Avatar" class="avatar">
|
||||||
|
<div class="avatar-ring"></div>
|
||||||
|
</div>
|
||||||
|
<h1 class="name">${CONFIG.profile.name}</h1>
|
||||||
|
<p class="bio">${CONFIG.profile.bio}</p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Render Links - 支援可見性和排序
|
||||||
|
const linksContainer = document.getElementById('links-container');
|
||||||
|
const visibleLinks = CONFIG.links
|
||||||
|
.filter(link => link.visible !== false)
|
||||||
|
.sort((a, b) => (a.order || 0) - (b.order || 0));
|
||||||
|
|
||||||
|
linksContainer.innerHTML = visibleLinks.map(link => `
|
||||||
|
<a href="${link.url}" class="link-card animate-slide-up" style="animation-delay: ${link.delay};" target="_blank" rel="noopener noreferrer">
|
||||||
|
<div class="link-icon"><i class="${link.icon}"></i></div>
|
||||||
|
<div class="link-content">
|
||||||
|
<span class="link-title">${link.title}</span>
|
||||||
|
<span class="link-desc">${link.desc}</span>
|
||||||
|
</div>
|
||||||
|
<div class="link-arrow"><i class="fas fa-chevron-right"></i></div>
|
||||||
|
</a>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
// Render Socials - 支援可見性和排序
|
||||||
|
const socialIcons = document.getElementById('social-icons');
|
||||||
|
const visibleSocials = CONFIG.socials
|
||||||
|
.filter(social => social.visible !== false)
|
||||||
|
.sort((a, b) => (a.order || 0) - (b.order || 0));
|
||||||
|
|
||||||
|
socialIcons.innerHTML = visibleSocials.map(social => `
|
||||||
|
<a href="${social.url}" title="${social.name}${social.note ? ' - ' + social.note : ''}" target="_blank" rel="noopener noreferrer"><i class="${social.icon}"></i></a>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
// Render Copyright
|
||||||
|
document.getElementById('copyright-text').innerHTML = `© ${CONFIG.profile.copyrightYear} ${CONFIG.profile.name}. All rights reserved.`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
297
style.css
Normal file
297
style.css
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
/* CSS Variables & Design Tokens */
|
||||||
|
:root {
|
||||||
|
--primary-color: #6366f1;
|
||||||
|
--accent-color: #a855f7;
|
||||||
|
--bg-dark: #0f172a;
|
||||||
|
--card-bg: rgba(30, 41, 59, 0.7);
|
||||||
|
--text-primary: #f8fafc;
|
||||||
|
--text-secondary: #94a3b8;
|
||||||
|
--glass-border: rgba(255, 255, 255, 0.1);
|
||||||
|
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base Reset */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background-color: var(--bg-dark);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.5;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Background Blobs */
|
||||||
|
.background-blobs {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.4;
|
||||||
|
animation: blob-float 20s infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob-1 {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
top: -100px;
|
||||||
|
left: -100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob-2 {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: var(--accent-color);
|
||||||
|
bottom: -50px;
|
||||||
|
right: -50px;
|
||||||
|
animation-delay: -5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob-3 {
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
background: #ec4899;
|
||||||
|
top: 40%;
|
||||||
|
left: 60%;
|
||||||
|
animation-delay: -10s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blob-float {
|
||||||
|
0% { transform: translate(0, 0) scale(1); }
|
||||||
|
100% { transform: translate(50px, 50px) scale(1.1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Container */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 580px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Profile Section */
|
||||||
|
.profile {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-container {
|
||||||
|
position: relative;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
margin: 0 auto 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 4px solid var(--glass-border);
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-ring {
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
left: -8px;
|
||||||
|
right: -8px;
|
||||||
|
bottom: -8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(45deg, var(--primary-color), var(--accent-color));
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 1;
|
||||||
|
animation: ring-pulse 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ring-pulse {
|
||||||
|
0% { transform: scale(1); opacity: 0.5; }
|
||||||
|
50% { transform: scale(1.05); opacity: 0.2; }
|
||||||
|
100% { transform: scale(1); opacity: 0.5; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-family: 'Outfit', sans-serif;
|
||||||
|
font-size: 2.2rem;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bio {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
max-width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links Section */
|
||||||
|
.links-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.2rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--card-bg);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid var(--glass-border);
|
||||||
|
border-radius: 1.2rem;
|
||||||
|
padding: 1.2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
transition: var(--transition);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card:hover {
|
||||||
|
transform: translateY(-5px) scale(1.02);
|
||||||
|
background: rgba(45, 55, 72, 0.8);
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 0.8rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-right: 1.2rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card:hover .link-icon {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-title {
|
||||||
|
display: block;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-desc {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-arrow {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card:hover .link-arrow {
|
||||||
|
transform: translateX(5px);
|
||||||
|
opacity: 1;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer Section */
|
||||||
|
.footer {
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons a {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 1.8rem;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons a:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations */
|
||||||
|
.animate-fade-in {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-in 1s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-up {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
animation: slide-up 0.8s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-up {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Adjustments */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
body {
|
||||||
|
padding: 1.5rem 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bio {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-icon {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user