3.8 KiB
phasefinal-web
The Phase Final, Inc. corporate site — nine static pages on Cloudflare Pages
(project phasefinal, account vh@phasefinal, phasefinal.pages.dev), at
www.phasefinal.com and phasefinal.com. Moved off ana-docker 2026-10-04 (Prime);
the nginx container there was retired (/opt/docker/{compose,conf}/phasefinal-web.retired-20261004).
conf/site/ is the deployed tree, including _headers (the response headers nginx used
to set) and 404.html (without it Pages serves the home page for every unknown path).
Built from the design brief at docs/design/ (boothed 2026-08-29); the markup
and CSS came from a Claude Design session and are checked in verbatim under
conf/site/ apart from the two post-export steps below.
Two steps every fresh export needs
The design tool ships the site with no font binaries and the @font-face
block commented out, deliberately, to honour the brief's zero-external-
requests rule. Both must be undone on import:
- Drop the four woff2 files into
conf/site/fonts/(Space Grotesk variable, IBM Plex Sans variable, IBM Plex Mono 400 + 600 — all SIL OFL, self-hosted, no CDN). - Uncomment the four
@font-facerules at the top ofconf/site/style.css.
Without these the page silently falls back to system fonts and looks wrong rather than broken, which is the failure mode you won't notice.
Deploy
stacks/phasefinal-web/deploy-pages.sh # conf/site → Pages production (branch main)
Needs a vaulted Cloudflare token with Account → Cloudflare Pages: Edit (see the script).
⚠ The 2026-10-04 migration used jackdaw's token as a one-off; a dedicated
nh3-dev/.config/cloudflare/infra-ops-pages-token is pending Prime. Check the result on
the per-deploy preview URL wrangler prints before trusting the custom domains.
DNS and redirects
www.phasefinal.com and phasefinal.com → CNAME phasefinal.pages.dev, Cloudflare-proxied
(both are Pages custom domains). Cloudflare-proxied is also what provides the email-address
obfuscation the contact block relies on. ⚠ The apex no longer 301s to www: Traefik used
to do that, Pages _redirects cannot redirect between hostnames, and no vaulted token may
create a zone Redirect Rule. Both hostnames serve the site until Prime mints a token with
Single Redirect: Edit; then add the rule phasefinal.com/* → https://www.phasefinal.com/${1} (301).
Lesson from the ana-docker era (2026-08-29)
Traefik silently skips containers Docker reports as unhealthy: no error, no router. The first
deploy's healthcheck used http://localhost/, which is ::1 in nginx:alpine while nginx
listened on IPv4 only. Use 127.0.0.1 in healthchecks for IPv4-only listeners.
Content constraints
The copy is governed by hard legal and voice constraints — client naming rules,
the never-"military"/"weapons" phrasing rule, no named individuals. Read the
design brief before editing any text. Edits are made surgically in
conf/site/index.html; there is no CMS and there will not be one.
Structure and design rules (cleanup, 2026-09-28)
- Every page carries the same site header (wordmark + nav), a real
<h1>, and the same footer outside<main>. Change the nav in all nine files at once: the labels are Applications, Systems, Hosting, AI, Engagement, Track record, Contact (+ Privacy in the footer). - The stylesheet link carries a version (
/style.css?v=<date>). CSS is cached for an hour (nginx.conf), so markup that changes with the CSS must bump it, or new pages meet old styles at the edge. - Anti-slop waivers, operator ruling 2026-09-28:
- The hero's full-bleed 3px volt rule is a brand device. The Impeccable detector's
side-tabrule flags it; that is waived. - Space Grotesk is the brand display face.
overused-fontis waived. - Everything else must stay clean: 0 other unwaived rows at 1280 and 390, light and dark.
- The hero's full-bleed 3px volt rule is a brand device. The Impeccable detector's