Files
frame44-landing-page/CLAUDE.md
2026-07-16 16:36:46 -04:00

4.3 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

Frame 44 marketing site — an Eleventy (11ty v3) static site. Nunjucks templates, plain CSS, no client-side framework, no build tooling beyond Eleventy itself. Sells map-native interactive exhibit software to museums, historical societies, and heritage sites.

Commands

npm install
npm run serve   # http://localhost:8080, live reload
npm run build   # writes static output to _site/

There is no test suite (npm test is a stub) and no linter configured.

_site/ is pure static HTML/CSS/JS/SVG — no server-side runtime required. Deployment is self-hosted (copy _site/ to a web server document root); no Netlify/Cloudflare Pages config exists.

Architecture

Data-driven pricing. All pricing content lives in src/_data/*.json, never 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, worked-example inputs

Adding an object to packages.json or historicalCollections.json automatically surfaces it on the relevant pages (home pricing teaser, /pricing/, /collections/) — no template changes needed. The pricing page's worked examples are computed in templates from this JSON via the cad, prepay, and findByKey Nunjucks filters defined in eleventy.config.js, so they can't drift out of sync with the underlying prices.

Key filters/shortcodes in eleventy.config.js:

  • cad — formats a number as CAD currency (whole dollars)
  • prepay — multi-year prepay pricing: 3yr = 2.5x annual, 5yr = 4x annual
  • sum, findByKey — array helpers used in templates
  • year shortcode — current year for footer copyright

i18n scaffolding (English-only today). UI strings live in src/_data/i18n/en.json, exposed to templates as i18n via src/_data/i18n.js (currently always returns en). The folder layout anticipates a /fr/ locale: adding French means creating src/_data/i18n/fr.json, switching i18n.js to select by data.lang, and duplicating page templates under src/fr/ with lang: fr front matter (they can extend/reuse the same layouts and macros). Product pricing data (packages.json etc.) only needs duplicating if names/descriptions require translation — see i18n.js for the pattern.

Logos vs. served images. src/assets/logos/ holds huge (8000×4500px) raw design-export PNGs (11 variants). eleventy.config.js passthrough copy deliberately excludes this folder — only src/assets/{css,js,images,fonts} ship to _site/. What's actually served (checked into src/assets/images/, cropped/resized from the raw sources) is logo-header.png (white+red, dark header), logo-footer.png (full-colour, light footer + JSON-LD), and the favicon set. If the brand mark changes, re-crop from src/assets/logos/ rather than hand-editing the served images.

Templates. src/_includes/layouts/base.njk is the shared layout; src/_includes/macros.njk holds shared Nunjucks macros; src/_includes/partials/ holds header/footer. Page routes are folders under src/ (about/, contact/, museums/, platform/, pricing/, collections/ via src/collections/index.njk) each with an index.njk.

Contact. The contact page uses a plain mailto: link (src/contact/index.njk) — there is no form backend.

Known placeholders / unconfirmed data (see site.json / extras.json flags)

  • contactEmail in src/_data/site.json is a placeholder (contactEmailConfirmed: false).
  • Hardware price range and installation timeline in extras.json are unconfirmed (extras.hardware.confirmed / extras.timeline.confirmed).
  • src/assets/css/style.css references self-hosted webfonts (Schibsted Grotesk, Inter) at /assets/fonts/... that are not checked in; the site falls back to system fonts until real .woff2 files are added.
  • Museum case-study copy in src/_data/museums.json (Grootegast, Holten) and all entries in src/_data/team.json are placeholders.
  • No og:image is set in src/_includes/layouts/base.njk.

Treat these as real gaps, not stale notes — check the confirmed flags in the JSON before assuming a number is final.