Headline outcomes:
- Feature parity with Stack/PaperMod on Tier A polish: breadcrumbs
(+BreadcrumbList JSON-LD), prev/next post navigation (rel=prev/next),
language switcher UI (gated on hugo.IsMultilingual), code-copy button
polish, <details> styling.
- Per-page-kind CSS bundles: core loads everywhere; home/single/archive/
search bundles load only where needed. Frees ~1 KB gz from non-post
pages. code-copy.js gated to post pages.
- Lighthouse-relevant network polish: Pagefind UI CSS preload-swap,
conditional preconnect to giscus.app on comment-enabled posts,
hreflang alternates on multilingual sites, <meta name=theme-color>
light/dark variants, aria-pressed SSR-rendered on theme-toggle.
- WCAG AA contrast: --tsuki-fg-subtle darkened to #6b6b6b (light); was
3.54:1 on bg, now 5:1. Pagination disabled uses --tsuki-fg-muted
without opacity compound. Header tap targets bumped to 40×40; pagination
to 44×44.
- i18n: full i18n/en.yml mirror (~50 keys); render-heading aria-label
i18n-driven via linkToSection key; new keys for breadcrumb*, prevPost,
nextPost, copyCode, copiedCode.
- Discovery: /llm.txt output format (llmstxt.org) on home; Speculation
Rules opt-in via params.prefetch.enable.
- <html lang> fallback: site.Language.LanguageCode → Lang → "en"
(was hard-coded "vi").
Per-kind bundle gz sizes on demo: home 3673 / post 4167 / list 2897 /
archives 3363 / search 3179 B (all under 4200 B cap).
Plan: plans/260510-0144-tsuki-v0.3.0/
- search/list.html: Pagefind UI container + module init with full vi
i18n strings; loads /pagefind/pagefind-ui.{css,js} from generated dir
- search-button.html in header, gated by params.search.enable
- comments.html for Giscus, opt-in via params.comments.giscus.enable;
reads repo/repoId/category/categoryId/mapping/theme/lang from params
- giscus-theme.js: MutationObserver on data-theme, postMessage iframe
on toggle so Giscus theme stays in sync with site
- search.css: header-actions row, search button, Pagefind UI tokens
mapped to tsuki design tokens
- comments.css: min-block-size on iframe to prevent layout shift
- exampleSite/hugo.yaml: commented giscus params block as docs
- i18n/vi.yml: Pagefind UI strings (clear, loadMore, zeroResults...)
Both features no-op when disabled. CSS bundle 3.5 KB gz (budget 15).
- post/list.html paginated section list with post-card
- pagination.html partial (renders only when >1 page)
- _default/taxonomy.html for term lists (/tags/, /categories/) with counts
- taxonomy/term.html for single term pages (paginated posts)
- archives/list.html + archive-group.html: year/month grouped flat list
- exampleSite: 4 new posts across 2025-2026, 2 categories, 4 tags, archive index
Modern Hugo 0.146+ template naming: term.html resolved via taxonomy/
path (Hugo 0.154 lookup ignores _default/term.html).