Kenya's Senate receives a cannabis legalisation petition
Sub-Saharan Africa, Cannabis, and Contemporary Drug Policy
The Cannabis Trade in Africa
Changelog eef38dc
50 history entries added9 history entries edited1 history entry removed1 score changed47 country profiles edited28 articles written2 articles edited6 files of code, design or docs +4,388 −329 lines
Sub-Saharan Africa, Cannabis, and Contemporary Drug Policy
The Cannabis Trade in Africa
PRIDE International and Drug War Diplomacy: The Parent Movement’s Global Battle against Marijuana in the United States, ca. 1970–1985
PRIDE International and Drug War Diplomacy: The Parent Movement's Global Battle against Marijuana in the United States, ca. 1970–1985
“Hashers Don’t Read Das Kapital”: East Germany, Socialist Prohibition, and Global Cannabis
Cannabis behind the Iron Curtain: Drugs and Drug Policy in the German Democratic Republic
PRIDE International and Drug War Diplomacy: The Parent Movement’s Global Battle against Marijuana in the United States, ca. 1970–1985
PRIDE International and Drug War Diplomacy: The Parent Movement's Global Battle against Marijuana in the United States, ca. 1970–1985
1 unchanged
“We Smoke Flowers”: On “Being High” in Postrevolutionary Iran
High on Modernity: Cannabis and the Quest for the Sublime in Iran
Smuggler’s Paradise: The Hash Trade and Drug Control in the Building of the Afghan State, ca. 1923–1974
Smuggler's Paradise: The Hash Trade and Drug Control in the Building of the Afghan State, ca. 1923–1974
1 unchanged
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States, ca. 1938–2018
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States
2 unchanged
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States, ca. 1938–2018
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States
2 unchanged
Smuggler’s Paradise: The Hash Trade and Drug Control in the Building of the Afghan State, ca. 1923–1974
Smuggler's Paradise: The Hash Trade and Drug Control in the Building of the Afghan State, ca. 1923–1974
cultivation 0 → 1
CultivatingThe law punishes growing cannabis for drug productiononly when it is prohibiteddone to produce narcotics, with fines and flogging that escalate on repeat offences; growing the plant as such is not an offence. A 2021 study found cannabis grown across the countryside, mostly on a small scale for local demand, and websites selling seeds and growing equipment openly.
wikianl, cgh, lc
Corporal punishment for small amounts and the death penalty for large ones. A 2017 amendme … mainly to armed or organised trafficking, though drug executions have since risen again. Practice towards users is far milder than the text: fieldwork published in 2021 found few police interventions over cannabis use, with arrests concentrated on heroin, methamphetamine and alcohol, and described the laxity as deliberate policy. The score follows the law, which still provides for flogging.
ihr, lc, cgh
Use is an offence, but dependent users who enter treatment are exempt from punishment. Hashish use is common and, in private, often overlooked. A 2021 study calls toleration of cannabis use the norm, including in a few places known for it, such as the village of Qalat near Shiraz, where it is smoked in cafes.
wiki, cgh
“We Smoke Flowers”: On “Being High” in Postrevolutionary Iran 5 unchanged
The whole market is illegal and, by a 2021 study based on fieldwork, easy to reach: officials said the time needed to obtain hashish or cannabis anywhere in Tehran had fallen from fifteen minutes to seven. Hashish is mass-produced in Afghanistan and Pakistan and comes in along the opiate routes. Herbal cannabis is widely grown in Iran, mostly on a small scale, and sold as gol ("flower"), a high-THC product that took over the market from about 2000. Dealers advertise through Instagram stories and deliver to the door. Dealers and users in Tehran put gol at about 50,000 tuman a gram, roughly 0.80 US dollars, with imported hashish cheaper.
cgh
cr, cann
cr, alto
Public consumption is punished more heavily thanBritish travel advice says Andorra has a zero-tolerance policy on the possession and use of illegal drugs, with up to two years and an €1that even the smallest amount can bring refusal of entry,800 fine expulsion, fines and prison sentences.
crfcdo
hca, tb
hca, tb, iwpr
cr, ris
cr, ris
ris, cr
The fine for a sub-gram amount is several months' average wagesBritish travel advice says possession or use of illegal drugs, including cannabis, carries severe penalties, and anything more isto expect a prison offencelong jail sentence and heavy fines for possessing, using or smuggling them. Drug charges have also been used against government critics.
cr, tripfcdo
Use is an administrative offence. British travel advice says use of illegal drugs, with compulsory treatment possibleincluding cannabis, carries severe penalties.
tripfcdo
NoneNo legal source. British travel advice says possession or use of illegal drugs, including cannabis, carries severe penalties.
crfcdo
cr, wiki
dr, cr
cr, wiki
cr, wiki
cr, dt
TraffickingArticle 30 of Law No. 15 of 2007 punishes anyone who, organised smugglingwith the intention of trafficking, sells, delivers, buys or supplying minors can bringpossesses a listed drug or plant, or grows, imports or exports it, with death or life imprisonment orand a fine of 5,000 to 50,000 dinars. In listed aggravated circumstances the death penalty is death.
crl15
Use is an offence. British travel advice says consuming or carrying illegal drugs, even a residual amount and even in transit through the airport, can lead to a prison sentence and deportation.
crfcdo
Trafficking, organised smugglingArticle 30 of Law No. 15 of 2007 sets death or supplying minors can bring life imprisonment for producing, importing, growing, selling or possessing listed drugs and plants with the intention of trafficking, and death penaltyalone in listed aggravated circumstances.
crl15
wiki, dt, cr
cr, wiki
ml, cr
ConsumptionUse is punished on the same terms aslike possession: British travel advice says to expect a long jail sentence and heavy fines for possessing, using or smuggling drugs.
crfcdo
wiki, cr
tb, wiki
tb, wiki
Prison terms of years are on the books for simpleBritish travel advice says possession, use or trafficking of illegal drugs is a serious offence that can result in a lengthy prison sentence and heavy fines. The death penalty, abolished in 2016, no longer applies to any drug offence.
tbfcdo, wiki
tb, wiki
wiki, trip
hoc, trip
hoc, wiki, trip
tb1, trip
NoneNo legal source. British travel advice says there are strict penalties for possession, use and trafficking of illegal drugs.
tripfcdo
trip, tb2
cr, wiki
cr, wiki
Uneven: weak state presenceNo source read for this profile gives the penalties or describes how the law is applied. Cannabis is the one drug produced in much of the country, with arrests and informal payments common inmainly for local consumption; the citiesscore assumes that prison is possible for users.
crwiki
Use is an offenceA law of February 2021 limits narcotics to medical, educational and scientific purposes; using cannabis for any other purpose stays prohibited.
crwiki
cr, wiki
cr, leaf
l407, cr
cr, koaci
koaci, cr
UseUsing is an offencepunished through possession: holding a drug for one's own use carries one to three months in prison and a fine of 50, now000 to 500,000 CFA francs. The law exempts people taking part in a harm-reduction programme, on conditions set by decree. Driving after using a drug is a separate offence with therapeutic injunctions as an alternativeone to prisonfive years.
crl407
l407, cr, koaci
Illegal with no personal-use threshold; the government describes its policy as zero tolerance. UnderThe president of the 2022 Penal Code simpleSupreme Court's criminal chamber said in November 2023 that possession typically carries six monthsand trafficking carry four to twothirty years in prison plus fines, and that 92% of the 689 people sanctioned for drug offences that year were sent to prison.
croncuba, fcdo
cr, cn1
cn1, cr
Use is treated throughBritish travel advice says Cuba has a zero-tolerance policy against the use, possession offenceand trafficking of drugs. The state offers free detoxification treatment.
crfcdo, oncuba
NoneNo legal source. British travel advice says Cuba has a zero-tolerance policy against the use, possession and trafficking of illegal drugs.
crfcdo
cr, cn1, cn2
wiki, cr
wiki, cr
tsa23, wiki, trip
cr, law
cr, law
es, cr
Use is a crime. Hashish is nonetheless one of the most widely used drugs in the countryBritish travel advice lists use alongside possession and trafficking as a serious offence that can lead, even for small amounts, to very long sentences.
crfcdo
NoneNo legal source. British travel advice says possession, use or trafficking of illegal drugs is a serious offence.
crfcdo
cr, law, es
cr, law, es
cr, leaf
PrisonBritish travel advice says drug offences are treated seriously and that possession can lead to five to ten years in prison and potentially large fines. No account of how the law is a real possibility forapplied to ordinary users; checks at Addis Ababa's airport are routine was found.
crfcdo
cr, leaf
cr, iol
ToleranceBritish travel advice says possession of drugs is informala serious offence and punishments can be withdrawn; foreign nationalssevere, including prison sentences. No account of how the law is applied in particular are reported to be prosecutedpractice was found.
crfcdo
wiki, iol, cr
cr, un
cr, un
cr, un
Consumption is an offence under the personal-use provision. British travel advice says there are severe penalties for all drug offences.
crfcdo, dl2b93
NoneNo legal source. British travel advice says there are severe penalties for all drug offences.
crfcdo
cr, un
cr, law
ic, cr
cr, ic
Trafficking carries six to fifteen yearsThe 1989 drug law, upDecree 126-89, punishes trafficking and transport with three to twenty when aggravatedyears in prison. It sets no quantity that separates dealing from personal use: the judge decides from the circumstances and the amount seized.
crtnihn
law, cr
ic, cr
cr, jl
cr, jl
wiki, cr
wiki, cr
cr, wiki
Sub-Saharan Africa, Cannabis, and Contemporary Drug Policy 6 unchanged
Cannabis accounts for most drug arrests. Police statistics for 2016 show 776 people arrested in relation to cannabis, against 92 for heroin and 11 for cocaine. Sentences can be heavy for very little: in one case reported in a 2021 study a man received two years in prison for a single "stick" worth twenty shillings. No more recent national breakdown was found.
cgh
cr, glepha
unodc, cr
glepha, cr
SupplyMaking or supplying drugs for sale is punished with seven to twelve yearsa crime under section 267 of the Criminal Code in force since 2019, morewith heavier categories of imprisonment for a group, a large amountsscale, an especially large scale or sale to a minor. Prison terms under the code run from six months to fifteen years.
crglepha
No legal source. British travel advice says it is illegal to possess or use drugs.
crfcdo
unodc, cr
trip, wiki, kt
cr, zakon
nt, cr
Supply is punished with long prison termsBritish travel advice gives the sentences for possessing, storing or transporting drugs in order to distribute them as five to eight years, and six to ten years for large amounts.
crfcdo
No legal source. British travel advice says illegal drugs, including cannabis, carry severe penalties.
crfcdo
cr, fcdo
cr, law
gi, cr
gi, cr
trip, law
wiki, trip
gdpo, trip
gdpo, trip
gdpo, trip
tb, leaf
aa, tb
cr, mi
NoneNo legal source. British travel advice says possession, trafficking and manufacture of any illegal drug, cannabis included, are serious offences and that the authorities have a zero- tolerance policy.
crfcdo
cr, at, mi
cr, clr
clr, cr
NoneNo legal source. British travel advice says possession of even small quantities of drugs can lead to imprisonment.
crfcdo
pen, cann, trip
trip, cann
Use is a crime. British travel advice says there is zero tolerance, that penalties for using drugs, including cannabis, are severe even for residual amounts, and that a long prison sentence, deportation and heavy fines should be expected.
tripfcdo
trip, kpu
NoneNo legal source. British travel advice says there are strict penalties for possessing and trafficking drugs, including cannabis.
tripfcdo
trip, kpu
trip, fcdo
wiki, tb
wiki, tb
case, trip
Use is covered byBritish travel advice says the possession offence, selling and use of drugs is illegal and can lead to prison sentences.
tripfcdo
NoneNo legal source. British travel advice says the possession, selling and use of drugs is illegal.
tripfcdo
case, st, trip
tb, nordic
scan, tb
mo, cr
mo, cr
mo, cr
cr, mo
mo, cr
cr, wiki
euaa, cr
cr, euaa
wiki, cr
cr, wiki
Prison is availableBritish travel advice says there are severe penalties for possession;all drug offences. No figures on how small cases often end in finesare dealt with were found.
crfcdo
wiki, cr
wvm, wiki, cr
dn, cr
wiki, cr
wiki, cr
TheBritish travel advice says penalties for drug offences are severe: life imprisonment for possession, and the death penalty for trafficking. No account of how the authorities that took power in December 2024 keptapply the existing law and have publicised seizures and destruction of drug stockpilesto users was found.
crfcdo
cr, wiki
NoneNo legal source. British travel advice says there are severe penalties for drug offences, including life imprisonment for possession.
crfcdo
cr, wiki
wiki, cr
law, cr
cr, ht
cr, law
No legal source for adult use. British travel advice says punishments for possessing or smuggling narcotic drugs can be severe.
crfcdo
ht, cr
cr, ht
cr, wiki
osf, cr
cr, wiki
en, cr
Use is itselfpunished. British travel advice says anyone found guilty of possessing or using illegal drugs could face a crime with up to five yearslengthy prison sentence in very basic conditions.
crfcdo
wiki, trip
ln1, cr
cr, ln1
None. The 2025 drug law counts the cannabis plant as a narcotic plant, prohibits growing it and excludes cultivation even from licensed research and production.
crl120
cr, ln1
ln2, cr, ln1
cr, lp
nr, cr
cr, lex
cr, lex
nr, cr, lp
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States, ca. 1938–2018
Reefer Madness Past and Present: Dr. Leopoldo Salazar Viniegra, Mexico, and the United States
2 unchanged
South Africa was one of the first countries to ban cannabis and the one that asked
the wo … ons began in [Natal in 1870](/history/south-africa-natal-1870/), aimed at
Indian labourers. The Orange River Colony [banned supplying it](/history/orange-river-colony-dagga-ordinance-1903/) in 1903, and reached the [Cape in 1891[listed it as a poison](/history/southcape-africacolony-capedagga-banpoison-1891listing-1905/) in 1905.
A [national ban](/history/south-africa-national-ban-1922/) followed in 1922, and the
nex … d enforcement from 2 to 6
for [South Africa](/country/za/). Access rose only from 0 to 1.
source-archive.json +1264 Not shown: a picture, a generated file, or past the length shown per change.
src/components/AverageChart.astro +2 @@ -17,5 +17,5 @@ const t1 = time(lastUpdated); // one chart for each combination of period and weighting const RANGES = [ - { id: "all", label: "All", startYear: 1900 }, // a few bans are older; they are already counted in the starting value + { id: "all", label: "All", startYear: 1860 }, // the handful of older bans are already counted in the starting value { id: "15y", label: "Last 15 years", startYear: endYear - 15 }, ]; @@ -45,5 +45,5 @@ function view(range, weighting) { // at most about a dozen year labels, on round steps const span = endYear - startYear; - const step = span > 50 ? 10 : span > 20 ? 5 : span > 14 ? 2 : 1; + const step = span > 120 ? 20 : span > 50 ? 10 : span > 20 ? 5 : span > 14 ? 2 : 1; const years = Array.from({ length: span + 1 }, (_, i) => startYear + i) .filter((yr) => yr % step === 0)
src/lib/countries.js +3 @@ -227,5 +227,7 @@ function scoreAt(c, t) { // There is a point at every dated change, and one each New Year so that slow shifts (estimated // changes, and populations growing at different rates) show up as well. -const CHART_FROM = 1900; +// The chart starts in 1860, before the first colonial bans. Population figures begin in 1900, so +// for earlier years the by-population average uses each country's 1900 population. +const CHART_FROM = 1860; function averageOverTime(weight) { const at = (t) => {
src/pages/culture.astro +86 @@ -0,0 +1,86 @@ +--- +// Culture: the announcement page for the participatory research that is to sit beside the index. +// The index maps laws; this is about the people and beliefs behind them. Nothing is collected +// here yet: the page says what the project asks and shows where the history already touches it. +import Base from "../layouts/Base.astro"; +import { changes } from "../lib/countries.js"; + +const base = import.meta.env.BASE_URL; +// What the project wants to understand, in the owner's own terms. +const themes = [ + ["Attitudes", "What people in a country actually think of cannabis and of those who use it, and how far that is from what the law says."], + ["Stigma", "Who is judged for using it, by whom, and what it costs them at work, in the family and in public."], + ["Traditions", "Where cannabis belongs to religion, medicine, farming or celebration, and what happened to those customs under prohibition."], + ["Obedience and authority", "Why people follow a law they do not believe in, and who they think has the right to decide."], + ["Resistance", "How people get around a ban, organise against it or simply ignore it, and what they risk."], + ["Generations", "What changed between grandparents, parents and children, and what did not."], +]; +// Places where the history on this site already records culture meeting law. Each must exist. +const threads = [ + ["india-hemp-drugs-commission-1894", "An inquiry of 1,200 witnesses found the habit widespread, and advised against banning it partly because of “the social and religious feeling on the subject”."], + ["india-bhang-exemption-1961", "India kept bhang out of the world treaty so that it could go on being drunk at Holi."], + ["nepal-pashupati-distribution-ended-1995", "Until 1995 a temple trust in Kathmandu handed cannabis to holy men at Shivaratri, from the Home Ministry's confiscated stock."], + ["jamaica-ganja-reform-2015", "Jamaica wrote Rastafari sacramental use into its law."], + ["transvaal-mine-dagga-survey-1908", "Asked in 1908 whether dagga should be banned, the managers of the Transvaal gold mines mostly said no: use was moderate, and restrictions would keep men from coming to work."], + ["south-africa-enforcement-compromise-1922", "A month after South Africa banned dagga, police were told to go easy in remote African areas, where an older man's morning pipe was “a custom so deep-rooted as almost to amount to a religious rite”."], + ["mexico-salazar-marijuana-myth-1938", "A Mexican health official told the Academy of Medicine that the madness of marijuana was a myth, and ended by handing his colleagues cigarettes of it."], + ["afghanistan-hashish-fertiliser-edicts-1969", "With Western travellers buying, Afghanistan's king issued edicts urging farmers to use fertiliser and grow more hashish."], + ["south-africa-natal-1870", "One of the first cannabis laws anywhere applied to one group only: Indian labourers in Natal."], + ["brazil-rio-pango-ban-1830", "Rio de Janeiro's ban of 1830 named the slaves who smoked it."], + ["egypt-first-ban-1868", "Egypt's first ban has been read as a centralising state's wish to civilise its lower classes."], +].map(([id, text]) => { + const ch = changes.find((x) => x.id === id); + if (!ch) throw new Error(`culture.astro: there is no history entry "${id}"`); + return { ch, text }; +}).sort((x, y) => x.ch.date.localeCompare(y.ch.date)); +--- +<Base title="Culture" description="Culture is a participatory anthropology project beside the Cannabis Freedom Index: how cannabis shapes, and is shaped by, society, through anonymous surveys, personal stories and community research."> + <main class="changes-page culture"> + <section class="hero hero-sm"> + <p class="eyebrow">Culture <span>in preparation</span></p> + <h1>The people behind the laws</h1> + <p class="lede">Culture is a participatory anthropology project exploring how cannabis shapes, and is shaped by, society. Through anonymous surveys, personal stories and community research, it examines cultural attitudes, stigma, traditions, obedience, authority and resistance across different countries and generations.</p> + <p class="lede">While the Freedom Index maps laws, Culture explores the people, beliefs and social forces behind them.</p> + </section> + + <section class="section"> + <div class="section-head"><div> + <h2>What it asks</h2> + <p class="sub">A score says what a person is allowed to do. It does not say what their neighbours think, what their grandmother grew, or why a law nobody respects is still obeyed.</p> + </div></div> + <dl class="culture-themes"> + {themes.map(([name, text]) => <div><dt>{name}</dt><dd>{text}</dd></div>)} + </dl> + </section> + + <section class="section"> + <div class="section-head"><div> + <h2>How it will work</h2> + <p class="sub">Three kinds of material, gathered from the people who live with these laws. None of it is open yet; this page will say when it is.</p> + </div></div> + <dl class="culture-themes three"> + <div><dt>Anonymous surveys</dt><dd>Short sets of questions, the same in every country, so that answers can be compared with each other and with the index.</dd></div> + <div><dt>Personal stories</dt><dd>Accounts in a person's own words: an arrest, a family argument, a harvest, a ritual.</dd></div> + <div><dt>Community research</dt><dd>Local knowledge that no statute records, collected and checked by people who know the place.</dd></div> + </dl> + </section> + + <section class="section"> + <div class="section-head"><div> + <h2>Where the history already touches it</h2> + <p class="sub">The index's <a href={`${base}history/`}>history</a> is a record of laws, but culture shows through it. A few of the places where it does:</p> + </div></div> + <ol class="culture-threads"> + {threads.map(({ ch, text }) => ( + <li> + <a href={`${base}history/${ch.id}/`}> + <time datetime={ch.date}>{ch.date.slice(0, 4)}</time> + <span>{ch.place.flag} {ch.place.name}</span> + <p>{text}</p> + </a> + </li> + ))} + </ol> + </section> + </main> +</Base>
src/pages/sources/index.astro +147 @@ -0,0 +1,147 @@ +--- +// Every source the index cites, counted. Books first, then websites by domain: the ones cited +// for several countries one by one, and the local ones (cited for a single country) grouped +// under that country. The page is not in the menu. +import Base from "../../layouts/Base.astro"; +import { getCollection } from "astro:content"; +import { places } from "../../lib/countries.js"; + +const base = import.meta.env.BASE_URL; +const num = (n) => n.toLocaleString("en-GB"); +const placeOf = new Map(places.map((c) => [c.slug, c])); + +// One citation = one source listed by one owner (a country profile, a history entry or an article). +// `where` is the country it was cited for, or "" for international entries. +const cites = []; +for (const { id, data } of await getCollection("countries")) { + const slug = id.split("/")[0]; + for (const s of Object.values(data.sources)) cites.push({ s, where: slug }); + for (const s of data.subunits?.sources ?? []) cites.push({ s, where: slug }); +} +const changes = (await getCollection("changes")).map((x) => x.data); +const countryOfChange = new Map(changes.map((ch) => [ch.id, ch.country ?? ""])); +for (const ch of changes) for (const s of ch.sources) cites.push({ s, where: ch.country ?? "" }); +for (const a of await getCollection("articles")) for (const s of a.data.sources) cites.push({ s, where: countryOfChange.get(a.id) ?? "" }); + +// ── Books: anything with a container or typed as a book or chapter ── +const isBook = (s) => s.type === "book" || s.type === "chapter" || Boolean(s.container); +const books = new Map(); // book title → { meta, chapters: Map(chapter title → { authors, locator, n }), n } +for (const { s } of cites.filter((x) => isBook(x.s))) { + const title = s.container ?? s.title; + const b = books.get(title) ?? { title, editors: s.editors, authors: s.container ? undefined : s.authors, publisher: s.publisher, year: s.year, isbn: s.isbn, chapters: new Map(), n: 0 }; + b.n++; + if (s.container) { + const ch = b.chapters.get(s.title) ?? { title: s.title, authors: s.authors ?? [], page: Infinity, n: 0 }; + ch.n++; + // citations give the pages they rely on, so the lowest one seen puts the chapters in book order + ch.page = Math.min(ch.page, parseInt((s.locator ?? "").replace(/\D+/, "")) || Infinity); + b.chapters.set(s.title, ch); + } + books.set(title, b); +} +const bookList = [...books.values()].sort((x, y) => y.n - x.n); + +// ── Websites, by domain ── +const domainOf = (url) => new URL(url).hostname.replace(/^www\./, ""); +const domains = new Map(); // domain → { urls: Set, n, where: Map(slug → n) } +for (const { s, where } of cites.filter((x) => !isBook(x.s) && x.s.url)) { + const d = domainOf(s.url); + const row = domains.get(d) ?? { domain: d, urls: new Set(), n: 0, where: new Map() }; + row.urls.add(s.url); + row.n++; + row.where.set(where, (row.where.get(where) ?? 0) + 1); + domains.set(d, row); +} +const all = [...domains.values()]; +// local: cited for exactly one country and nothing international +const isLocal = (r) => r.where.size === 1 && ![...r.where.keys()].includes(""); +const wide = all.filter((r) => !isLocal(r)).sort((x, y) => y.n - x.n || x.domain.localeCompare(y.domain)); +const local = new Map(); // slug → rows +for (const r of all.filter(isLocal)) { + const slug = [...r.where.keys()][0]; + local.set(slug, [...(local.get(slug) ?? []), r]); +} +const localRows = [...local] + .map(([slug, rows]) => ({ c: placeOf.get(slug), rows: rows.sort((x, y) => y.n - x.n || x.domain.localeCompare(y.domain)), n: rows.reduce((a, r) => a + r.n, 0) })) + .filter((x) => x.c) + .sort((x, y) => x.c.name.localeCompare(y.c.name)); +const urlCount = new Set(cites.filter((x) => x.s.url).map((x) => x.s.url)).size; +const stats = [ + [num(cites.length), "Citations"], + [num(urlCount), "Web pages cited"], + [num(all.length), "Websites"], + [num(wide.length), "Cited for several countries"], + [num(all.length - wide.length), "Local, for one country"], + [num(bookList.length), bookList.length === 1 ? "Book" : "Books"], +]; +--- +<Base title="Sources" description={`The ${num(urlCount)} web pages and ${bookList.length} books cited by the Cannabis Freedom Index, counted by website and by country.`}> + <main class="changes-page sources-page"> + <section class="hero hero-sm"> + <p class="eyebrow">Sources</p> + <h1>What the index is built on</h1> + <p class="lede">Every score, explanation and history entry cites where it comes from. This page counts those sources: books first, then websites, with the local ones grouped under the country they were used for. A citation is one source listed once by a country profile, a history entry or an article.</p> + </section> + + <dl class="hist-stats"> + {stats.map(([n, label]) => <div><dt>{label}</dt><dd>{n}</dd></div>)} + </dl> + + <section class="section" id="books"> + <div class="section-head"><div> + <h2>Books</h2> + <p class="sub">Printed sources, with the chapters that are cited and how often.</p> + </div></div> + {bookList.map((b) => ( + <div class="src-book"> + <h3>{b.title}</h3> + <p class="src-meta">{[b.editors && `Edited by ${b.editors.join(" and ")}`, b.authors && b.authors.join(", "), b.publisher, b.year, b.isbn && `ISBN ${b.isbn}`].filter(Boolean).join(" · ")} <b>{b.n} {b.n === 1 ? "citation" : "citations"}</b></p> + {b.chapters.size > 0 && ( + <table class="src-table"> + <thead><tr><th>Chapter</th><th>Author</th><th class="num">Cited</th></tr></thead> + <tbody> + {[...b.chapters.values()].sort((x, y) => x.page - y.page).map((ch) => ( + <tr><td>{ch.title}</td><td>{ch.authors.join(", ")}</td><td class="num">{ch.n}</td></tr> + ))} + </tbody> + </table> + )} + </div> + ))} + </section> + + <section class="section" id="websites"> + <div class="section-head"><div> + <h2>Websites cited for several countries</h2> + <p class="sub">{num(wide.length)} sites used for more than one country, or for international entries, most cited first.</p> + </div></div> + <table class="src-table"> + <thead><tr><th>Website</th><th class="num">Pages</th><th class="num">Citations</th><th class="num">Countries</th></tr></thead> + <tbody> + {wide.map((r) => ( + <tr><td><a href={`https://${r.domain}/`} target="_blank" rel="noopener noreferrer">{r.domain}</a></td><td class="num">{num(r.urls.size)}</td><td class="num">{num(r.n)}</td><td class="num">{[...r.where.keys()].filter(Boolean).length}</td></tr> + ))} + </tbody> + </table> + </section> + + <section class="section" id="local"> + <div class="section-head"><div> + <h2>Local sources, by country</h2> + <p class="sub">{num(all.length - wide.length)} sites cited for one country only: its laws, courts, ministries and press. The number after a site is how often it is cited.</p> + </div></div> + <table class="src-table src-local"> + <thead><tr><th>Country</th><th>Websites</th><th class="num">Citations</th></tr></thead> + <tbody> + {localRows.map(({ c, rows, n }) => ( + <tr> + <th scope="row"><a href={`${base}country/${c.slug}/`}>{c.flag} {c.name}</a></th> + <td>{rows.map((r, i) => <><a href={`https://${r.domain}/`} target="_blank" rel="noopener noreferrer">{r.domain}</a>{r.n > 1 && <small> {r.n}</small>}{i < rows.length - 1 && <span class="sep"> · </span>}</>)}</td> + <td class="num">{n}</td> + </tr> + ))} + </tbody> + </table> + </section> + </main> +</Base>
src/styles/global.css +35 @@ -1242,2 +1242,37 @@ details.segrow .segrow-top > span, .segrow:not(details) .segrow-top > span { fon .numbers-grid dd a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 6px; } @media (max-width: 760px) { .numbers-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } + +/* Culture: the announcement page. Themes as a ruled grid, history threads as a ledger. */ +.culture .hero .lede + .lede { margin-top: 14px; color: var(--text); } +.culture-themes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 clamp(24px, 4vw, 56px); margin: 0; border-top: 1px solid var(--text); } +.culture-themes div { padding: 16px 0 22px; border-bottom: 1px solid var(--border); } +.culture-themes dt { font: 400 26px/1.1 var(--display); } +.culture-themes dd { margin: 8px 0 0; color: var(--text-2); font-size: 14.5px; line-height: 1.5; max-width: 40ch; } +.culture-threads { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--text); } +.culture-threads a { display: grid; grid-template-columns: 6ch 22ch 1fr; gap: 20px; align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--border); } +.culture-threads time, .culture-threads span { font: 400 11.5px var(--mono); text-transform: uppercase; letter-spacing: .05em; color: var(--muted); } +.culture-threads p { margin: 0; font: 400 21px/1.25 var(--display); text-wrap: pretty; } +.culture-threads a:hover p { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; } +.culture .section-head .sub a { text-decoration: underline; text-underline-offset: 3px; } +@media (max-width: 760px) { + .culture-themes { grid-template-columns: 1fr; } + .culture-threads a { grid-template-columns: 6ch 1fr; } + .culture-threads p { grid-column: 1 / -1; } +} + +/* Sources: flat ruled tables of what is cited */ +.src-table { width: 100%; border-collapse: collapse; border-top: 1px solid var(--text); font-size: 14px; } +.src-table th, .src-table td { padding: 9px 16px 9px 0; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; } +.src-table thead th { font: 400 10.5px var(--mono); text-transform: uppercase; letter-spacing: .06em; color: var(--muted); cursor: default; } +.src-table .num { text-align: right; padding-right: 0; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; } +.src-table .mono { font-family: var(--mono); font-size: 12.5px; white-space: nowrap; } +.src-table td a:hover, .src-table th a:hover { text-decoration: underline; text-underline-offset: 3px; } +.src-table tbody th { font-weight: 400; white-space: nowrap; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--text); width: 22ch; } +.src-local td { color: var(--text-2); line-height: 1.7; } +.src-local td small { font: 400 10.5px var(--mono); color: var(--muted); } +.src-local .sep { color: var(--border); } +.src-book + .src-book { margin-top: 40px; } +.src-book h3 { font: 400 30px/1.1 var(--display); margin: 0; } +.src-meta { margin: 8px 0 16px; color: var(--text-2); font-size: 13.5px; } +.src-meta b { font: 400 10.5px var(--mono); text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-left: 10px; } +.sources-page .hist-stats { margin-top: 8px; }