{{- /* Homepage DayPage Redesign — Bear / 熊 Mirrors the design prototype: Hero + AI Chat + Posts + Books + Projects + Travel + Subscribe + Footer Lang: en (default) / zh — detected from .Lang */ -}} {{- $isZh := eq .Lang "zh" -}} {{- $lang := .Lang -}} {{- $d := site.Data.homepage -}}
{{/* ── Hero ─────────────────────────────────────────── */}}
{{/* Ambient 3D field — sits behind both columns, purely decorative. Stays empty (transparent) on phones / reduced-motion / no-WebGL. */}}
{{ if $isZh }}在线 · 漫游中{{ else }}Online · Roaming{{ end }}

{{ $d.hero.nameEn }} {{ $d.hero.nameLast }}. {{ if $isZh }}{{ $d.hero.nameZh }} · {{ $d.hero.nickZh }}{{ else }}熊 · {{ $d.hero.nickZh }}{{ end }}

{{- range $i, $tag := $d.hero.tagline }}{{ if $i }}/{{ end }}{{ $tag }}{{ end }}

{{ if $isZh }}{{ $d.hero.bioZh | safeHTML }}{{ else }}{{ $d.hero.bioEn | safeHTML }}{{ end }}

{{- if site.Params.socialIcons }}
{{- range site.Params.socialIcons }} {{- if eq .name "wechat" }} {{- $qrSrc := .qr | relURL -}} {{- with resources.Get "wechat.jpg" -}} {{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) -}} {{- if and hugo.IsExtended $prod -}} {{- $qrSrc = (.Resize "440x webp q88").RelPermalink -}} {{- else -}} {{- $qrSrc = (.Resize "440x q88").RelPermalink -}} {{- end -}} {{- end -}} {{- else }} {{ partial "svg.html" . }} {{- end }} {{- end }}
{{- end }}
{{- $bubblesENData := slice -}} {{- $angles := slice -90 -30 30 90 150 210 -}} {{- $dists := slice 1.0 1.05 0.95 1.0 1.05 0.95 -}} {{- range $i, $text := $d.ai.bubblesEn -}} {{- $bubblesENData = $bubblesENData | append (dict "text" $text "angle" (index $angles $i) "dist" (index $dists $i)) -}} {{- end -}} {{- $bubblesZHData := slice -}} {{- range $i, $text := $d.ai.bubblesZh -}} {{- $bubblesZHData = $bubblesZHData | append (dict "text" $text "angle" (index $angles $i) "dist" (index $dists $i)) -}} {{- end -}}
{{/* Persistent 3D stage: the Three.js canvas lives here and is NEVER torn down on orbit↔chat swaps. orbit and chat are DOM layers rendered into #hp-bear-layer on top of it, so the same AI orb flows continuously between states (recedes behind the chat glass rather than disappearing). aria-hidden: purely ambient. */}}
{{/* ── Posts ───────────────────────────────────────── */}}
01

{{ if $isZh }}正在写的{{ else }}Writing{{ end }}{{ if $isZh }}{{ else }}文章{{ end }}

{{ if $isZh }}所有文章{{ else }}All Posts{{ end }}
{{- $pages := (where (where site.RegularPages "Lang" $lang) "Section" "in" site.Params.mainSections).ByDate.Reverse }} {{- $featured := index $pages 0 }} {{- $recent := after 1 $pages | first 2 }} {{- $archive := after 3 $pages | first 4 }}
{{/* ── Books ──────────────────────────────────────── */}}
02

{{ if $isZh }}我的旅行书{{ else }}Field Notebooks{{ end }}{{ if $isZh }}{{ else }}游记{{ end }}

{{/* ── Projects ────────────────────────────────────── */}}
03

{{ if $isZh }}正在构建{{ else }}Building{{ end }}{{ if $isZh }}{{ else }}项目{{ end }}

GITHUB
{{- range $d.projects.repos }}
📦
{{ .org }}/{{ .name }}

{{ .desc }}

