Hanpu Li 李函璞

implementation notes · 2026

About this site

This is a deliberately static website. The public pages are documents first: complete HTML, CSS and local assets, with a small amount of vanilla JavaScript only where interaction genuinely helps.

The rule is simple: content must remain readable without a framework, a client-side translation layer or JavaScript-driven rendering.

01

Architecture

Static by design.

The portfolio is generated as complete HTML5 documents from small templates and structured JSON. A Python 3 standard-library builder emits each language edition ahead of time; the browser does not assemble the site at runtime.

The site is served by GitHub Pages from the main branch. There is no CMS, application framework, database or server-side application behind the portfolio.

runtime
HTML5 · CSS · vanilla JavaScript
build
Python 3 · JSON · HTML templates
hosting
GitHub Pages

02

Content & languages

Seven editions, no runtime translation.

English, Traditional Chinese (Hong Kong), Simplified Chinese, Japanese, German, French and Russian are built as separate static editions with canonical URLs, hreflang alternates and locale-specific metadata.

Literary source texts have stricter rules than ordinary interface copy. Traditional Chinese is canonical where specified; Simplified Chinese literary mirrors are script-converted and hash-checked, while translations preserve stanza and line structure through dedicated validation.

locales
en-GB · zh-Hant-HK · zh-Hans · ja · de · fr · ru
literary conversion
OpenCC helper · source hashes · line-parity checks
metadata
canonical · hreflang · Open Graph

03

Layout & typography

Editorial CSS rather than a component framework.

The layout uses CSS Grid, subgrid, container queries, logical properties, custom properties and fluid clamp() sizing. Media queries remain conservative fallbacks; components reflow from their own available width where the browser supports container queries.

Typography is self-hosted as WOFF2. EB Garamond handles most Latin prose, Courier Prime and Cousine handle metadata, Shippori Mincho serves Traditional Chinese and Japanese, Noto Serif SC serves Simplified Chinese, and a tiny I.Ming subset fills the remaining Hong Kong glyph gaps. The CJK subsets are rebuilt with fontTools and Brotli; the Noto source is pinned by commit and SHA-256.

layout
Grid · subgrid · container queries · logical properties
type
EB Garamond · Courier Prime · Cousine · Shippori Mincho · Noto Serif SC · I.Ming
colour
light/dark via prefers-color-scheme

04

Accessibility

Adaptation without removing content.

The portfolio uses semantic landmarks, one primary heading, skip links, visible keyboard focus, descriptive language controls and touch targets large enough to use reliably. Reduced-motion, higher-contrast and forced-colour system preferences are respected.

A persistent reading panel can switch to sans-serif text, increase type and spacing, narrow text columns, simplify the layout, reduce motion and increase contrast. These preferences are progressive enhancement and are stored locally in the browser.

preferences
sans · larger type · spacing · measure · simple layout · motion · contrast
storage
localStorage only
checks
custom structural audit · axe-core browser audit

05

Images & performance

Responsive media, no gallery runtime.

Photographs and research plates use picture/srcset with WebP and JPEG candidates, explicit dimensions and responsive sizes. The lead image is prioritised; images further down the page are lazy-loaded and decoded asynchronously.

Below-the-fold portfolio sections can use content-visibility, while View Transitions and scroll-linked motion are optional progressive enhancements. Reduced-motion preferences disable animation.

images
picture · srcset · WebP · JPEG
loading
explicit dimensions · lazy loading · async decoding
progressive CSS
content-visibility · View Transitions · scroll timelines

06

Build, QA & deployment

Generated pages are testable artefacts.

The repository checks that generated pages are current, locale schemas match, literary structures have not drifted, accessibility landmarks and controls remain intact, local links and fragments resolve, images have alt text and JavaScript parses.

Browser QA adds geometry checks across languages and viewport widths, axe-core accessibility scans and HTML validation. In GitHub Actions, the dependency-light checks run first and the browser suite follows on pushes and pull requests; GitHub Pages independently publishes the static files from main.

repository checks
build freshness · i18n · accessibility · links/assets · JS syntax
browser QA
Playwright · axe-core · html-validate
delivery
GitHub Actions · GitHub Pages

07

Principles

The portfolio treats source content, generated output and browser behaviour as separate layers: edit structured content and templates, rebuild, then verify the emitted documents.

Progressive enhancement is optional by design. Unsupported CSS features, disabled JavaScript or unavailable local storage must not hide the work or block navigation.

Runtime privacy

The portfolio loads no analytics, advertising network, third-party web font or tracking script. It sets no cookies. The only persistent browser state used by the portfolio is the local reading-preference record.