studynote/homepage/index.html
MikiVL 5e01c8df4a feat: 个人主页 + 部署配置(www.mikivl.online)
- vite.config.ts: 加 base: '/app/',App 部署在子路径
- server/index.ts: MODELS_FILE 支持环境变量覆盖(容器化写权限)
- homepage/index.html: 极简开发者风格个人主页(About/Projects/Skills/Contact)
- nginx/default.conf: 反向代理,SSE proxy_buffering off,SPA fallback
- docker-compose.yml: Nginx + Hono 容器编排,models_data volume 持久化
- deploy.sh: 一键本地构建 + rsync 上传 + 远端重启

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 01:27:39 +08:00

358 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="mikivl — 独立开发者,专注构建 AI 驱动的生产力工具" />
<title>mikivl — 开发项目</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0d0d11;
--bg-card: #13131a;
--bg-hover: #1a1a24;
--border: #22222e;
--text: #e2e2ec;
--muted: #7070a0;
--faint: #3a3a55;
--accent: #818cf8;
--accent2: #34d399;
--tag-bg: #1e1b4b;
--tag-text: #a5b4fc;
}
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--text);
font-family: 'SF Mono', 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
font-size: 14px;
line-height: 1.7;
-webkit-font-smoothing: antialiased;
}
/* ── Nav ── */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
display: flex; align-items: center; justify-content: space-between;
padding: 0 clamp(1.5rem, 5vw, 4rem);
height: 56px;
background: rgba(13,13,17,0.88);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border-bottom: 1px solid var(--border);
}
.nav-logo {
font-size: 1rem; font-weight: 700; color: var(--accent);
text-decoration: none; letter-spacing: -0.02em;
}
.nav-logo span { color: var(--muted); font-weight: 400; }
.nav-links { display: flex; gap: 2rem; list-style: none; }
.nav-links a {
color: var(--muted); text-decoration: none; font-size: 0.8rem;
letter-spacing: 0.06em; text-transform: uppercase;
transition: color 0.15s;
}
.nav-links a:hover { color: var(--text); }
/* ── Layout ── */
main { max-width: 860px; margin: 0 auto; padding: 0 clamp(1.5rem, 5vw, 2rem); }
section { padding: 6rem 0 2rem; }
section:first-of-type { padding-top: 9rem; }
/* ── Section label ── */
.section-label {
font-size: 0.72rem; letter-spacing: 0.15em; text-transform: uppercase;
color: var(--accent); margin-bottom: 0.5rem;
}
h2 {
font-size: clamp(1.4rem, 3vw, 1.9rem); font-weight: 700;
color: var(--text); margin-bottom: 1.75rem; letter-spacing: -0.03em;
}
/* ── Hero ── */
.hero-greeting {
font-size: 0.85rem; color: var(--accent2); margin-bottom: 0.75rem;
letter-spacing: 0.08em;
}
.hero-name {
font-size: clamp(2.2rem, 7vw, 3.6rem); font-weight: 800;
color: var(--text); letter-spacing: -0.04em; line-height: 1.05;
margin-bottom: 1.25rem;
}
.hero-name em { color: var(--accent); font-style: normal; }
.hero-desc {
font-size: 0.95rem; color: var(--muted); max-width: 500px;
line-height: 1.85; margin-bottom: 2.25rem;
font-family: system-ui, -apple-system, sans-serif;
}
.hero-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.btn {
display: inline-flex; align-items: center; gap: 0.45rem;
padding: 0.55rem 1.1rem;
border-radius: 6px; font-size: 0.82rem;
text-decoration: none; transition: all 0.15s;
font-family: inherit;
}
.btn-primary {
background: var(--accent); color: #0d0d11; border: 1px solid var(--accent);
font-weight: 600;
}
.btn-primary:hover { background: #a5b4fc; border-color: #a5b4fc; }
.btn-ghost {
background: transparent; color: var(--muted); border: 1px solid var(--border);
}
.btn-ghost:hover { border-color: var(--faint); color: var(--text); background: var(--bg-hover); }
/* ── Divider ── */
.divider { border: none; border-top: 1px solid var(--border); margin: 0; }
/* ── Projects ── */
.projects-grid { display: grid; gap: 1rem; }
.project-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1.5rem 1.6rem;
text-decoration: none;
display: block;
transition: border-color 0.15s, background 0.15s, transform 0.18s;
position: relative; overflow: hidden;
}
.project-card::before {
content: '';
position: absolute; top: 0; left: 0; right: 0; height: 2px;
background: linear-gradient(90deg, var(--accent), var(--accent2));
opacity: 0; transition: opacity 0.2s;
}
.project-card:hover {
border-color: var(--faint);
background: var(--bg-hover);
transform: translateY(-2px);
}
.project-card:hover::before { opacity: 1; }
.project-header {
display: flex; align-items: flex-start;
justify-content: space-between; gap: 1rem; margin-bottom: 0.5rem;
}
.project-name {
font-size: 1rem; font-weight: 700; color: var(--text);
letter-spacing: -0.02em;
}
.project-status {
font-size: 0.7rem; padding: 0.15rem 0.5rem;
border-radius: 20px; letter-spacing: 0.05em;
background: #052e16; color: #6ee7b7;
white-space: nowrap; margin-top: 2px;
}
.project-desc {
font-size: 0.85rem; color: var(--muted); line-height: 1.75;
font-family: system-ui, -apple-system, sans-serif;
margin-bottom: 1.1rem;
}
.project-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tag {
font-size: 0.7rem; padding: 0.18rem 0.5rem;
background: var(--tag-bg); color: var(--tag-text);
border-radius: 4px; letter-spacing: 0.03em;
}
.tag.green { background: #052e16; color: #6ee7b7; }
.tag.purple { background: #2e1065; color: #c4b5fd; }
.tag.orange { background: #431407; color: #fdba74; }
.tag.sky { background: #082f49; color: #7dd3fc; }
/* ── Skills ── */
.skills-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
gap: 1rem;
}
.skill-group {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1.1rem 1.2rem;
}
.skill-group-title {
font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase;
color: var(--accent); margin-bottom: 0.8rem;
}
.skill-list { list-style: none; }
.skill-list li {
font-size: 0.83rem; color: var(--muted); padding: 0.22rem 0;
display: flex; align-items: center; gap: 0.5rem;
}
.skill-list li::before { content: '▸'; color: var(--faint); font-size: 0.65rem; }
/* ── Contact ── */
.contact-links { display: flex; flex-direction: column; gap: 0.9rem; }
.contact-link {
display: inline-flex; align-items: center; gap: 0.75rem;
color: var(--muted); text-decoration: none; font-size: 0.88rem;
transition: color 0.15s; width: fit-content;
}
.contact-link:hover { color: var(--accent); }
.contact-icon { color: var(--faint); font-size: 1rem; width: 1.2rem; text-align: center; }
/* ── Footer ── */
footer {
border-top: 1px solid var(--border);
padding: 2rem clamp(1.5rem, 5vw, 4rem);
text-align: center;
color: var(--faint); font-size: 0.75rem;
margin-top: 4rem;
}
/* ── Cursor blink ── */
.cursor {
display: inline-block; width: 3px; height: 0.85em;
background: var(--accent); margin-left: 1px;
vertical-align: text-bottom; border-radius: 1px;
animation: blink 1.1s step-end infinite;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
/* ── Responsive ── */
@media (max-width: 600px) {
.nav-links { gap: 1.2rem; }
.skills-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 400px) {
.nav-links li:nth-child(3), .nav-links li:nth-child(4) { display: none; }
}
</style>
</head>
<body>
<nav>
<a class="nav-logo" href="#about">mikivl<span>.online</span></a>
<ul class="nav-links">
<li><a href="#about">about</a></li>
<li><a href="#projects">projects</a></li>
<li><a href="#skills">skills</a></li>
<li><a href="#contact">contact</a></li>
</ul>
</nav>
<main>
<!-- About -->
<section id="about">
<p class="hero-greeting">// hello, world</p>
<h1 class="hero-name">mikivl<em>.</em><span class="cursor"></span></h1>
<p class="hero-desc">
独立开发者,专注于构建 AI 驱动的生产力工具。<br>
喜欢探索 AI 与实用工具的交叉地带,用代码解决真实问题。
</p>
<div class="hero-actions">
<a class="btn btn-primary" href="#projects">查看项目 →</a>
<a class="btn btn-ghost" href="#contact">联系我</a>
</div>
</section>
<hr class="divider" />
<!-- Projects -->
<section id="projects">
<p class="section-label">// projects</p>
<h2>开发项目</h2>
<div class="projects-grid">
<a class="project-card" href="/app/" target="_blank" rel="noopener">
<div class="project-header">
<span class="project-name">读书笔记 App</span>
<span class="project-status">● 上线中</span>
</div>
<p class="project-desc">
AI 驱动的个人读书笔记工具。富文本编辑器,支持 AI 续写、润色、摘要、翻译,
多文件夹管理标签系统导入导出MD / DOCX / PDF数据本地存储隐私优先。
</p>
<div class="project-tags">
<span class="tag">React 19</span>
<span class="tag">TypeScript</span>
<span class="tag sky">Vite</span>
<span class="tag green">Hono</span>
<span class="tag purple">Claude API</span>
<span class="tag orange">TipTap</span>
<span class="tag">IndexedDB</span>
</div>
</a>
</div>
</section>
<hr class="divider" />
<!-- Skills -->
<section id="skills">
<p class="section-label">// skills</p>
<h2>技术栈</h2>
<div class="skills-grid">
<div class="skill-group">
<p class="skill-group-title">Frontend</p>
<ul class="skill-list">
<li>React / TypeScript</li>
<li>Vite / TailwindCSS</li>
<li>TipTap / ProseMirror</li>
<li>Framer Motion</li>
</ul>
</div>
<div class="skill-group">
<p class="skill-group-title">Backend</p>
<ul class="skill-list">
<li>Node.js / Hono</li>
<li>REST / SSE</li>
<li>Docker / Nginx</li>
<li>Linux / VPS</li>
</ul>
</div>
<div class="skill-group">
<p class="skill-group-title">AI</p>
<ul class="skill-list">
<li>Anthropic Claude API</li>
<li>Prompt Engineering</li>
<li>Streaming (SSE)</li>
<li>RAG / Embeddings</li>
</ul>
</div>
<div class="skill-group">
<p class="skill-group-title">Tooling</p>
<ul class="skill-list">
<li>Git / GitHub</li>
<li>Vitest / ESLint</li>
<li>Claude Code</li>
<li>SSH / rsync</li>
</ul>
</div>
</div>
</section>
<hr class="divider" />
<!-- Contact -->
<section id="contact">
<p class="section-label">// contact</p>
<h2>联系方式</h2>
<div class="contact-links">
<a class="contact-link" href="https://github.com/MikiVL" target="_blank" rel="noopener">
<span class="contact-icon"></span>
github.com/MikiVL
</a>
<a class="contact-link" href="mailto:hi@mikivl.online">
<span class="contact-icon">@</span>
hi@mikivl.online
</a>
</div>
</section>
</main>
<footer>
<p>© 2026 mikivl · built with ♥ and <a href="https://claude.ai/code" style="color:var(--faint);text-decoration:none;" target="_blank">Claude Code</a></p>
</footer>
</body>
</html>