{{ .lang }}
{{- end }}
{{/* ── Writing Activity ─────────────────────────────── */}} {{- $allPages := (where (where site.RegularPages "Lang" $lang) "Date" "gt" (time "1970-01-01")).ByDate.Reverse -}} {{- $thisYear := now.Year -}} {{- $thisYearPages := where $allPages "Date.Year" $thisYear -}} {{- $firstYear := $thisYear -}} {{- range $allPages -}}{{- if lt .Date.Year $firstYear -}}{{- $firstYear = .Date.Year -}}{{- end -}}{{- end -}} {{- $yearsActive := add (sub $thisYear $firstYear) 1 -}} {{- $allPosts := slice -}} {{- range $allPages -}} {{- $allPosts = $allPosts | append (dict "date" (.Date.Format "2006-01-02") "title" .Title "url" .RelPermalink) -}} {{- end -}} {{- $recentPosts := $allPages | first 8 -}}
04

{{ if $isZh }}发布记录{{ else }}Post Activity{{ end }}{{ if $isZh }}{{ else }}写作{{ end }}

{{ if $isZh }}完整归档{{ else }}All Archives{{ end }}
{{ len $allPages }}
{{ if $isZh }}总文章{{ else }}Posts{{ end }}
{{ len $thisYearPages }}
{{ if $isZh }}今年{{ else }}This Year{{ end }}
{{ $yearsActive }}
{{ if $isZh }}写作年数{{ else }}Years{{ end }}
{{ len (site.Taxonomies.categories) }}
{{ if $isZh }}分类{{ else }}Topics{{ end }}
{{- range $i, $p := $recentPosts -}} {{- if $i }}·{{ end -}} {{ $p.Title }} {{- end -}}
{{- range seq $thisYear -1 $firstYear -}} {{- end -}}
LESS MORE {{ $thisYear }} ACTIVITY
{{/* ── Subscribe ────────────────────────────────────── */}}
SIGNAL · 信号

{{ if $isZh }}别错过任何一个信号。{{ else }}Never miss a signal.{{ end }}

{{ if $isZh }}为构建者写作。AI、开源与漫游笔记,直接送到你的邮箱。已有 {{ $d.subscribe.count }}+ 读者。{{ else }}Built for builders. New posts on AI, open source & nomad life — direct to your inbox. Joined by {{ $d.subscribe.count }}+ readers.{{ end }}

{{ if $isZh }}不发广告,随时退订{{ else }}No spam, unsubscribe anytime{{ end }} · RSS {{- with (site.GetPage "/").OutputFormats.Get "JSONFeed" }} JSON {{- end }} {{- with (site.GetPage "/").OutputFormats.Get "OPML" }} OPML {{- end }}
{{/* ── By-channel feeds (compact, magazine-style) ── */}}
{{ if $isZh }}按频道订阅{{ else }}By channel{{ end }}
{{- $colors := slice "#3b82f6" "#10b981" "#a855f7" "#ec4899" "#06b6d4" "#eab308" -}} {{- range $i, $section := site.Sections -}} {{- $rss := $section.OutputFormats.Get "RSS" -}} {{- if $rss -}} {{- $title := $section.Title | default $section.Section -}} {{- $color := index $colors (mod $i (len $colors)) }} {{ $title }} RSS {{- end -}} {{- end }}
{{/* ── Footer ──────────────────────────────────────── */}}
{{/* ── Hero ambient 3D field ───────────────────────────────────── three.js + the hero-field shader, both fingerprinted and locally hosted (same pattern as knowledge-galaxy). The module self-gates: on phones / reduced-motion / no-WebGL it mounts nothing, so this block adds zero runtime cost there beyond a tiny deferred import. */}} {{- $three := resources.Get "js/vendor/three.module.min.js" | resources.Fingerprint "sha384" -}} {{- /* Bundle hero-field + its ./webgl-guard import into one file via esbuild, keeping the bare `three` import external so it resolves via the importmap below. This avoids a second network request 404'ing on the relative guard import. */ -}} {{- $heroField := resources.Get "js/three/hero-field.js" | js.Build (dict "format" "esm" "minify" hugo.IsProduction "externals" (slice "three")) -}} {{- /* The Bear AI orb: shader sphere + neural particle field, same bundling rules (three external → importmap, webgl-guard inlined). */ -}} {{- $bearOrb := resources.Get "js/three/bear-orb.js" | js.Build (dict "format" "esm" "minify" hugo.IsProduction "externals" (slice "three")) -}} {{- if not site.Params.assets.disableFingerprinting -}} {{- $heroField = $heroField | fingerprint -}} {{- $bearOrb = $bearOrb | fingerprint -}} {{- end -}}