70 lines
3.8 KiB
Markdown
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.
|
|
|