diff --git a/src/pages/index.astro b/src/pages/index.astro index 1cae67b..fb5f8e0 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -32,7 +32,7 @@ const featuredMetrics: Record = {
-
+
@@ -53,32 +53,90 @@ const featuredMetrics: Record = { platform, CI/CD, workflow automation and this blog. I write up what broke, what the evidence said, and how I fixed it.

-

+

+
+ +
+ + +
+
+
162
+
Containers in Prod
+
+
+
3 Hosts
+
Unraid · Synology · VPS
+
+
+
78
+
Compose Stacks
+
+
+
91
+
Bilingual Write-ups
+
+
+
+ + -
- - - From Code to Production — Systems Architecture & DevOps Infrastructure Ecosystem - -
+ +
+ + From Code to Production — Systems Architecture & DevOps Infrastructure Ecosystem +
+ From Code to Production — Systems Architecture & DevOps Infrastructure + ESC / Click outside to close +
+
+
+
-

Latest posts

+
+

Latest posts

+ +
{posts.length === 0 ? (

No posts yet — check back soon.

) : ( diff --git a/src/pages/zh/index.astro b/src/pages/zh/index.astro index dd2dcac..f575db2 100644 --- a/src/pages/zh/index.astro +++ b/src/pages/zh/index.astro @@ -36,7 +36,7 @@ const featuredMetrics: Record = { altLocaleUrl={`${SITE.url}/`} >
-
+
@@ -54,32 +54,90 @@ const featuredMetrics: Record = {

从代码到服务器,生产环境的 Web 系统我自己从头做到尾。三台自管服务器上跑着 162 个容器:客户站点、邮件平台、CI/CD、流程自动化,还有这个博客。这里写的是「坏了什么、证据在哪、怎么修好」。

-

+

+ 技术栈: + Docker + 自托管 + n8n + 本地 GPU AI + Python + PHP + 安全防护 +
+
+ +
+ + +
+
+
162
+
生产环境容器
+
+
+
3 台宿主
+
Unraid · 群晖 · VPS
+
+
+
78
+
Compose 编排栈
+
+
+
91 篇
+
中英双语实战复盘
+
+
+
+ + -
- - - 从代码到生产环境 —— 系统架构与 DevOps 运维生态图 - -
+ +
+ + 从代码到生产环境 —— 系统架构与 DevOps 运维生态图 +
+ 从代码到生产环境 —— 系统架构与 DevOps 运维生态图 + ESC / 点击外部关闭 +
+
+
+
-

最新文章

+ {posts.length === 0 ? (

中文文章即将发布,敬请期待。

) : ( diff --git a/src/styles/global.css b/src/styles/global.css index 925d648..6fc2278 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -518,35 +518,105 @@ pre code { } .hero h1 { margin: 0; font-size: 1.85rem; line-height: 1.25; } .hero-sub { font-size: 1.02rem; color: var(--muted); max-width: 62ch; margin: 0 0 0.25rem; line-height: 1.6; } + +/* Tech Stack Pills */ +.hero-pills { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.45rem; + margin: 0.85rem 0 0; +} +.hero-pills-label { + font-size: 0.78rem; + color: var(--faint); + font-family: var(--font-mono); + margin-right: 0.15rem; +} +.tech-pill { + display: inline-flex; + align-items: center; + font-size: 0.78rem; + font-family: var(--font-mono); + color: var(--muted); + background: var(--surface); + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.18rem 0.65rem; + text-decoration: none; + transition: all 0.2s ease; +} +.tech-pill:hover { + color: var(--brand); + border-color: var(--brand); + background: color-mix(in srgb, var(--brand) 10%, transparent); +} + +/* CTA buttons & RSS note */ .hero-cta { display: flex; flex-wrap: wrap; - gap: 0.6rem; - margin: 1.15rem 0 0.75rem; + gap: 0.75rem; + margin: 0; } .btn { - display: inline-block; - font-size: 0.9rem; + display: inline-flex; + align-items: center; + font-size: 0.88rem; color: var(--ink); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); - padding: 0.5rem 0.85rem; + padding: 0.52rem 0.95rem; text-decoration: none; + transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease; +} +.btn:hover { + border-color: var(--brand); + color: var(--brand); +} +.btn-primary { + background: var(--brand); + color: #ffffff !important; + border-color: var(--brand); + font-weight: 600; + box-shadow: 0 2px 8px color-mix(in srgb, var(--brand) 30%, transparent); +} +.btn-primary:hover { + background: var(--brand-soft); + border-color: var(--brand-soft); + color: #ffffff !important; + transform: translateY(-1px); + box-shadow: 0 4px 14px color-mix(in srgb, var(--brand) 45%, transparent); } -.btn:hover { border-color: var(--brand); color: var(--brand); } -.btn-primary { border-color: var(--brand); color: var(--brand); } .hero-note { font-size: 0.82rem; color: var(--faint); margin: 0; } + +/* Visual block (Banner + Lightbox + Infra Stats Grid) */ +.hero-visual { + display: flex; + flex-direction: column; + gap: 0.75rem; + min-width: 0; +} .hero-banner-card { - overflow: hidden; + position: relative; + display: block; + width: 100%; + padding: 0; + margin: 0; border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2)); background: var(--surface); + border-radius: 12px; + overflow: hidden; box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.15); + cursor: zoom-in; + text-align: left; transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease; } .hero-banner-card:hover { border-color: color-mix(in srgb, var(--brand) 40%, var(--border)); box-shadow: 0 14px 36px -10px rgba(0, 0, 0, 0.25); + transform: translateY(-1px); } .hero-banner-img { width: 100%; @@ -555,59 +625,219 @@ pre code { display: block; object-fit: cover; } +.hero-banner-zoom-badge { + position: absolute; + bottom: 0.65rem; + right: 0.65rem; + z-index: 2; + padding: 0.25rem 0.6rem; + font-size: 0.75rem; + font-weight: 500; + color: #ffffff; + background: rgba(15, 23, 42, 0.82); + backdrop-filter: blur(6px); + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 6px; + pointer-events: none; + transition: background 0.2s ease, border-color 0.2s ease; +} +.hero-banner-card:hover .hero-banner-zoom-badge { + background: var(--brand); + border-color: rgba(255, 255, 255, 0.35); +} -/* Desktop: 2-column grid layout (>= 900px) */ -@media (min-width: 900px) { +/* 4-Stat Infra Grid */ +.hero-infra-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0.75rem; +} +.infra-stat-card { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 0.7rem 0.9rem; + display: flex; + flex-direction: column; + justify-content: center; + transition: border-color 0.2s ease, background 0.2s ease; +} +.infra-stat-card:hover { + border-color: color-mix(in srgb, var(--brand) 35%, var(--border)); +} +.infra-stat-val { + font-size: 1.3rem; + font-weight: 700; + line-height: 1.2; + color: var(--ink); + letter-spacing: -0.02em; + font-family: var(--font-mono); +} +.infra-stat-label { + font-size: 0.76rem; + color: var(--muted); + margin-top: 0.2rem; + line-height: 1.35; +} + +/* Architecture Lightbox Dialog */ +.arch-lightbox { + border: none; + border-radius: 12px; + background: transparent; + padding: 0; + max-width: 94vw; + max-height: 94vh; + margin: auto; + box-shadow: 0 25px 60px rgba(0, 0, 0, 0.6); + outline: none; +} +.arch-lightbox::backdrop { + background: rgba(0, 0, 0, 0.85); + backdrop-filter: blur(8px); +} +.arch-lightbox-inner { + position: relative; + display: flex; + flex-direction: column; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 12px; + overflow: hidden; +} +.arch-lightbox-close { + position: absolute; + top: 0.75rem; + right: 0.75rem; + z-index: 2; + width: 36px; + height: 36px; + border-radius: 50%; + border: 1px solid var(--border); + background: rgba(0, 0, 0, 0.6); + color: #fff; + font-size: 1.4rem; + line-height: 1; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background 0.2s, transform 0.15s; +} +.arch-lightbox-close:hover { + background: var(--brand); + transform: scale(1.05); +} +.arch-lightbox img { + width: 100%; + max-height: 82vh; + object-fit: contain; + display: block; +} +.arch-lightbox-caption { + display: flex; + justify-content: space-between; + align-items: center; + gap: 1rem; + padding: 0.65rem 1rem; + font-size: 0.82rem; + color: var(--muted); + border-top: 1px solid var(--border); + background: var(--paper); +} +.arch-lightbox-hint { + font-size: 0.75rem; + color: var(--faint); +} + +/* Desktop layout: >= 960px */ +@media (min-width: 960px) { .hero { display: grid; - grid-template-columns: 1.15fr 0.85fr; - gap: 2.5rem; - align-items: center; + grid-template-columns: 1fr 1fr; + grid-template-rows: auto 1fr; + grid-template-areas: + "intro visual" + "actions visual"; + gap: 1.5rem 2rem; + align-items: stretch; } - .hero-content { + .hero-intro { + grid-area: intro; + } + .hero-actions { + grid-area: actions; display: flex; flex-direction: column; - min-width: 0; + justify-content: flex-end; + gap: 0.75rem; } - .hero-banner-card { - border-radius: 12px; - margin: 0; + .hero-visual { + grid-area: visual; } } -/* Mobile & Tablet: single-column visual flow (< 900px) */ -@media (max-width: 899px) { +/* Mobile & Tablet: < 960px */ +@media (max-width: 959px) { .hero { display: flex; flex-direction: column; - gap: 0; - } - .hero-content { - display: contents; - } - .hero-id { - order: 1; - margin-bottom: 0.75rem; - } - .hero-sub { - order: 2; - margin-bottom: 0; + gap: 1.25rem; } .hero-banner-card { - order: 3; - margin: 1rem 0; border-radius: 8px; } - .hero-cta { - order: 4; - margin: 0 0 0.75rem; - } - .hero-note { - order: 5; - margin: 0; + .hero-actions { + display: flex; + flex-direction: column; + gap: 0.75rem; } } +/* Section Header with Category Shortcuts */ +.section-head-with-nav { + display: flex; + align-items: baseline; + justify-content: space-between; + flex-wrap: wrap; + gap: 0.75rem 1rem; + margin: 2.25rem 0 0.75rem; +} +.section-head-with-nav h2 { + margin: 0; +} +.section-nav-pills { + display: inline-flex; + flex-wrap: wrap; + gap: 0.4rem; + align-items: center; +} +.section-nav-pill { + font-size: 0.76rem; + font-family: var(--font-mono); + color: var(--muted); + background: var(--surface); + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.15rem 0.6rem; + text-decoration: none; + transition: all 0.2s ease; +} +.section-nav-pill:hover { + color: var(--brand); + border-color: var(--brand); + background: color-mix(in srgb, var(--brand) 10%, transparent); +} +.section-nav-all { + color: var(--brand); + border-color: color-mix(in srgb, var(--brand) 30%, var(--border)); +} +.section-nav-all:hover { + background: var(--brand); + color: #ffffff; + border-color: var(--brand); +} + /* ---------- Featured 2x2 Cyber-Bento Grid ---------- */ .featured-bento-grid { display: grid;