feat(listing): portfolio-first archive, case-study hero, row action links

/posts/ and /zh/posts/ become hybrid: three fixed-slug flagship cards above the
complete year/month archive, with the flagship block collapsing (inert, h=0) as
soon as the reader filters. /categories/case-studies/ becomes a portfolio: compact
two-column hero with a 21:9 deterministic topology banner, flagship ordering from
lib/portfolio.ts instead of pubDate, and one measured pill per card.

Also fixes what the screenshot review turned up: ZH archive rows and category chips
were printing raw English slugs, the two chip strips were unlabelled and read as one
list with a duplicated 'devops', card meta rows broke rhythm past four tags, the nav
had no current-section indicator, and mobile title links were under the 44px tap
minimum. scripts/probe-layout.mjs is the repeatable gate: 72/72 page x viewport
checks and the collapse test.
This commit is contained in:
hoelee committed 2026-10-27 04:06:54 +08:00
1 parent 68771101ea
commit 041471d25e
17 files changed
+1632 -76

No files matched your search

+18 -4
View File
@@ -64,6 +64,20 @@ const switchLabel = isZh ? 'EN' : '中文';
const nav = isZh
? { blueprints: '系统蓝图', caseStudies: '工程案例', posts: '全部文章', about: '关于与合作' }
: { blueprints: 'Blueprints', caseStudies: 'Case Studies', posts: 'All Posts', about: 'Work With Me' };
// Which section is the reader in? Without this the four nav links looked identical on
// every page, so the new portfolio route had no visible "you are here".
const sectionPath = Astro.url.pathname.replace(/^\/zh(?=\/|$)/, '') || '/';
const inSection = {
blueprints: sectionPath.startsWith('/blueprints'),
caseStudies: sectionPath.startsWith('/categories/case-studies'),
posts:
(sectionPath.startsWith('/posts') ||
sectionPath.startsWith('/tags') ||
sectionPath.startsWith('/categories')) &&
!sectionPath.startsWith('/categories/case-studies'),
about: sectionPath.startsWith('/about') || sectionPath.startsWith('/work-with-me'),
};
---
<!doctype html>
@@ -184,10 +198,10 @@ const nav = isZh
whole group onto a second row (`flex-basis: 100%`) instead of letting
individual links wrap around the search / language / theme controls. */}
<ul class="nav-links">
<li><a class="nav-link" href={isZh ? '/zh/blueprints/' : '/blueprints/'}>{nav.blueprints}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/categories/case-studies/' : '/categories/case-studies/'}>{nav.caseStudies}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/posts/' : '/posts/'}>{nav.posts}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/about/' : '/about/'}>{nav.about}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/blueprints/' : '/blueprints/'} aria-current={inSection.blueprints ? 'page' : undefined}>{nav.blueprints}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/categories/case-studies/' : '/categories/case-studies/'} aria-current={inSection.caseStudies ? 'page' : undefined}>{nav.caseStudies}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/posts/' : '/posts/'} aria-current={inSection.posts ? 'page' : undefined}>{nav.posts}</a></li>
<li><a class="nav-link" href={isZh ? '/zh/about/' : '/about/'} aria-current={inSection.about ? 'page' : undefined}>{nav.about}</a></li>
</ul>
<button class="search-toggle" id="search-toggle" aria-label={isZh ? '搜索' : 'Search'}>
⌕ <span class="search-hint">{isZh ? '搜索' : 'Search'}</span><kbd class="search-key">/</kbd>