{{ if .IsHome }}{{ site.Title }}{{ else }}{{ .Title }} · {{ site.Title }}{{ end }}
{{- /*
Priority: this page's own front matter > an explicit site-wide
params.description override > params.profile.bio, stripped of markdown
down to plain text. Set params.description only when the SEO snippet
should say something different from the colophon bio; otherwise bio is
the single source of truth for both.
*/}}
{{- $desc := .Description }}
{{- if not $desc }}{{ $desc = site.Params.description }}{{ end }}
{{- if not $desc }}{{ with site.Params.profile.bio }}{{ $desc = . | markdownify | plainify }}{{ end }}{{ end }}
{{ with $desc -}}
{{- end }}
{{ with resources.Get "css/style.scss" }}
{{ $opts := dict "transpiler" "dartsass" "outputStyle" "compressed" }}
{{ with . | toCSS $opts }}
{{ end }}
{{ end }}
{{- /* One hreflang tag per translated version of this page, so search
engines serve readers the right language instead of always the one
that happens to rank. x-default points at the lowest-weight (English)
translation, since that's the site's default language. */}}
{{- $translations := sort .AllTranslations "Language.Weight" }}
{{- range $translations }}
{{- end }}
{{- with index $translations 0 }}
{{- end }}
{{- /*
Declarative, not htmx.config.preload = {...} in a script: a tag
is parsed with the rest of the document, before any script (deferred or
not) runs, so htmx's constructor sees it synchronously and correctly
every time - no dependency on inline-script/defer/DOMContentLoaded
ordering at all. boostEvent switches hx-preload's trigger from the
default mousedown/touchstart to mouseover, so the fetch for a boosted
link starts the instant the cursor touches it rather than waiting for a
press.
*/}}
{{- /*
Official htmx extension, vendored from the same htmx.org package as
htmx.min.js above (node_modules/htmx.org/dist/ext/hx-preload.min.js -
re-copy it from there on a version bump). Prefetches a boosted link's
GET response, reused automatically if the click follows within 5s.
Needs no hx-ext or other opt-in - just being loaded activates it for
every boosted anchor.
*/}}
{{- /*
htmx's own browser back/forward handling (#restoreHistory) is a
separate code path from a boosted click - it calls htmx.ajax() directly
with swap:"outerSync" hardcoded, a full body replace, not our
innerMorph below. Left alone, a link click morphed smoothly but
back/forward tore the masthead down and rebuilt it. Preempt it with the
same config used everywhere else (kept as one Hugo value, $swapSpec,
rather than duplicated literals, so the two can't drift apart), and
abort a still-in-flight restore before starting the next one - the same
guard htmx's own implementation has - so mashing back/forward can't let
a slow, stale response land after a faster, newer one.
`defer` only affects scripts with a `src` - htmx.min.js and
hx-preload.min.js above genuinely wait until after parsing, but this
inline script has no `src` and runs immediately in place during
parsing, defer or not. It must not touch `htmx` at its top level, only
from inside a listener that fires later - hence DOMContentLoaded, which
is guaranteed to fire only after every deferred script, htmx.min.js and
hx-preload.min.js included, has already run.
*/}}
{{- $swapSpec := dict "swap" "innerMorph" "transition" true }}
{{ block "head" . }}{{ end }}
{{- /*
Boosts every same-origin link/form into an AJAX navigation, inherited from
body down (htmx 4 requires the ":inherited" suffix explicitly - it no
longer inherits hx-* attributes implicitly). Boosted elements default to
targeting the whole ; innerMorph diffs the new body onto the old
one node-by-node instead of replacing it wholesale, so unchanged nodes
(the masthead's "mykiwi.blog" link) are patched in place rather than
torn down and re-flashed, while changed ones - the per-page signal SVG
path, the swapped #main content - update normally. transition:true wraps
that diff in a native View Transition for a soft cross-fade.
*/}}
{{ i18n "skipToContent" }}