Changelog 051549etree, with Claude Opus 5.5
Footer: build commit (linked to GitHub) and date on the right; npm run build:quick
The stamp uses GITHUB_SHA in the deploy and git locally. build:quick sets SKIP_OG=1 so small frontend changes can be checked without drawing the preview images; the deploy still runs the full build.
6 files of code, design or docs +28 −2 lines
Code, design and documents 6 files
AGENTS.md +1 −1
@@ -15,3 +15,3 @@ cannabis law (`changes.yaml`, `articles/`) and a cultural atlas (`culture/`), bu else's uncommitted changes, and commit only your own files. - Don't start dev or preview servers; check with `npm run build` (one build at a time) and the - HTML in `dist/`. + HTML in `dist/`. For a small frontend change, `npm run build:quick` skips the preview images.
package.json +1 −0
@@ -7,4 +7,5 @@ "dev": "astro dev", "build": "astro build", + "build:quick": "SKIP_OG=1 astro build", "preview": "astro preview", "books:status": "node scripts/books-status.cjs",
src/layouts/Base.astro +4 −0
@@ -9,4 +9,5 @@ import Leaf from "../components/Leaf.astro"; import { Icon } from "astro-icon/components"; import { SEARCH_ICONS, RESULT_KIND_ICONS } from "../lib/search-icons.js"; +import { build } from "../lib/build-info.js"; // `seoTitle` replaces the whole <title> (search-result wording); `jsonld` is one schema.org @@ -127,7 +128,10 @@ const schemas = jsonld ? [jsonld].flat() : []; <footer class="footer"> + <div class="footer-main"> <p>Cannabis Freedom Index · Informational only, not legal advice · Map data © Natural Earth</p> <p class="footer-links"><a href={`${base}about/`}>About</a> · <a href={`${base}sources/`}>Sources</a> · <a href={`${base}glossary/`}>Glossary</a> · <a href={`${base}changelog/`}>Changelog</a> · <a href={`${base}rss.xml`}>RSS</a> · <a href={`${base}data/`}>Download the data</a> · <a href={`${base}llms.txt`} title="A plain-text guide to this site for language models">For AI: llms.txt</a> · <a href={`${base}data/#licence`}>Licence: data CC BY 4.0, code MIT</a></p> <p>Open source — the scores, explanations and code are on <a href={repo} target="_blank" rel="noopener noreferrer">GitHub</a>. Spotted a mistake or a law that changed? <a href={`${repo}/issues`} target="_blank" rel="noopener noreferrer">Open an issue</a> or send a pull request.</p> + </div> + <p class="footer-build">{build.short && <>Build <a href={`${repo}/commit/${build.sha}`} target="_blank" rel="noopener noreferrer" title="The commit this site was built from">{build.short}</a> · </>}<time datetime={build.date}>{build.label}</time></p> </footer>
src/lib/build-info.js +15 −0
@@ -0,0 +1,15 @@ +// What the footer says about this build: the commit it was built from and the day. Read once per +// build. The deploy workflow sets GITHUB_SHA; locally git is asked; without either, no commit. +import { execFileSync } from "node:child_process"; + +const sha = process.env.GITHUB_SHA || (() => { + try { return execFileSync("git", ["rev-parse", "HEAD"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim(); } catch { return ""; } +})(); + +const built = new Date(); +export const build = { + sha, + short: sha.slice(0, 7), + date: built.toISOString().slice(0, 10), + label: built.toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric", timeZone: "UTC" }), +};
src/pages/og/[...path].png.js +2 −1
@@ -98,5 +98,6 @@ for (const c of places) { } -export const getStaticPaths = () => Object.entries(cards).map(([path, card]) => ({ params: { path }, props: { card } })); +// `npm run build:quick` (SKIP_OG=1) draws no cards, to check a small change fast; the deploy always draws them +export const getStaticPaths = () => process.env.SKIP_OG ? [] : Object.entries(cards).map(([path, card]) => ({ params: { path }, props: { card } })); const draw = async ([kind, props]) => kind === "culture" ? renderOg(kind, { ...props, photo: await photoOf(props.photo.file, props.photo.fit) })
src/styles/global.css +5 −0
@@ -1148,4 +1148,9 @@ tbody tr:hover .cname { text-decoration: underline; text-underline-offset: 4px; .footer { text-align: left; font-size: 10.5px; padding: 28px clamp(16px, 4vw, 40px) 48px; margin-top: clamp(64px, 9vw, 120px); border-top: 1px solid var(--text); } +/* the build stamp (commit and date) sits on the right, under the rest on a phone */ +.footer { display: flex; justify-content: space-between; align-items: flex-start; gap: 6px 32px; flex-wrap: wrap; } +.footer-main { flex: 1 1 520px; min-width: 0; } +.footer .footer-build { margin: 0; white-space: nowrap; font-variant-numeric: tabular-nums; } +.footer-build a { font-family: var(--mono); } /* ══ Country profile ═════════════════════════════════════════════════════════