# Frame 44 — Marketing Site Eleventy (11ty v3) static site. Nunjucks templates, plain CSS, no client-side framework, no build tooling beyond Eleventy itself. ## Build & run ``` npm install npm run serve # http://localhost:8080, live reload npm run build # writes static output to _site/ ``` `_site/` is pure static HTML/CSS/JS/SVG — no server-side runtime required. ## Deploying (self-hosted) Copy the contents of `_site/` to your web server's document root after running `npm run build`. Any static file server works. Example nginx server block: ```nginx server { listen 80; server_name frame44.com www.frame44.com; root /var/www/frame44-landing-page/_site; index index.html; location / { try_files $uri $uri/index.html =404; } } ``` No Netlify/Cloudflare Pages config is included — this build targets self-hosting. If that changes later, add `netlify.toml` or a Cloudflare Pages project pointing `npm run build` → `_site/`. The contact page uses a plain `mailto:` link (see `src/contact/index.njk`), so there's no form backend to wire up. When email delivery is set up (sendmail or otherwise), the address that link points to still needs to be a real, monitored inbox — see the TODO list below. ## Logo & favicon The real brand mark lives in `src/assets/logos/` as huge (8000×4500px) design-export PNGs — 11 variants (colour/mono/white × horizontal/stacked lockups, plus two duplicate favicon-mark exports). That folder is **not** shipped: `eleventy.config.js` only passes through `src/assets/{css,js,images,fonts}`, deliberately excluding `src/assets/logos`, so those multi-megabyte source files never reach `_site/`. What's actually served, all cropped/resized from those sources and checked into `src/assets/images/`: - `logo-header.png` — white + red horizontal lockup, for the dark header band - `logo-footer.png` — full-colour (black + red) horizontal lockup, for the light footer and the JSON-LD `logo` field (schema.org recommends a logo on a light/transparent background, not an inverted one) - `favicon-16x16.png` / `favicon-32x32.png` / `apple-touch-icon.png`, and `src/favicon.ico` (multi-size 16/32/48) — the square icon mark composited onto a solid `--color-ink` tile, since the source mark is white + red and needs a dark background to read If the brand mark changes, re-crop from `src/assets/logos/` (or a new export) rather than hand-editing the PNGs in `src/assets/images/`. ## Where prices live All pricing content is in `src/_data/*.json` — nothing is hardcoded in templates: - `packages.json` — the four core packages (Exhibit One, Gallery, Flagship, Multi-Site) - `historicalCollections.json` — licensed historical data collections - `aitools.json` — optional AI add-ons + the bundle - `extras.json` — extras, prepay terms, hardware range, grant support note, and the worked-example inputs Changing a number in one of these files updates every page that shows it. The pricing page's "worked example" and the multi-year prepay example are *computed* in the template from these JSON values (via the `cad`, `prepay`, and `findByKey` Nunjucks filters in `eleventy.config.js`) — they are not separately typed-in numbers, so they can't drift out of sync with the package/collection/AI-tool prices. ### Adding a package Add an object to `src/_data/packages.json`: ```json { "key": "unique-key", "name": "Package Name", "badge": null, "buildPrice": 10000, "annualPrice": 3000, "summary": "One-line summary.", "features": ["Feature one", "Feature two"] } ``` It will automatically appear in the home page pricing teaser and the `/pricing/` packages grid. ### Adding a historical collection Add an object to `src/_data/historicalCollections.json` with `key`, `name`, `price`, `priceType` (`"annual"` or `"one-time-per-project"`), `description`, `whatsInside`, and `suits`. It will automatically appear on both `/pricing/` and `/collections/`. ## Planned `/fr/` locale The site builds English-only today, but the data/folder layout is already split so French can be added without restructuring: - UI strings (nav labels, buttons, footer copy) live in `src/_data/i18n/en.json`, exposed to templates as `i18n` via `src/_data/i18n.js`. - To add French: create `src/_data/i18n/fr.json`, then change `i18n.js` from always returning `en` to selecting by `data.lang` (the comment at the top of that file spells out the exact change). - Duplicate the page templates under `src/fr/` (e.g. `src/fr/index.njk`, `src/fr/pricing/index.njk`) with front matter `lang: fr` and `permalink: /fr/...`. They can `{% extends %}`/reuse the same layout and macros — only the copy and `lang` differ. - Prices themselves (`packages.json`, `historicalCollections.json`, etc.) don't need duplicating unless product names/descriptions need translation — in that case, add locale-suffixed data files (e.g. `packages.fr.json`) and pick the right one the same way `i18n.js` does. ## What's not real yet (TODO before launch) - **Contact email** — `contact@frame44.example` is a placeholder (`site.contactEmailConfirmed: false` in `src/_data/site.json`). Flagged inline on the Contact page. - **Hardware price range** ($3,500–$9,000/screen) — unconfirmed, flagged on the Pricing page (`extras.hardware.confirmed: false`). - **Installation timeline** (8–16 weeks) — unconfirmed, flagged on the Pricing page (`extras.timeline.confirmed: false`). - **Self-hosted webfonts** — `src/assets/css/style.css` references `/assets/fonts/schibsted-grotesk/*.woff2` and `/assets/fonts/inter/*.woff2`, but no font files are checked in (this environment has no network access to fetch them). The site falls back to system fonts until real woff2 files are added at those paths. - **Museum case-study copy** — Grootegast and Holten summaries in `src/_data/museums.json` are `` placeholders; real photos also needed at `src/assets/images/placeholders/grootegast.svg` / `holten.svg` (currently generated placeholder graphics). - **Team bios** — all three entries in `src/_data/team.json` are placeholders (name, role, bio, photo). - **Open Graph share image** — no `og:image` tag is set. Add a real image and an `og:image` meta tag in `src/_includes/layouts/base.njk` once one exists. - **Lighthouse scores** — not run in this environment (no browser available here). Run `npm run build && npx serve _site` and check Performance/Accessibility/Best Practices/SEO locally before launch, particularly once the real webfonts and images are in place (placeholders are lightweight SVG, so real photos may change the Performance number).