Changelog 8ce76e8
minor updates
8 files of code, design or docs +225 −205 lines
Code, design and documents 8 files
public/favicon.svg +1 −2
Not shown: a picture, a generated file, or past the length shown per change.
src/components/CountryArticle.astro +6 −2
@@ -4,5 +4,5 @@ import { SEGMENTS, CONTEXT, REC_LABEL, MED_LABEL } from "../data/data.js"; import { DETAILS } from "../data/details.js"; -import { countries, segAvg, segmentPoints, segmentMax, subunitsOf } from "../lib/countries.js"; +import { countries, segAvg, segmentPoints, segmentMax, subunitsOf, formatDate } from "../lib/countries.js"; import { tierOf, tierColor } from "../lib/tiers.js"; @@ -15,4 +15,7 @@ const d = sub ? null : DETAILS[c.id]; const countryUrl = `${base}country/${c.slug}/`; const unitUrl = (x) => `${countryUrl}${x.id}/`; +// Date the entry was last reviewed, stored as YYYY-MM-DD and shown in full. +const updated = sub ? group.reviewed : d?.reviewed; +const updatedText = updated && formatDate(updated); const byName = group ? [...group.units].sort((a, b) => a.name.localeCompare(b.name)) : []; const r = 42; @@ -62,5 +65,5 @@ const circ = 2 * Math.PI * r; {sub ? <p class="d-hint">{group.intro} Select a segment to show or hide the rules.</p> - : <p class="d-hint">Select a segment to show or hide the exact rules and sources.{d && ` Reviewed ${d.reviewed}.`}</p>} + : <p class="d-hint">Select a segment to show or hide the exact rules and sources.</p>} {sub && SEGMENTS.map((s, i) => ( <details class="segrow" open> @@ -165,4 +168,5 @@ const circ = 2 * Math.PI * r; </> )} + {updated && <p class="c-updated">Last updated: <time datetime={updated}>{updatedText}</time></p>} </div> </article>
src/components/Leaf.astro +2 −3
@@ -1,14 +1,13 @@ --- // Seven-leaflet cannabis leaf, drawn from one leaflet shape rotated and scaled -// around the point where the leaflets meet the stem. +// around the point where the leaflets meet. No stem; the fan is centred in the box. const { size = 22 } = Astro.props; const leaflets = [[0, 1], [-31, 0.9], [31, 0.9], [-63, 0.7], [63, 0.7], [-97, 0.43], [97, 0.43]]; --- <svg viewBox="0 0 24 24" width={size} height={size} aria-hidden="true"> - <g transform="translate(12 16.4) scale(1.28)" fill="currentColor"> + <g transform="translate(12 18.25) scale(1.4)" fill="currentColor"> {leaflets.map(([angle, k]) => ( <path d="M0 0C1.9-2.6 1.5-7 0-10C-1.5-7-1.9-2.6 0 0Z" transform={`rotate(${angle}) scale(${k})`} /> ))} </g> - <path d="M12 16.4V21.6" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" /> </svg>
src/data/details.js +197 −197
@@ -2,5 +2,5 @@ * * DETAILS[countryId] = { - * reviewed: "Month YYYY", + * reviewed: "YYYY-MM-DD", * sources: { key: [label, url] }, * seg: ten entries in SEGMENTS order, each { t: explanation, src: [source keys] } @@ -12,5 +12,5 @@ export const DETAILS = { CA: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { justice: ["Department of Justice Canada — Cannabis legalization and regulation", "https://www.justice.gc.ca/eng/cj-jp/cannabis/"], @@ -34,5 +34,5 @@ export const DETAILS = { UY: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { law: ["Ley N° 19.172 — Regulación y control del cannabis (IMPO)", "https://www.impo.com.uy/bases/leyes/19172-2013"], @@ -55,5 +55,5 @@ export const DETAILS = { DE: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { bmg: ["Bundesgesundheitsministerium — FAQ zum Cannabisgesetz", "https://www.bundesgesundheitsministerium.de/themen/cannabis/faq-cannabisgesetz"], @@ -76,5 +76,5 @@ export const DETAILS = { US: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { ncsl: ["National Conference of State Legislatures — State cannabis laws", "https://www.ncsl.org/health/state-medical-cannabis-laws"], @@ -98,5 +98,5 @@ export const DETAILS = { MT: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { cap628: ["Authority on the Responsible Use of Cannabis Act (Cap. 628)", "https://legislation.mt/eli/cap/628/eng"], @@ -120,5 +120,5 @@ export const DETAILS = { JM: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { fact: ["Ministry of Justice — Dangerous Drugs (Amendment) Act 2015 fact sheet", "https://ncst.gov.jm/wp-content/uploads/2015/09/Ganja-FACT-SHEET-Amendment-to-Dangerous-Drug-ACT.pdf"], @@ -141,5 +141,5 @@ export const DETAILS = { ZA: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { act: ["Cannabis for Private Purposes Act 7 of 2024 — full text", "https://lawlibrary.org.za/akn/za/act/2024/7/eng@2024-06-03"], @@ -163,5 +163,5 @@ export const DETAILS = { CZ: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { expats: ["Expats.cz — Inside Czechia's 2026 cannabis law", "https://www.expats.cz/czech-news/article/inside-czechia-s-2026-cannabis-laws-how-much-can-you-legally-grow-and-possess"], @@ -185,5 +185,5 @@ export const DETAILS = { TH: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { thaiger: ["The Thaiger — Cannabis in Thailand 2026: the new medical-only rules", "https://thethaiger.com/guides/cannabis/cannabis-thailand-2026-medical-rules"], @@ -206,5 +206,5 @@ export const DETAILS = { NL: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { gov: ["Government of the Netherlands — Toleration policy regarding soft drugs and coffee shops", "https://www.government.nl/topics/drugs/toleration-policy-regarding-soft-drugs-and-coffee-shops"], @@ -227,5 +227,5 @@ export const DETAILS = { LU: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { idpc: ["IDPC — Growing and smoking weed at home now legal in Luxembourg", "https://idpc.net/news/2023/07/growing-and-smoking-weed-at-home-now-legal-in-luxembourg"], @@ -249,5 +249,5 @@ export const DETAILS = { TT: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { wiki: ["Wikipedia — Cannabis in Trinidad and Tobago", "https://en.wikipedia.org/wiki/Cannabis_in_Trinidad_and_Tobago"], @@ -270,5 +270,5 @@ export const DETAILS = { CH: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { chch: ["ch.ch (Swiss authorities) — Cannabis", "https://www.ch.ch/en/safety-and-justice/police/cannabis"], @@ -291,5 +291,5 @@ export const DETAILS = { CO: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { wiki: ["Wikipedia — Cannabis in Colombia", "https://en.wikipedia.org/wiki/Cannabis_in_Colombia"], @@ -313,5 +313,5 @@ export const DETAILS = { ES: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { wiki: ["Wikipedia — Cannabis in Spain", "https://en.wikipedia.org/wiki/Cannabis_in_Spain"], @@ -335,5 +335,5 @@ export const DETAILS = { AG: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { wiki: ["Wikipedia — Cannabis in Antigua and Barbuda", "https://en.wikipedia.org/wiki/Cannabis_in_Antigua_and_Barbuda"], @@ -356,5 +356,5 @@ export const DETAILS = { PT: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { law: ["Lei n.º 30/2000 — regime jurídico do consumo de estupefacientes (Diário da República)", "https://diariodarepublica.pt/dr/detalhe/lei/30-2000-599720"], @@ -378,5 +378,5 @@ export const DETAILS = { AR: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { res: ["Resolución 1780/2025, Ministerio de Salud — REPROCANN rules", "https://www.argentina.gob.ar/normativa/nacional/norma-413121/texto"], @@ -399,5 +399,5 @@ export const DETAILS = { BZ: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { act: ["Misuse of Drugs (Amendment) Act 2017, No. 47 of 2017 (PDF, via OAS)", "https://oas.org/ext/Portals/33/adam/Content/1LAvBxqRKUevbza4NS5FZw/Text/Act-No.-47-of-2017-Misuse-of-Drugs-Amendment-Act-2017.pdf"], @@ -420,5 +420,5 @@ export const DETAILS = { CL: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { tni: ["Transnational Institute — Drug law reform in Chile: basic guide", "https://www.tni.org/en/node/16144"], @@ -441,5 +441,5 @@ export const DETAILS = { DM: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { wiki: ["Wikipedia — Cannabis in Dominica", "https://en.wikipedia.org/wiki/Cannabis_in_Dominica"], @@ -462,5 +462,5 @@ export const DETAILS = { LC: { - reviewed: "October 2026", + reviewed: "2026-10-04", sources: { … 1220 more lines
src/data/subunits.js +3 −0
@@ -16,4 +16,5 @@ export const SUBUNITS = { label: "State", plural: "states", + reviewed: "2026-10-04", intro: "Federal law still prohibits non-medical cannabis everywhere in the United States; these scores describe state law. Counties and cities can add their own rules, and state law does not apply on federal land.", sources: [ @@ -79,4 +80,5 @@ export const SUBUNITS = { label: "Province or territory", plural: "provinces and territories", + reviewed: "2026-10-04", intro: "The federal Cannabis Act applies everywhere in Canada. Provinces and territories set the minimum age, where you may consume, how shops work, and whether you may grow at home.", sources: [ @@ -104,4 +106,5 @@ export const SUBUNITS = { label: "State or territory", plural: "states and territories", + reviewed: "2026-10-04", intro: "Each Australian state and territory has its own drug law. Medical cannabis is regulated federally and is available on prescription everywhere, mostly through telehealth clinics.", sources: [
src/lib/countries.js +11 −0
@@ -28,7 +28,18 @@ export const worldAvg = countries.reduce((a, c) => a + c.raw, 0) / countries.len import { SUBUNITS } from "../data/subunits.js"; import { SUBUNIT_DETAILS, unitSource } from "../data/subunit-details.js"; +import { DETAILS } from "../data/details.js"; const scoreOf = (s) => s.reduce((a, v, i) => a + segmentPoints(i, v), 0); +// Review dates are stored as YYYY-MM-DD; this is how they are shown everywhere. +export const formatDate = (iso) => + new Date(`${iso}T00:00:00Z`).toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric", timeZone: "UTC" }); + +// The most recent review date across every country and state entry. +export const lastUpdated = [ + ...Object.values(DETAILS).map((d) => d.reviewed), + ...Object.values(SUBUNITS).map((g) => g.reviewed), +].filter(Boolean).sort().at(-1); + // For a country id, returns { label, plural, intro, sources, units } with each unit scored, // ranked within its country, and placed where it would sit among countries. Undefined if none.
src/pages/index.astro +2 −1
@@ -4,5 +4,5 @@ import DidYouKnow from "../components/DidYouKnow.astro"; import Lore from "../components/Lore.astro"; import { SEGMENTS, DATA_SNAPSHOT, REC_LABEL, MED_LABEL } from "../data/data.js"; -import { countries, regions, worldAvg } from "../lib/countries.js"; +import { countries, regions, worldAvg, lastUpdated, formatDate } from "../lib/countries.js"; import { TIERS, tierColor } from "../lib/tiers.js"; @@ -119,4 +119,5 @@ const mapData = countries.map(({ id, num, name, flag, raw, score, rank, s }) => </table> </div> + <p class="table-updated">Last updated: <time datetime={lastUpdated}>{formatDate(lastUpdated)}</time></p> </section>
src/styles/global.css +3 −0
@@ -427,2 +427,5 @@ td.num, th.num { width: 52px; color: var(--muted); } .u-score { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; } @media (max-width: 640px) { .units { columns: 1; } } + +.c-updated { margin: 28px 0 0; padding-top: 14px; border-top: 1px solid var(--border); color: var(--muted); font-size: 13px; } +.table-updated { margin: 12px 4px 0; color: var(--muted); font-size: 13px; text-align: right; }