feat(hero): refactor home hero to 2-column desktop grid and mobile visual flow
Deploy / build (push) Successful in 24s

This commit is contained in:
hoelee committed 2026-10-26 10:16:14 +08:00
1 parent 9fd02b8320
commit d5a0fc089d
3 files changed
+118 -64

No files matched your search

+30 -28
View File
@@ -32,37 +32,39 @@ const featuredMetrics: Record<string, string> = {
<BaseLayout title={SITE.title} description={SITE.description} altLocaleUrl={`${SITE.url}/zh/`}>
<section class="hero">
<div class="hero-id">
<picture>
<source srcset={SITE.photo.smallWebp} type="image/webp" />
<img
class="hero-photo"
src={SITE.photo.small}
alt={`${SITE.author} (${SITE.handle})`}
width="72"
height="72"
decoding="async"
/>
</picture>
<h1>{SITE.author} — full-stack developer &amp; DevOps engineer</h1>
<div class="hero-content">
<div class="hero-id">
<picture>
<source srcset={SITE.photo.smallWebp} type="image/webp" />
<img
class="hero-photo"
src={SITE.photo.small}
alt={`${SITE.author} (${SITE.handle})`}
width="72"
height="72"
decoding="async"
/>
</picture>
<h1>{SITE.author} — full-stack developer &amp; DevOps engineer</h1>
</div>
<p class="hero-sub">
I build and operate production web systems — from the code down to the servers.
<strong>162 containers across three self-managed hosts</strong> run client sites, a mail
platform, CI/CD, workflow automation and this blog. I write up what broke, what the
evidence said, and how I fixed it.
</p>
<p class="hero-cta">
<a class="btn btn-primary" href="#featured">Read the engineering case studies ↓</a>
<a class="btn" href="/about/">Hiring? Profile &amp; stack →</a>
<a class="btn" href={SITE.website} target="_blank" rel="noopener">Malaysian SME? How I work ↗</a>
</p>
<p class="hero-note">
{posts.length} posts in English and 中文 · <a href="/rss.xml">RSS</a>
</p>
</div>
<p class="hero-sub">
I build and operate production web systems — from the code down to the servers.
<strong>162 containers across three self-managed hosts</strong> run client sites, a mail
platform, CI/CD, workflow automation and this blog. I write up what broke, what the
evidence said, and how I fixed it.
</p>
<p class="hero-cta">
<a class="btn btn-primary" href="#featured">Read the engineering case studies ↓</a>
<a class="btn" href="/about/">Hiring? Profile &amp; stack →</a>
<a class="btn" href={SITE.website} target="_blank" rel="noopener">Malaysian SME? How I work ↗</a>
</p>
<p class="hero-note">
{posts.length} posts in English and 中文 · <a href="/rss.xml">RSS</a>
</p>
<div class="hero-banner-card">
<picture>
<source srcset="/images/hero-banner-2x.webp 2048w, /images/hero-banner.webp 1024w" sizes="(max-width: 1120px) 100vw, 1120px" type="image/webp" />
<source srcset="/images/hero-banner-2x.webp 2048w, /images/hero-banner.webp 1024w" sizes="(max-width: 900px) 100vw, 480px" type="image/webp" />
<img
class="hero-banner-img"
src="/images/hero-banner.jpg"
+27 -25
View File
@@ -36,34 +36,36 @@ const featuredMetrics: Record<string, string> = {
altLocaleUrl={`${SITE.url}/`}
>
<section class="hero">
<div class="hero-id">
<picture>
<source srcset={SITE.photo.smallWebp} type="image/webp" />
<img
class="hero-photo"
src={SITE.photo.small}
alt={`${SITE.author}(${SITE.handle})`}
width="72"
height="72"
decoding="async"
/>
</picture>
<h1>{SITE.author} —— 全栈开发者兼 DevOps 工程师</h1>
<div class="hero-content">
<div class="hero-id">
<picture>
<source srcset={SITE.photo.smallWebp} type="image/webp" />
<img
class="hero-photo"
src={SITE.photo.small}
alt={`${SITE.author}(${SITE.handle})`}
width="72"
height="72"
decoding="async"
/>
</picture>
<h1>{SITE.author} —— 全栈开发者兼 DevOps 工程师</h1>
</div>
<p class="hero-sub">
从代码到服务器,生产环境的 Web 系统我自己从头做到尾。<strong>三台自管服务器上跑着 162 个容器</strong>:客户站点、邮件平台、CI/CD、流程自动化,还有这个博客。这里写的是「坏了什么、证据在哪、怎么修好」。
</p>
<p class="hero-cta">
<a class="btn btn-primary" href="#featured">先看工程案例 ↓</a>
<a class="btn" href="/zh/about/">招聘方:技术栈与履历 →</a>
<a class="btn" href={SITE.website} target="_blank" rel="noopener">中小企业:合作方式 ↗</a>
</p>
<p class="hero-note">
共 {posts.length} 篇中文文章 · <a href="/">English</a> · <a href="/rss.xml">RSS</a>
</p>
</div>
<p class="hero-sub">
从代码到服务器,生产环境的 Web 系统我自己从头做到尾。<strong>三台自管服务器上跑着 162 个容器</strong>:客户站点、邮件平台、CI/CD、流程自动化,还有这个博客。这里写的是「坏了什么、证据在哪、怎么修好」。
</p>
<p class="hero-cta">
<a class="btn btn-primary" href="#featured">先看工程案例 ↓</a>
<a class="btn" href="/zh/about/">招聘方:技术栈与履历 →</a>
<a class="btn" href={SITE.website} target="_blank" rel="noopener">中小企业:合作方式 ↗</a>
</p>
<p class="hero-note">
共 {posts.length} 篇中文文章 · <a href="/">English</a> · <a href="/rss.xml">RSS</a>
</p>
<div class="hero-banner-card">
<picture>
<source srcset="/images/hero-banner-2x.webp 2048w, /images/hero-banner.webp 1024w" sizes="(max-width: 1120px) 100vw, 1120px" type="image/webp" />
<source srcset="/images/hero-banner-2x.webp 2048w, /images/hero-banner.webp 1024w" sizes="(max-width: 900px) 100vw, 480px" type="image/webp" />
<img
class="hero-banner-img"
src="/images/hero-banner.jpg"
+61 -11
View File
@@ -501,8 +501,8 @@ pre code {
/* ---------- Home hero ---------- */
.hero {
margin: 0.5rem 0 2.5rem;
padding-bottom: 1.5rem;
margin: 0.5rem 0 2.2rem;
padding-bottom: 1.75rem;
border-bottom: 1px solid var(--border);
}
.hero-id { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem; }
@@ -516,13 +516,13 @@ pre code {
flex-shrink: 0;
display: block;
}
.hero h1 { margin: 0; }
.hero-sub { font-size: 1.05rem; color: var(--muted); max-width: 62ch; }
.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; }
.hero-cta {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
margin: 1.25rem 0 0.75rem;
margin: 1.15rem 0 0.75rem;
}
.btn {
display: inline-block;
@@ -538,17 +538,15 @@ pre code {
.btn-primary { border-color: var(--brand); color: var(--brand); }
.hero-note { font-size: 0.82rem; color: var(--faint); margin: 0; }
.hero-banner-card {
margin: 1.75rem 0 0.5rem;
border-radius: var(--radius);
overflow: hidden;
border: 1px solid var(--border);
border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2));
background: var(--surface);
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
transition: border-color 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.15);
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 8px 32px rgba(0, 0, 0, 0.2);
box-shadow: 0 14px 36px -10px rgba(0, 0, 0, 0.25);
}
.hero-banner-img {
width: 100%;
@@ -558,6 +556,58 @@ pre code {
object-fit: cover;
}
/* Desktop: 2-column grid layout (>= 900px) */
@media (min-width: 900px) {
.hero {
display: grid;
grid-template-columns: 1.15fr 0.85fr;
gap: 2.5rem;
align-items: center;
}
.hero-content {
display: flex;
flex-direction: column;
min-width: 0;
}
.hero-banner-card {
border-radius: 12px;
margin: 0;
}
}
/* Mobile & Tablet: single-column visual flow (< 900px) */
@media (max-width: 899px) {
.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;
}
.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;
}
}
/* ---------- Featured 2x2 Cyber-Bento Grid ---------- */
.featured-bento-grid {
display: grid;