Files
esh-pfi-infrastructure/stacks/phasefinal-web/README.md
T

70 lines
3.8 KiB
Markdown

# 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:
1. 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).
2. Uncomment the four `@font-face` rules at the top of `conf/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
```bash
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-tab` rule flags it; that is waived.
- Space Grotesk is the brand display face. `overused-font` is waived.
- Everything else must stay clean: 0 other unwaived rows at 1280 and 390, light and dark.