Lu's interactive personal portfolio, built around the living pixel pond version of Signal Desk.
The homepage focuses on Lu's selected public projects and an interactive procedural pond rather than a catalogue of product pages.
The site has two public routes: /, the interactive portfolio, and /privacy, a short personal-use privacy policy. Retired concept and product URLs resolve to the pond-themed 404.
The portfolio features HomeBot, rakazo-android, Linux Sonar, bongocat, and cursor-barrier.
The interface follows the system light/dark preference. The pond, fish, and feeding controls retain their existing behavior in both modes. The static illustrated portrait sits beside the personal introduction with an image loading fallback. Navigation is available at every screen size, including without JavaScript.
- Vite 8 with React prerendering for GitHub Pages
- React 19 and TypeScript
- ui-stack shadcn/Radix components, scoped pondside homepage styles, CSS Modules, and Tailwind CSS v4
- Framer Motion for interface motion
- Three.js and Yuka for the procedural pond ecosystem
- Lucide React for interface icons
npm ci
npm run devOpen http://localhost:5173.
Run the production checks:
npm run lint
npm run build
npm run test:pondThe browser suite uses Python Playwright. Install its dependency and Chromium once, then run:
python3 -m pip install -r requirements-test.txt
python3 -m playwright install chromium
npm run test:e2enpm run test:e2e:setup runs both setup commands. Set E2E_PORT to use a specific isolated test-server port; otherwise the harness allocates one.
npm run preview serves the built out directory at http://127.0.0.1:3004 with real 404 responses. The browser suite uses this production export.
Pushes to master and manual runs deploy the static export through GitHub Pages.
Before the artifact build, deployment calls .github/workflows/checks.yml, the
same verification used by pull requests: dependency audit, lint, pond tests, and
the production browser suite, which includes a production build. A failed or
cancelled verification prevents the artifact build and deployment.
Verification and artifact build both check out the event's immutable
github.sha, including when a branch advances during a run. The local reusable
workflow reference selects the checks from the caller's commit. Pull requests
verify their synthetic merge commit; deployment verifies its own push or manual
run commit again. This gate does not rely on branch protection or an earlier
PR result. See GitHub's reusable workflow rules.
Successful local checks do not establish a successful Actions run. Runner availability, billing, and the Pages environment can still prevent deployment.
Open Graph and Twitter large-image cards use the checked-in 1200 x 630 PNG
public/share-cards/luinbytes-dev-pond.png for the homepage. The versioned filename
avoids reusing the old pink card's cached image URL. The old PNG remains available
for existing links, but no current metadata references it.
The editable layout is scripts/share-card.html for the homepage. It uses local assets/fonts and renders
offline. To regenerate after an intentional design edit, use the browser-test
setup above, then:
npm run build
python3 scripts/generate-share-card.py
python3 -m unittest discover -s tests/browser -p '*_test.py' -k ShareCardStaticExportTests -vThe generator embeds the original card fonts from installed Fontsource packages, renders offline, and checks loaded
fonts plus a 32px text-safe inset. Review the PNG at full size and at typical
embed size before updating the expected SHA-256 values in
ShareCardStaticExportTests to the generator's printed value. The browser suite builds once and checks the metadata, asset dimensions/hash and absence of old
image references in exported HTML. Normal Pages builds need no Python, browser,
image service or runtime route: Vite copies the checked-in PNGs into the static export.
- Built by Lu
- Powered by caffeine and spite
Home, privacy, and the 404 page have separate HTML and client entries. Vite generates
their stylesheet and preload links. Run node scripts/measure-page-assets.mjs
after a build to inspect each page's initial uncompressed JavaScript and CSS.
Each production page contains a meta Content Security Policy that allows scripts and connections from this site, plus the approved inline script hash. Other inline JavaScript, embedded frames, plugins, and form submissions are blocked. Inline styles remain allowed for React and animation styles. Blob images remain allowed for local pond textures.
The local preview sends the full CSP from scripts/security-policy.mjs plus
frame-ancestors 'none', X-Frame-Options: DENY,
X-Content-Type-Options: nosniff, and Referrer-Policy: no-referrer.
It runs over HTTP and sends no HSTS header.
GitHub Pages serves the static export through Cloudflare. On 9 November 2026 at
09:04:41 UTC, fresh public GET and HEAD samples for / and /privacy returned
Content-Security-Policy: frame-ancestors 'none', X-Frame-Options: DENY,
X-Content-Type-Options: nosniff, and
Strict-Transport-Security: max-age=86400. Both pages retained the full meta CSP.
Production therefore has a response CSP limited to framing plus the full meta
policy, while preview also sends the full policy as a response header.
The QA report did not record production Referrer-Policy, so response header parity
with preview's no-referrer is unverified. See the dated public header evidence and policy
differences for earlier observations and coverage limits.
Pull requests run dependency auditing, lint, unit tests, and the production browser suite. Deployment actions use pinned commits, and only the deployment job receives Pages write and identity-token permissions.