Static site, see?
- HTMX-first static site to keep things simple, fast and linkable; avoid SPA frameworks while retaining modern UX.
- Each route is a fully valid HTML page for direct loads and crawlers from Google and also random villages in Albania; HTMX speedifies navigation by swapping only
#main-content.
- Gallery
- Added Gallery tab in navigation.
- Gallery layout/styles: Single-column layout;
aspect-ratiosizing to prevent CLS; lazy-loaded images withdecoding="async"and tunedfetchpriority. - Lightbox: Click images to open overlay with caption, scroll lock/restored on close.
- Homepage image: switched to
/static/jnl3_768.png.
- HTMX UX
- Scroll reset on
#main-contentswaps; history restores prior scroll on back/forward. - Anchor hash support after swaps (e.g.,
/post#section). - Removed
show:#main-content:topfrom year links; logic centralised instatic/site.js.
- Scroll reset on
-
HTMX UX
- Year and post links now swap with view transitions:
hx-swap="innerHTML transition:true". - Scroll-to-top on navigations is centralised in
static/site.js(listens tohtmx:afterSwap). No inline JS. - Still no
hx-boost. Explicit HTMX everywhere.
- Year and post links now swap with view transitions:
-
Performance / LCP
- Preload homepage hero (
/static/jnl2.png) in<head>and made it first-class LCP: removedloading="lazy", addeddecoding="async"+fetchpriority="high". - Dropped the “hide body then reveal” FOUC hack; let CSS block render like nature intended.
htmx.min.jsandsite.jsnowdeferon year pages.
- Preload homepage hero (
-
CSS / Motion
- Fixed typo:
prefers-colour-scheme→prefers-color-scheme. USA USA USA - Respect
prefers-reduced-motion: shimmer placeholders don’t animate for users who opt out.
- Fixed typo:
-
A11y / Semantics
role="main"on#main-contentacross pages.- Year nav has
aria-label="Year navigation".
-
Head / Meta
- Added
<meta name="theme-color" content="#000000">. - Kept custom head-merge logic in
static/site.js(simple, no dependency on the htmx extension).
- Added
Why
- Keep the story HTMX-first: tiny JS, snappy UX, no frameworks.
- Better LCP and fewer layout freakouts, smoother swaps and cleaner markup.
-
Architecture
- Header, nav, footer and homepage/post content are componentised and loaded via
hx-getwithhx-trigger="load". - Links use explicit
hx-get/hx-select="#main-content"/hx-target="#main-content"andhx-push-urlfor history. hx-preserveon critical<head>elements; lightweight head merge instatic/site.jsto adopt new<title>, meta, links without duplication.- No
hx-boost; explicit attributes keep control over swap targets, transitions and history.
- Header, nav, footer and homepage/post content are componentised and loaded via
-
UX
- View transitions on swaps where supported; graceful fallback.
- Centralised scroll handling: top on navigation, restore prior position on back/forward; hash anchors respected after swap.
-
Performance
- Preload LCP image and use
decoding="async"+fetchpriority="high"; scriptsdeferwhere safe. - FOUC -- surprisingly easy to fuck up -- let CSS do the right thing and eliminate that JS footprint.
- Preload LCP image and use
-
Ops
- GitHub Pages hosting with
CNAME,sitemap.xmlkept simple; year indexes link to standalone post pages. - Local test server with optional delay (
serve_with_delay.py) to validate skeleton states.
- GitHub Pages hosting with