Nigeria's Senate votes for the death penalty for drug trafficking
deathdebate
Changelog 74c796d
6 history entries added2 history entries edited1 score changed8 country profiles edited8 files of code, design or docs +624 −193 lines
deathdebate
1975-10-24
Nigeria removes the death penalty for growing hempcannabis
An amendment toNigeria’s military government removed the Indian Hemp Decree dropped capital punishmentdeath penalty for cultivationcultivating and reduced the prison termsimporting or selling cannabis, replacing it with imprisonment of at least ten years. ASmoking or possession became punishable by a 200-naira fine, imprisonment of at least six months, or both.[@1] In 1984 decreethe government raised them againthe cultivation prison term to at least 21 years.[@2]
Nigeria — Indian Hemp (Amendment) Decree 34 of 1975, government text communicated to the UN
Nigeria — Indian Hemp (Amendment) Decree 27 of 1984, Official Gazette 55
Wikipedia — Cannabis in Nigeria
The Origins of Cannabis Prohibition in Nigeria and the Indian Hemp Decree of 1966
military, sentencing
The capital alternative was removed, but at least ten years of imprisonment remained; both sit within the rubric’s most severe penalty band.
enforcement 4 → 2
AOrdinary first offence withpossession of up to 30 g isbrings a $100–250 fine. A driver with nomore than 1 g in the passenger area can face up to 90 days in jail, even on a first offence. Medical dispensaries serve card holderscardholders.
AOrdinary first offence withpossession of 30 g or less isbrings a fine of up to $100–250 with no jailfine. A second brings 5conviction within two years can bring up to 60 days in jail. More[@2] A driver possessing more than 1 g but no more than 30 g ison their person, or knowingly keeping or allowing it in the passenger area, faces up to 90 days and/or a felony$1,000 fine. This includes the glove compartment; the trunk and non-passenger areas of a vehicle without a trunk are excluded from this extra offence.[@2] Above 30 g but below 250 g, the law permits up to one year in county jail and/or $1,000, or up to three years in state custody and/or $3,000.[@2]
AOrdinary first possession of up to 30 g is fine-only. The separate driver offence for more than 1 g to 30 g can bring jail on a first small offenceconviction, butand repeat possession can also bring jail from the second.[@2]
Mississippi State Board of Medical Licensure — Mississippi Medical Practice Act and Related Laws (2026) 1 unchanged
The Constitutional Court struck down penalties forPrivate cannabis consumption in 2018, making private useis legal, while possession, growing and sale remain restricted. In July 2025 parliament broughtParliament restored prison back for possessing more than 5 g of dried cannabis in July 2025. On 24In June 2026 the Constitutional Court barred imprisonment for buying or possessingin a case about 0.1315 g of cannabis resin for personal-use. Buying or possessing that resin remains a crimeunder the pre-May-2025 code; criminal liability remained. Cultivation and sale remain crimes, so there is no lawful source.
Up to 5 g of dried cannabis is an administrative offence with a fine. Criminal Code amendmentsAmendments adopted on 2 July 2025 ended the court-made rule that 5–70 g could not bringrestored prison: for buying or holding more than 5 g can now be punished, with up to six years for the basic offence, 70–250 g with five to eight years for 70–250 g, and up to one year for a repeat offence under 5 g with up to one year. On[@civil,ocm,jam] In its 24 June 2026 ruling on the code as it stood before May 2025, the Constitutional Court held thatbarred imprisonment for buying or possessing 0.1315 g of cannabis resin for personal use, including after a prior drug conviction, is unconstitutional. Buying or possessing that resin remains a crimeIt left criminal liability in place. The ruling concerns that resin amount.[@cc882,cc882judgment]
civil, ocm, jam, cc882, cc882judgment
UsePrivate consumption itself is not punished and under 5 g of dried cannabis brings a fine, but since. Since July 2025, prison is again possible abovefor possessing more than 5 g of dried cannabis and for a repeat offence under 5 gsmall-quantity possession. On[@civil,ocm,idpc] In its 24 June 2026 ruling on the code as it stood before May 2025, the Constitutional Court held thatbarred imprisonment cannot be imposed for buying or possessing 0.1315 g of cannabis resin for personal use, including after a prior drug conviction. Buying or possessing that resin remains a crimeIt left criminal liability in place. Sale and larger quantities carry long prison sentences.[@cc882,cc882judgment]
civil, ocm, idpc, cc882, cc882judgment
There is no legallawful recreational supply for anyone. The Constitutional Court's rulings protect a person's own use, not: buying or carrying across a border, growing and selling remain prohibited.[@idpc] Up to 5 g of dried cannabis isbrings an administrative offence with a fine; since amendments adopted on 2the July 2025, buying or holding more than amendments restored prison above 5 g can be punished with prisonand for repeat small-quantity possession. On[@civil,ocm] In its 24 June 2026 ruling on the code as it stood before May 2025, the Constitutional Court held thatbarred imprisonment cannot be imposed for buying or possessing 0.1315 g of cannabis resin for personal use, including after a prior drug conviction. Buying or possessing that resin remains a crimeIt left criminal liability in place.[@cc882,cc882judgment]
idpc, civil, ocm, jam, cc882, cc882judgment
Constitutional Court of Georgia — Paata Cherkezishvili v Parliament, judgment 1/2/882 10 unchanged
Cannabis is a Class I narcotic under Law 35 of 2009. FromSince 2 January 2026, Article 111(1) punishes planting or possessing it in plant form withcarries up to twelve years in prison and/or a category VI fine. There is no four-year minimum. More than 1 kg or more than fiveat least six plants israises the penalty to life imprisonment or up to twenty years, and/or a higher fine. That paragraph does not providePossession under Article 111 has no death penalty or special minimum prison term. A person treated as an abuser[@uu35,uu2026] Personal use under Article 127 instead facescarries up to four years, and one proven; a person proved to be a victim of drug abuse must be sent toreceive rehabilitation, an outcome that often depends on money and lawyers.[@uu35]
uu126, uu35, gp, tempouu2026
Planting cannabis is the samepunished under Article 111 offence. FromSince 2 January 2026, the basic penalty is up to twelve years and/or a category VI fine, with no four-year minimum. More than 1 kg or more than fiveat least six plants iscarries life imprisonment or up to twenty years and/or a higher fine. That paragraphThe special minimum prison terms have been removed; Article 111 does not provide a death sentence.[@uu2026,uu35]
uu126uu2026, uu35
From 2 January 2026Selling, selling, buying, brokering or delivering a Class I narcotic iscarries life imprisonment or up to twenty years, and/or a category VI fine (Article 114(1)). MoreFor plant-form cannabis, more than 1 kg or more than fiveat least six plants iscan bring death, life, imprisonment or up to twenty years (and/or a higher fine under Article 114(2)).[@uu2026,uu35] Giving a Class I narcotic to another person to use remains an offencecarries up to fifteen years and/or a category VI fine under Article 116(1). If it causes death or permanent disability, which stays in forceArticle 116(2) allows death, life imprisonment or up to twenty years and/or a higher fine. The 2026 adjustmentlaw removed the special minimum prison minimums from the narcotics articles that had themterms.[@uu2026,uu35]
uu126uu2026, uu35
Law 1 of 2026, issued onSince 2 January 2026, repealedaggravated sale or delivery under Article 113. Article 114 stays. Salecan bring death, life imprisonment or delivery ofup to twenty years and/or a higher fine. For cannabis in plant form, the threshold is more than 1 kg, or more than fiveat least six plants. Possession and planting under Article 111 carry prison penalties only.[@uu2026,uu35] The new Criminal Code’s Article 610 replaces the former production, import, export and distribution offence in Article 113: the same plant-weight or plant-count threshold can bebring death, life, imprisonment or up to twenty years. Possessing and/or planting that quantitya category VI fine. For non-plant Class I narcotics the threshold is life or up to twenty years under Article 111(2)more than 5 g. Article 116, givingGiving a Class I narcotic to another person, stays in force. Indonesia retains the to use can also bring death penalty for drug traffickingunder Article 116(2) if it causes death or permanent disability.[@uu2026,uu35]
uu126uu2026, uu35, sun
Law 35 of 2009 lists as aThe Class I narcoticlist covers the cannabis plant and "all its parts of the plant, including seeds, fruit, and straw", and its products. Planting[@uu35] Since 2 January 2026, unauthorised planting, keeping or possessing a Class I narcotic in plant form without right is, from 2 January 2026,carries up to twelve years and/or a category VI fine under Article 111(1), with no statutorywithout a special minimum prison term.[@uu2026]
holuu35, uu126uu2026
There is no legal recreational supply for anyone. Every cannabis product is illegal, including medicinal cannabis, CBD, hemp products, oils, creams and edibles. Cannabis is a Class I narcotic under Law 35 of 2009and is prohibited for health services, including for foreign medical patients. From[@uu35] Since 2 January 2026, possessing the plant iscarries up to twelve years and/or a category VI fine, with no four-yearwithout a special minimum prison term. A person who can prove they are a user may instead get[@uu2026] Personal use under Article 127 carries up to four years or court-ordered; a person proved to be a victim of abuse must receive rehabilitation.[@uu35]
uu126uu35, tempo, gpuu2026
Indonesia National Narcotics Agency — Law 35 of 2009 on Narcotics, original official text
Indonesia — Law 1 of 2026 on Penal Adjustments, official gazette text
Undang-Undang Republik Indonesia Nomor 35 Tahun 2009 tentang Narkotika (Wikisource)
8 unchanged
PossessionCannabis possession carries long mandatory prison terms. Cultivation carries life under the NDLEA Act. The compiled; the older Indian Hemp Act still prints death orprescribes at least 21 years for cultivationafter its amendments. AAn October 2026 replacement bill to repeal that Act isremains before the Senate and is not law.
A 2017 review of West African drug laws summarises theThe NDLEA Act as punishingpunishes production, planting or growing with life imprisonment. Section 2(1) of[@idpc17] Under the compiledolder Indian Hemp Act sentences a person who knowingly plants or cultivates any plant of, the genus cannabis either to1975 amendment removed the cultivation death or tosentence and the 1984 amendment set imprisonment for not less thanof at least 21 years.[@iha75,iha84] A 2026 bill transmittedsent to the Senate would repeal that Act. It has been referred for legislative processingin October 2026 proposes to replace both Acts and is not lawremains pending.[@naltf]
idpc17, ihaiha75, naltfiha84, omnaltf
TheUnder the NDLEA Act makes no distinction between, possession and use: both carry fifteen to twenty-five years.[@idpc17] The 1984 Indian Hemp Actamendment separately sets at least four years, with no option of without a fine, option for smoking Indian hempcannabis or knowingly possessing it, and at least five for possessing a pipe or other smoking utensil.[@iha84]
idpc17, ihaiha84
Section 2(1) of the compiledThe Indian Hemp Act sentences knowing cultivation of any cannabis plant either to’s death or to imprisonmentpenalty for not less thancultivation was removed on 24 October 1975. The 1984 amendment replaced the prison term with at least 21 years. Sale and export under the same[@iha75,iha84] The online 2004 compilation are prison termsstill prints the older death alternative, but the gazetted amendments replace it; repeal of an amending law does not less than 21 yearsby itself revive the earlier penalty. A[@iha,iha75,iha84,interpret] The October 2026 bill transmitted to replace the Senate would repeal the Indian Hemp Act and the NDLEA Act togetherremains a proposal before the Senate. It has been referred for legislative processing and is not law.[@naltf]
iha75, iha84, iha, interpret, naltf
Nigeria — Indian Hemp (Amendment) Decree 34 of 1975, government text communicated to the UN Nigeria — Indian Hemp (Amendment) Decree 27 of 1984, Official Gazette 55 Nigeria — Interpretation Act 13 unchanged
Use without a medical card is illegal. A registered patientRegistered patients may use the approved medical products. Raw plant material and products that could be smoked or vaped are prohibited.[@2] Recreational use is illegal.[@1]
Registered Alabama patients and caregivers may buy at licensed dispensaries. Callie'’s Apothecary in Montgomery opened on 4 June 2026, Callie's Apothecary infollowed by Talladega on 28 August 2026, and Bama Bloom in Athens on 14 September 2026. A card requires Alabama residency, a qualifying condition and a recommendation from a physician certified by the Board of Medical Examinersphysician’s recommendation. AllowedApproved products include lozenges, tablets, capsules, tinctures, topicals, patches and oils for an inhaler. Raw plant material and products that could be smoked or vaped are prohibited.[@2]
limitedlegal
Recreational use is illegal. A registered patientRegistered patients may use the approved medical products.[@2] Smoking isand medical use in public are prohibited. Vaporization is prohibited for a registered patient overpatients aged 21 or younger.[@4]
FromSince 1 July 2026 a, registered patient or caregiverpatients and caregivers may buy oils, tinctures, patches, lotions, capsules, ingestibles and vaporizer products, including medical cannabis flower for vaporization, at afrom licensed dispensarydispensaries or an independent pharmacypharmacies. Smoking, candies, cookies and patient home growing areremain prohibited. A cardholder may possess up to 12,000 mg of THC in a labelled pharmaceutical containerpackaging, with up tono more than 1,200 mg in aeach package.[@2,3]
Georgia General Assembly — SB 220, Putting Georgia’s Patients First Act Georgia Code — Unlawful consumption of medical cannabis 2 unchanged
NoneThere is no medical or adult-use dispensary programme. Only CBD with[@1] Compliant final hemp products may contain up to 0.3% THC by weight, but hemp cigarettes, cigars, smokeless hemp, teas and vaping products are prohibited, alongside products barred by food and drug rules.[@2,3] A patient with a debilitating condition, or the parent or guardian of a qualifying minor, has a defence to possession charges for independently tested treatment oil with THC no more than 5% of its CBD concentration. They must carry a qualifying Kansas physician’s letter dated within the previous 15 months and show it to an officer on request. This is legala defence to prosecution; Kansas has no licensed medical dispensaries.[@4,5]
Kansas Legislature — Commercial Industrial Hemp Act definitions Kansas Legislature — Unlawful hemp products Kansas Legislature — Claire and Lola’s Law Kansas Revisor of Statutes — Possession of controlled substances 1 unchanged
Adults 21+ may carry 2.5 oz on you, keep 10 oz at home andplus the harvest of up to twelve plants per household — the most generous home-grow limit in the country. Shopslawfully grown there, and buy from licensed loungesshops. Cannabis above 2.5 oz at home must be secured with locks or other functioning security devices.
Adults 21+ may possess 2.5 oz on your person and, including no more than 15 g of concentrate. At their residence they may keep 10 oz at homeplus cannabis harvested from plants lawfully cultivated there, with no separate weight cap on that harvest. FromAnything above 2.5 to 5 oz isat home must be in a $500 civil infractioncontainer or area secured with locks or other functioning security devices.[@2]
TwelveAdults 21+ may grow up to twelve plants per householdresidence for personal use, out of public view and in an enclosed, secured area. The cannabis harvested there is allowed at that residence in addition to the ordinary 10 oz home allowance.[@2]
Michigan Judicial Institute — Scope of the Michigan Regulation and Taxation of Marihuana Act 1 unchanged
AnyGrowing even a small number of plants for personal use can be prosecuted as felony manufacture. The ordinary statutory penalty is up to five years in prison and/or a felony$15,000 fine, with no blanket 2½-year minimum.5 to 5 years[@2,3] Medical patients cannot grow at home; production requires a licence.[@1]
Pennsylvania General Assembly — Controlled Substance, Drug, Device and Cosmetic Act Pennsylvania Superior Court — Commonwealth v. Van Aulen (2008) 1 unchanged
docs/WRITING.md +2 @@ -129,4 +129,6 @@ references. The same source keeps its number wherever it is cited again. `sources` list; `[@1,3]` cites two. Put the mark after the full stop, with no space: `…in 1972.[@1]` +- **State/province files:** `[@2]` cites the second source in the file’s `sources` list. + Segment text renders numbered inline references; summaries remain plain text. - **Country files:** cite by source key: `[@bmg]`, `[@bmg, kcang]`, using only the keys listed in that segment's or context section's `sources`.
docs/research/issues-108-118-2026-10-24.md +77 @@ -0,0 +1,77 @@ +# Issues 108–118: legal corrections and chart semantics + +Reviewed 24 October 2026. Source copies, extracted text, the issue bodies and validation helpers are in `tmp/issues-108-118/`. This batch fixes the requested issues; it is not a reconstruction of every country's earlier scores. + +## 108 — Nigeria: reconcile the compilation with the amendments + +**Resolution: keep `recreational: illegal`. The original amendment texts replace the capital cultivation alternative with imprisonment.** The online 2004 Indian Hemp Act compilation is not a reliable consolidated rendering of section 2(1). The profile now explicitly explains its conflicting death wording and cites the amendments. + +- [1975 Decree 34, communicated by the Nigerian government to the UN](https://digitallibrary.un.org/record/131681/files/e-nl-1980-91-e.pdf), E/NL.1980/91, section 1(a), replaces everything from “to be sentenced” to the end of section 2(1) with imprisonment **not less than ten years**. Section 1(b) also replaces the import/sale death alternative with at least ten years. Commencement: 24 October 1975. The explanatory note says “not exceeding”; that contradicts the operative text. Use the operative minimum, which is also the wording quoted by the subsequent amendment. The scan was inspected visually. +- [1984 Decree 27, original Official Gazette 55](https://archive.gazettes.africa/archive/ng/1984/ng-government-gazette-supplement-dated-1984-09-20-no-55-part-a.pdf), A553–554, section 1(a), expressly amends section 2(1) **as amended in 1975**. It substitutes imprisonment **not less than 21 years** for the ten-year prison term. It does not insert a death alternative. The scan was inspected visually. It was made 14 September, published 20 September 1984, and deemed effective 31 December 1983 (sections 2–3). +- Section 3(2) repeals the 1975 amending Act. That does not silently restore the original capital language: [Interpretation Act](https://lawsofnigeria.placng.org/print.php?sn=218) sections 4(1) and 6(1)(a) direct that amended laws be read as amended and that repeal does not revive something already out of force. The 1984 operative cultivation amendment independently specifies the new prison wording. +- The [online compilation](https://lawsofnigeria.placng.org/print.php?sn=202) still prints death or at least 21 years. Its text therefore cannot displace the original sequential substitutions. The profile's death-penalty context acknowledges the discrepancy instead of using the reprint to classify Nigeria as currently capital for cannabis cultivation. +- [Mohammed v FRN (2018)](https://lawcarenigeria.com/abubakar-mohammed-v-federal-republic-of-nigeria2018/) concerns implied repeal of the magistrates' jurisdiction provision by the NDLEA Act's Federal High Court jurisdiction. It does not decide the section 2 death question. The conclusion above rests on the actual sentencing amendments, not an invented wholesale implied repeal. +- The [October 2026 executive bill](https://naltf.gov.ng/senate-receives-executive-bills-to-overhaul-drug-enforcement-framework-and-expand-transport-safety-mandate/) is a proposal to replace both Acts. It is recorded as debate, not an enacted repeal. No subsequent enactment was established in this review. + +Also removed the profile’s separate pipe-possession penalty: the 1975 decree section 1(e) deleted section 6, and the 1984 decree does not restore it. The consumption paragraph now cites the gazetted smoking/possession amendment directly. + +Corrected the 1975 history entry to its commencement date and primary text, added the 1984 prison amendment, and reclassified the 2024 Senate proposal as debate. The current practical scores remain unchanged: resolving the reprint does not establish new current rights. The old 1966 national score step is inherited and is not asserted to be a fully audited historical vector. Removing death while retaining at least ten years stays in the rubric's severe-penalty range; the 1975 and 1984 amendments carry explicit unscored reasons. + +## 109–110 — Indonesia: read the actual 2026 annex + +The issue's Kemenko PDF URL returns 404. A complete 260-page gazetted copy is available from the [Bandung regional legislature's legal documentation service](https://jdihdprd.bandungkab.go.id/asset/file_hukum/No_1_Tahun_2026__69df0feee34a76.73084363.pdf). The [BPK registry](https://peraturan.bpk.go.id/Details/337869/uu-no-1-tahun-2026) confirms promulgation and commencement on 2 January 2026. The [Supreme Court's analysis](https://marinews.mahkamahagung.go.id/artikel/implikasi-uu-penyesuaian-pidana-terhadap-perbuatan-pidana-0NL) corroborates the amendments; the enactment is the controlling source. + +Annex II pp. 1–2: article 111(1), up to twelve years and/or category VI fine; 111(2), life or up to twenty years and/or increased fine; 114(1), life or up to twenty years and/or category VI fine; 114(2), death, life or up to twenty years and/or increased fine; 116(1), up to fifteen years and/or category VI fine; 116(2), death, life or up to twenty years and/or increased fine. There are no four-, five- or six-year special statutory prison floors in these amended penalties. + +The [official 2009 BNN text](https://jdih.bnn.go.id/internal/assets/assets/produk/UU/2009/10/UU_Nomor_35_tahun_2009.pdf) supplies the unchanged offence elements: articles 111(2) and 114(2) say **more than 1 kg OR more than five plants**, rendered as at least six plants. Five plants can still meet the independent weight criterion. Article 111 has no death alternative. Article 116(2)'s capital aggravation depends on death or permanent disability, not the plant-count test. + +The 2026 law's recast Criminal Code article 622 repeals article 113. Its recast article 610 covers production, import, export and distribution: basic Class I maximum fifteen years and/or category V fine; aggravated plant-form Class I **more than 1 kg OR more than five plants**, or non-plant Class I **more than 5 g**, permits death/life/up to twenty years and/or category VI fine. Profile text now distinguishes 610 from 111/114 instead of citing repealed 113 as current. + +Revised possession, cultivation, sharing, capital penalties, seeds and visitor guidance with inline citations. Added the 2 January history event. All six scores remain zero: long prison maximums, criminal use, prohibited growing and supply, and capital trafficking remain within their existing rubric levels. No mechanical score rise follows from deleting a mandatory floor. + +## 111 — Georgia: judgment narrower than a current blanket resin exemption + +Read the [full Georgian judgment 1/2/882](https://constcourt.ge/ka/judicial-acts?legal=20023) as well as the [court's English release](https://www.constcourt.ge/en/media/news/the-first-board-of-the-constit.html). The operative part explicitly addresses **article 260(1), (3) as in force before 1 May 2025**, for buying/possessing **0.1315 g resin** for personal use, including a prior drug conviction. It strikes imprisonment, leaves criminal liability intact, and takes effect on publication, 24 June 2026. The repeat-possession branch had already been addressed in 2022; the judgment terminates that part of the claim. + +The previously added profile text was too broad about which code was invalidated. The profile and new history entry now identify the pre-May-2025 code. Do not treat the ruling as full legalisation, an exemption for all resin quantities, or an amendment of the dried-herb five-gram threshold. Scores and partial status remain unchanged. + +## 112–113 — US Georgia and Alabama + +Both profiles already contained initial corrections at the start of this batch. Verified them against the [Georgia commission FAQ](https://www.gmcc.ga.gov/faqs), [SB 220 enacted status](https://www.legis.ga.gov/legislation/70559), [Georgia Code 16-12-234](https://law.justia.com/codes/georgia/title-16/chapter-12/article-9/part-3/section-16-12-234/), and [Alabama commission patient page](https://amcc.alabama.gov/patients/). The governor's signed-download URL supplied in the issue was unreachable; the enacted code and legislature are used instead. + +Georgia: effective 1 July 2026; approved medical flower for vaporization, 12,000 mg THC possession and 1,200 mg per package; no smoking, no vaporization at age 21 or younger, no public consumption. Registry and physician certification remain required. Changed medical status to **legal**, since the operating programme now permits medical flower and is no longer oil/pharmaceutical-only. Kept access at **one**: eligibility and registry constraints remain, and this review does not establish the rubric's easy-medical-access level. Added a state history event and primary citations. + +Alabama: first Montgomery sale 4 June; Talladega 28 August; Athens 14 September. No assumption that other licensed or announced sites are operating. Residency, qualifying condition, physician recommendation and card required. Raw flower and smoking/vaping products prohibited. **Limited** medical label remains appropriate for pharmaceutical-only access; access **one**, already corrected before this batch, describes actual restricted supply. Added the first-sales event. State events remain unscored on the national timeline, as required by the federation rule. + +## 114 — Mississippi + +Read the [2026 state medical board's statutory compilation](https://www.msbml.ms.gov/sites/default/files/2026%20Law%20Documents/Mississippi_Medical_Practice_Act.pdf), printed pp. 88–89, section 41-29-139(c)(2)(A)–(B). First ordinary <=30 g: $100–250; second conviction within two years: up to sixty days (the previous five-day floor was also wrong). The additional vehicle offence applies to an **operator**, for **>1 g to <=30 g** on their person or knowingly kept/allowed in the passenger area, including the glove compartment, with up to ninety days and/or $1,000. The trunk and non-passenger area of a trunkless vehicle are excluded from that additional offence. + +For >30 g to <250 g, state the alternatives directly: up to one year county jail and/or $1,000, or up to three years state custody and/or $3,000. Removed the categorical “all above thirty grams is felony” shortcut. + +**Enforcement four → two**, a correction to existing exposure: “fines or diversion only” cannot describe the first-offence vehicle imprisonment option. The generated quick answer now permits prison. Possession three stays for the ordinary fine-only small-possession rule. The state's total falls from 24 to 20; no national score changes or invented 2026 legal-change date. + +## 115–117 — Michigan, Pennsylvania, Kansas + +- **Michigan:** [state judiciary benchbook](https://www.courts.michigan.gov/4a8168/siteassets/publications/benchbooks/csbb/csbbresponsivehtml5.zip/CSBB/Ch_8_Marijuana/Scope_of_Michigan_Regulation_and_Taxation_of_Marihuana_Act_(MRTMA).htm), quoting 333.27955(1)(b) and 333.27954(1)(f), (i). Residence allowance is ten ounces **plus** homegrown harvest; twelve plants per residence, secured/out of public view; excess above 2.5 ounces secured. Carry limit 2.5 ounces, at most fifteen grams concentrate. No inferred unrestricted off-premises possession. Scores remain within existing legal capped-possession/grow levels. +- **Pennsylvania:** [official Drug Act](https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1972/0/0064..PDF) section 13(a)(30), (f)(2), ordinary manufacture maximum five years and/or $15,000, with no 2½-year floor. [Van Aulen (2008)](https://law.justia.com/cases/pennsylvania/superior-court/2008/s29044-08.html) confirms personal-use growing can constitute manufacture. Its actual sentence was below the supposed 2½-year mandatory floor. The ordinary cap is distinguished from higher bulk/repeat penalties; score one retained, as small manufacture has a lower ceiling than the >1,000-pound class in (f)(1.1). Medical home growing remains prohibited, supported by the existing programme/penalty source, not misattributed to a 2008 case. +- **Kansas:** read official [2-3901](https://kslegislature.gov/b2025_26/laws/002_000_0000_chapter/002_039_0000_article/002_039_0001_section/002_039_0001_k/), [2-3908](https://www.kslegislature.gov/b2025_26/laws/002_000_0000_chapter/002_039_0000_article/002_039_0008_section/002_039_0008_k/), [65-6235](https://kslegislature.gov/b2025_26/laws/065_000_0000_chapter/065_062_0000_article/065_062_0035_section/065_062_0035_k/) and [21-5706(d)](https://www.ksrevisor.gov/statutes/chapters/ch21/021_057_0006.html). Final compliant hemp products <=0.3% THC by weight, subject to prohibited product types. Medical oil defence is THC <=5% **of CBD concentration**, independent laboratory verification, qualifying condition and carried Kansas physician letter within fifteen months. It is an affirmative defence, not a dispensary licence or blanket possession authorisation. Medical none/access zero retained. + +State segment text now supports numeric inline citations using the existing citation renderer. Plain preview segment values have marks stripped. Existing state texts without marks retain automatic whole-text citations. Updated the writing guide with this syntax. + +## 118 — charts + +- Chart 07 names the dated denominator, places the omitted unknown-date count next to the headline, and retains the count in its source note. Chart 09 expressly limits its colonial sample to dated first restrictions. +- Chart 10 remains a **history-topics stream**, with medical/hemp and enforcement separate. Removed the directional easing-vs-tightening aggregate; the width now describes recorded entries, not how much actually happened. Chart 08 continues to count signed scored changes. +- Charts 34/43 consistently describe the **largest religious group**, matching the OWID categorical field, without fabricating >50% shares. +- Chart 26 describes the observed Pearson correlation and mixed observation years without causal claims about price effects. +- Four development measures without matching maps have non-link rows. Only the internet measure points to the internet map; hover copy promises a destination only for actual links. Shared row styling preserves layout. +- Added regression tests for dated denominators, category semantics, actual dataset map-field destinations, and claim wording. Build/render checks cover non-link rows and citation targets. + +## Validation + +- `node --test scripts/chart-semantics.test.cjs`: all four targeted regression tests pass. +- Full Astro build: 4,061 pages, successful. Render checks pass for all affected country/state pages and history entries, numbered citation targets, clean JSON/CSV exports, Mississippi's “Fine or prison” quick answer, Georgia's “Medical: Legal” label, and the corrected chart wording and destinations. +- History object audit: only the six additions and two listed revisions changed; national score vectors are unchanged. Added events have valid tags and explicit unscored reasons where required. +- `node --test scripts/history-scope.test.cjs`: 34 pass, two existing failures. The Hong Kong test expects digits “15 years” where the profile writes “fifteen years”; the Kuwait test expects the law number in the consumption paragraph where it is recorded elsewhere. Neither profile nor this test file changed in this batch (`git diff --exit-code HEAD -- countries/hk.yaml countries/kw.yaml scripts/history-scope.test.cjs` passes). +- `git diff --check` passes. The temporary `site/` build is deleted after verification; downloaded sources, extracts and logs are retained.
scripts/chart-semantics.test.cjs +49 @@ -0,0 +1,49 @@ +const { test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const yaml = require('js-yaml'); +const semantics = import('../src/lib/chart-semantics.js'); + +test('first restriction statistics exclude estimates from their denominator', async () => { + const { firstRestrictionSample } = await semantics; + const sample = firstRestrictionSample([{ ch: { date: '1921' } }, { ch: { date: '1937' } }, { ch: { date: '1925', estimate: true } }]); + assert.equal(sample.dated.length, 2); + assert.equal(sample.undated, 1); + assert.deepEqual(sample.dated.map((x) => x.year), [1921, 1937]); + const page = fs.readFileSync('src/pages/charts.astro', 'utf8'); + assert.match(page, /Among \{dated.length\} countries with dated first restrictions/); + assert.match(page, /Only former colonies with a dated first restriction are counted/); +}); + +test('history topic counts keep medical, enforcement and legal-direction topics separate', async () => { + const { topicCounts, HISTORY_TOPICS } = await semantics; + const fixture = ['medical', 'hemp', 'enforcement', 'easing', 'tightening'].map((category) => ({ category, date: '2026' })); + fixture.push({ category: 'ban', date: '1925', estimate: true }); + const counts = topicCounts(fixture, [1920, 2020]); + const count = (id) => counts[HISTORY_TOPICS.findIndex((g) => g.id === id)]; + assert.deepEqual(count('medical'), [0, 2]); + assert.deepEqual(count('enforcement'), [0, 1]); + assert.deepEqual(count('easing'), [0, 1]); + assert.deepEqual(count('tightening'), [0, 1]); + assert.doesNotMatch(fs.readFileSync('src/pages/charts.astro', 'utf8'), /easing outweighs tightening|easeNow|tightNow/); +}); + +test('development links match the field actually mapped', async () => { + const { DEVELOPMENT_MEASURES } = await semantics; + const datasets = yaml.load(fs.readFileSync('datasets/datasets.yaml', 'utf8')); + const development = Array.isArray(datasets) ? datasets.find((d) => d.id === 'development') : datasets.development; + for (const measure of DEVELOPMENT_MEASURES) { + if (measure.href) { + assert.equal(measure.field, development.map.field); + assert.equal(measure.href, `map/${development.map.slug}/`); + } else assert.notEqual(measure.field, 'internet'); + } + assert.equal(DEVELOPMENT_MEASURES.filter((m) => m.href).length, 1); +}); + +test('chart claims match categorical religion data and observational price data', () => { + const page = fs.readFileSync('src/pages/charts.astro', 'utf8'); + assert.doesNotMatch(page, /Muslim.majority|Christian majority|does not make cannabis dearer|have no majority faith/); + assert.match(page, /Muslims are the largest group/); + assert.match(page, /Across \{priced.length\} countries, cannabis price and the score show/); +});
src/components/CountryArticle.astro +8 @@ -16,5 +16,5 @@ import SourceCitation from "./SourceCitation.astro"; import Cited from "./Cited.astro"; import References from "./References.astro"; -import { references, citeParts } from "../lib/cite.js"; +import { references, citeParts, citedKeys } from "../lib/cite.js"; import { SHOW_PRICES } from "../lib/config.js"; import { PLANTING_STATUS, STATUS_SECTIONS, PLANTING_TRADE } from "../lib/segment-ids.js"; @@ -50,4 +50,9 @@ const scoreRefs = references("sc"), ctxRefs = references("cx"); const partsOf = (block, refs, where) => citeParts(block.cite.text, refs, (k) => block.cite.keys.includes(k) && block.cite.of(k), block.cite.keys, `countries/${c.slug}.yaml: ${where}`); const segParts = d ? d.segments.map((seg, i) => seg && partsOf(seg, scoreRefs, SEGMENTS[i].id)) : []; +const unitRefs = references("unit"); +const unitParts = sub ? sub.segCite.map((text, i) => citeParts(text, unitRefs, + (k) => /^[1-9]\d*$/.test(k) && sub.sources[+k - 1], + citedKeys(text) ?? sub.sources.map((_, i) => String(i + 1)), + `countries/${c.slug}/${sub.id}.yaml: ${SEGMENTS[i].id}`)) : []; const ctxParts = d ? Object.fromEntries(d.context.filter(Boolean).map((x) => [x.key, partsOf(x, ctxRefs, x.key)])) : {}; const INCB = ["International Narcotics Control Board — Travellers carrying medicines containing controlled substances", "https://www.incb.org/incb/en/travellers/index.html", null, "https://www.incb.org/incb/en/travellers/index.html"]; @@ -294,5 +299,5 @@ const culture = cultureOf(c); </summary> <div class="why"> - {sub.seg && <p>{sub.seg[i]}</p>} + {sub.seg && <p><Cited parts={unitParts[i]} /></p>} </div> </details> @@ -300,8 +305,5 @@ const culture = cultureOf(c); {sub && ( <section class="c-unit-sources"> - <h2 class="d-h">Sources</h2> - <ul class="srcs"> - {sub.sources.map((source) => <SourceCitation source={source} />)} - </ul> + <References refs={unitRefs} /> </section> )}
src/lib/chart-semantics.js +29 @@ -0,0 +1,29 @@ +// First-restriction quartiles describe the dated sample, never the estimated dates. +export function firstRestrictionSample(firsts) { + return { + undated: firsts.filter(({ ch }) => ch.estimate).length, + dated: firsts.filter(({ ch }) => !ch.estimate).map((f) => ({ ...f, year: +String(f.ch.date).slice(0, 4) })), + }; +} + +// Topic groups include unscored reports and events. They do not measure legal direction. +export const HISTORY_TOPICS = [ + { id: "tightening", label: "Bans and tightening", cats: ["ban", "tightening", "death"], color: "var(--t1)" }, + { id: "enforcement", label: "Enforcement", cats: ["enforcement"], color: "var(--t0)" }, + { id: "easing", label: "Easing and legalisation", cats: ["easing", "legalisation"], color: "var(--t5)" }, + { id: "medical", label: "Medical and hemp", cats: ["medical", "hemp"], color: "var(--t4)" }, + { id: "debate", label: "Debate and culture", cats: ["debate", "culture"], color: "var(--t3)" }, + { id: "law", label: "Treaties and other law", cats: ["international", "other"], color: "var(--muted)" }, +]; +export function topicCounts(changes, decades) { + return HISTORY_TOPICS.map((g) => decades.map((d) => changes.filter((ch) => g.cats.includes(ch.category) && !ch.estimate && +String(ch.date).slice(0, 4) >= d && +String(ch.date).slice(0, 4) < d + 10).length)); +} + +// Only internet has a dedicated map. Other development measures remain readable without a link. +export const DEVELOPMENT_MEASURES = [ + { label: "People using the internet", field: "internet", href: "map/internet/" }, + { label: "Living in towns and cities", field: "urban", href: null }, + { label: "Aged 65 or over", field: "aged_65", href: null }, + { label: "Life expectancy", field: "life_expectancy", href: null }, + { label: "Enrolled in higher education", field: "higher_education", href: null }, +];
src/lib/countries.js +2 @@ -161,5 +161,6 @@ export function subunitsOf(id) { reviewed: isoDate(data.updated), worldRank: 1 + countries.filter((c) => c.raw > raw).length, - seg: SEGMENTS.map((seg) => data.segments[seg.id]), // six explanations, in SEGMENTS order + seg: SEGMENTS.map((seg) => stripCites(data.segments[seg.id])), + segCite: SEGMENTS.map((seg) => data.segments[seg.id]), // six explanations, in SEGMENTS order sources: [...data.sources.map(pair), ...groupSources], // the unit's own source first use: data.use ? { ...data.use, source: pair(data.use.source) } : null, // past-year use from its country's survey
src/pages/charts.astro +21 @@ -5,4 +5,5 @@ // Every chart leads on: a year to the history, a country to its profile, a region to the rankings, // a dataset to its map. A small script at the end adds hover cards with the detail behind a mark. +import { firstRestrictionSample, HISTORY_TOPICS, topicCounts, DEVELOPMENT_MEASURES } from "../lib/chart-semantics.js"; import Base from "../layouts/Base.astro"; import AverageChart from "../components/AverageChart.astro"; @@ -107,6 +108,5 @@ const strength = Math.abs(r) < 0.3 ? "only weakly" : Math.abs(r) < 0.7 ? "modera const B0 = 1850; const firsts = countries.map((c) => ({ c, ch: changes.findLast((ch) => ch.country === c && ch.score) })).filter((f) => f.ch); -const undated = firsts.filter((f) => f.ch.estimate).length; -const dated = firsts.filter((f) => !f.ch.estimate).map((f) => ({ ...f, year: +String(f.ch.date).slice(0, 4) })); +const { undated, dated } = firstRestrictionSample(firsts); const banYears = dated.map((f) => f.year).sort((a, b) => a - b); const quart = (q) => banYears[Math.floor((banYears.length - 1) * q)]; @@ -197,14 +197,7 @@ const peak2020 = ridges.at(-1).d.indexOf(Math.max(...ridges.at(-1).d)); // ── What the history is about, decade by decade: a streamgraph of its entries by kind ── -const STREAM = [ - { id: "tightening", label: "Bans and tightening", cats: ["ban", "tightening", "death"], color: "var(--t1)" }, - { id: "enforcement", label: "Enforcement", cats: ["enforcement"], color: "var(--t0)" }, - { id: "easing", label: "Easing and legalisation", cats: ["easing", "legalisation"], color: "var(--t5)" }, - { id: "medical", label: "Medical and hemp", cats: ["medical", "hemp"], color: "var(--t4)" }, - { id: "debate", label: "Debate and culture", cats: ["debate", "culture"], color: "var(--t3)" }, - { id: "law", label: "Treaties and other law", cats: ["international", "other"], color: "var(--muted)" }, -]; +const STREAM = HISTORY_TOPICS; const D0 = 1860, decades = Array.from({ length: Math.floor(NOW / 10) - D0 / 10 + 1 }, (_, i) => D0 + i * 10); -const streamCounts = STREAM.map((g) => decades.map((d) => changes.filter((ch) => g.cats.includes(ch.category) && !ch.estimate && +String(ch.date).slice(0, 4) >= d && +String(ch.date).slice(0, 4) < d + 10).length)); +const streamCounts = topicCounts(changes, decades); const decadeTotals = decades.map((_, i) => streamCounts.reduce((s, row) => s + row[i], 0)); const streamMax = Math.max(...decadeTotals); @@ -228,5 +221,4 @@ const streams = (() => { })(); const peakDecade = decades[decadeTotals.indexOf(streamMax)]; -const easeNow = streamCounts[2].at(-1) + streamCounts[3].at(-1), tightNow = streamCounts[0].at(-1) + streamCounts[1].at(-1); // names beside scatter dots, the most telling first, unless one would land on a name already @@ -265,6 +257,4 @@ const corr = (pts) => { const priceFit = corr(priced); const PX1 = Math.ceil(Math.max(...priced.map((p) => p.x)) / 10) * 10, PY1 = Math.ceil(Math.max(...priced.map((p) => p.y)) / 5) * 5; -const priceMedian = (pred) => median(priced.filter(pred).map((p) => p.y)); -const priceStrict = priceMedian((p) => p.x < 15), priceMild = priceMedian((p) => p.x >= 15); const priceNamed = pickLabels([...priced].sort((a, b) => Math.abs(b.y - median(priced.map((q) => q.y))) - Math.abs(a.y - median(priced.map((q) => q.y)))).map((p) => ({ key: p.c.id, x: pct(p.x, 0, PX1), y: 100 - pct(p.y, 0, PY1) }))); @@ -631,9 +621,5 @@ const MEASURES = [ ["Freedom and the state", "Government effectiveness", "#state-capacity", (c) => latestSince(c.series.government_effectiveness, "score", 2020)?.score], ["Wealth and development", "Income per person (log)", "map/income/", (c) => logOr(latestSince(c.series.gdp, "gdp_ppp", 2018)?.gdp_ppp)], - ["Wealth and development", "People using the internet", "map/internet/", (c) => dev(c, "internet")], - ["Wealth and development", "Living in towns and cities", "map/internet/", (c) => dev(c, "urban")], - ["Wealth and development", "Aged 65 or over", "map/internet/", (c) => dev(c, "aged_65")], - ["Wealth and development", "Life expectancy", "map/internet/", (c) => dev(c, "life_expectancy")], - ["Wealth and development", "Enrolled in higher education", "map/internet/", (c) => dev(c, "higher_education")], + ...DEVELOPMENT_MEASURES.map(({ label, href, field }) => ["Wealth and development", label, href, (c) => dev(c, field)]), ["Wealth and development", "Research papers per person (log)", "#research", (c) => { const r = research.find((x) => x.c === c); return r ? Math.log10(r.per) : null; }], ["Use and drugs", "Adults who use cannabis", "#use", (c) => (c.use && !c.use.estimate ? c.use.prevalence : null)], @@ -652,7 +638,7 @@ const MEASURES = [ ["Markets and enforcement", "Cannabis seized per person (log)", "map/cannabis-seizures/", (c) => { const kg = latestSince(c.series.seizures, "total_kg", 2018)?.total_kg; return kg != null ? Math.log10(1 + perPerson(c, kg, 1e6)) : null; }], ["Culture and history", "Cannabis in the news (log)", "#in-the-news", (c) => { const r = latestSince(c.series.news, "share", 2024); return r && r.share > 0 ? Math.log10(r.share) : null; }], - ["Culture and history", "Christian majority", "#religion", (c) => faithIs(c, "Christians")], + ["Culture and history", "Christians are the largest group", "#religion", (c) => faithIs(c, "Christians")], ["Culture and history", "No religion is the largest group", "#religion", (c) => faithIs(c, "Religiously Unaffiliated")], - ["Culture and history", "Muslim majority", "#religion", (c) => faithIs(c, "Muslims")], + ["Culture and history", "Muslims are the largest group", "#religion", (c) => faithIs(c, "Muslims")], ["Culture and history", "Opinion that using marijuana is not immoral", "#opinion", (c) => (c.datasets.pew_marijuana ? c.datasets.pew_marijuana.acceptable + c.datasets.pew_marijuana.not_moral : null)], ["Culture and history", "Years under prohibition since 1860", "#stripes", (c) => bannedYears.get(c.id)], @@ -1022,6 +1008,6 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <section class="ch" id="first-bans"> <p class="ch-kicker"><a href="#first-bans">{kick("first-bans")}</a></p> - <h2>Half the world's countries first restricted cannabis between {banQ1} and {banQ3}</h2> - <p class="ch-dek">Each dot is a country, placed at the year of its first recorded rule on cannabis and coloured by its score today. The middle year is {banMid}. Some came under a colonial power's law before they were countries.</p> + <h2>Among {dated.length} countries with dated first restrictions, the middle half falls between {banQ1} and {banQ3}</h2> + <p class="ch-dek">{undated} countries with unknown first-restriction dates are left out. Each dot is a country, placed at the year of its first recorded rule on cannabis and coloured by its score today. The middle year is {banMid}. Some came under a colonial power's law before they were countries.</p> <div class="ch-frame ch-swarm" data-no-preview> {swarms.map((g) => ( @@ -1079,5 +1065,5 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <p class="ch-kicker"><a href="#empire">{kick("empire")}</a></p> <h2>{bigEmpire.before} of the {bigEmpire.dots.length} former colonies of the {bigEmpire.r.name} had a rule on cannabis before it made one at home</h2> - <p class="ch-dek">For each former colonial power, a row of its former colonies, each placed at the year of its first recorded rule on cannabis and coloured by its score today; the black line is the year the ruler first restricted cannabis at home. Many of these first rules were the ruler's own law, made for the colony, and stayed on the books after independence.</p> + <p class="ch-dek">Only former colonies with a dated first restriction are counted here. For each former colonial power, a row of those colonies, each placed at the year of its first recorded rule on cannabis and coloured by its score today; the black line is the year the ruler first restricted cannabis at home. Many of these first rules were the ruler's own law, made for the colony, and stayed on the books after independence.</p> <div class="ch-frame ch-swarm ch-empire" data-no-preview> {empires.map((e) => ( @@ -1102,6 +1088,6 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <section class="ch" id="stream"> <p class="ch-kicker"><a href="#stream">{kick("stream")}</a></p> - <h2>The {peakDecade}s fill the history most; this decade, easing outweighs tightening {easeNow} to {tightNow}</h2> - <p class="ch-dek">Every dated entry in the history, laws and raids, rulings and reports, treaties and books, counted by decade and kind. The wider the stream, the more happened. The 2020s are not over.</p> + <h2>The {peakDecade}s have the most recorded history entries</h2> + <p class="ch-dek">Every dated entry in the history, laws and raids, rulings and reports, treaties and books, counted by decade and kind. The wider the stream, the more entries we have recorded. These are topics, not counts of laws becoming stricter or more lenient. The 2020s are not over.</p> <div class="ch-frame ch-stream" data-no-preview> <div class="ch-plot"> @@ -1492,6 +1478,6 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <section class="ch" id="price"> <p class="ch-kicker"><a href="#price">{kick("price")}</a></p> - <h2>{Math.abs(priceFit.r) < 0.3 ? "A harsher law does not make cannabis dearer" : priceFit.r < 0 ? "Where the law is harsher, cannabis costs more" : "Where the law is milder, cannabis costs more"}: €{priceStrict.toFixed(2)} a gram under prohibition, €{priceMild.toFixed(2)} elsewhere</h2> - <p class="ch-dek">Each dot is a European country: across, its cannabis score; up, the typical street price of a gram of herb in the latest year reported. If prohibition worked by making cannabis scarce, the dots on the left would sit higher.</p> + <h2>Across {priced.length} countries, cannabis price and the score show {Math.abs(priceFit.r) < 0.3 ? "little" : Math.abs(priceFit.r) < 0.7 ? "moderate" : "strong"} correlation (r = {priceFit.r.toFixed(2)})</h2> + <p class="ch-dek">Each dot is a European country: across, its cannabis score; up, the typical street price of a gram of herb in the latest year reported. The observations come from different years since 2018 and show an association across countries; they cannot isolate the effect of the law on price.</p> <div class="ch-frame ch-scatter" data-no-preview> <div class="ch-y">{Array.from({ length: PY1 / 5 + 1 }, (_, i) => i * 5).map((t) => <span style={`top:${100 - pct(t, 0, PY1)}%`}>€{t}</span>)}</div> @@ -1686,5 +1672,5 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <section class="ch" id="religion"> <p class="ch-kicker"><a href="#religion">{kick("religion")}</a></p> - <h2>Faith and the law: no Muslim-majority country scores above {Math.round(muslim.max.raw)}; the freest are mostly Christian or have no majority faith</h2> + <h2>Where Muslims are the largest religious group, no country scores above {Math.round(muslim.max.raw)}</h2> <p class="ch-dek">Each dot is a country, in the row of its largest religious group (Pew's 2020 estimate) and placed along the row by its cannabis score. The bar is each group's middle. Religion is one force among many: colonial law, wealth and the year a country met the drug treaties all play a part.</p> <div class="ch-frame ch-faith" data-no-preview> @@ -1909,17 +1895,17 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` <p class="ch-kicker"><a href="#what-goes-with-it">{kick("what-goes-with-it")}</a></p> <h2>Across the world, {strongest.label.replace(/ \(.*\)$/, "").toLowerCase()} goes with cannabis freedom most closely (r = {strongest.r.toFixed(2)}); in fewer countries, {strongestNarrow.label.replace(/ \(.*\)$/, "").toLowerCase()} does even more (r = {strongestNarrow.r.toFixed(2)})</h2> - <p class="ch-dek">How closely each of {measures.length} measures moves with the cannabis score across the countries that have it: 1 would mean they rise together exactly, −1 that one falls as the other rises, 0 no link at all. A yes-or-no measure, such as a Muslim majority, counts 1 for yes. A link is not a cause, and many of these measures move with each other; those marked Europe cover few countries. Click a bar for its chart or map.</p> + <p class="ch-dek">How closely each of {measures.length} measures moves with the cannabis score across the countries that have it: 1 would mean they rise together exactly, −1 that one falls as the other rises, 0 no link at all. A yes-or-no measure, such as Muslims being the largest religious group, counts 1 for yes. A link is not a cause, and many of these measures move with each other; those marked Europe cover few countries. Linked bars open the matching chart or map.</p> <ol class="ch-corr" data-no-preview> {MEASURE_GROUPS.map(({ g, list }) => <> <li class="ch-corr-group">{g}</li> - {list.map((m) => ( + {list.map((m) => { const Row = m.href ? "a" : "div"; return ( <li> - <a href={m.href.startsWith("#") ? m.href : `${base}${m.href}`} data-measure={measures.indexOf(m)}> + <Row class="ch-corr-row" href={m.href ? (m.href.startsWith("#") ? m.href : `${base}${m.href}`) : undefined} data-measure={measures.indexOf(m)}> <span class="ch-bar-name">{m.label} <small>{m.n}</small></span> <span class="ch-corr-track"><i class="ch-corr-zero"></i><span class="ch-corr-bar" style={`${m.r >= 0 ? `left:50%;width:${m.r * 50}%` : `right:50%;width:${-m.r * 50}%`};--c:${m.r >= 0 ? "var(--t5)" : "var(--t1)"}`}></span></span> <span class="ch-bar-num">{m.r > 0 ? "+" : "−"}{Math.abs(m.r).toFixed(2)}</span> - </a> + </Row> </li> - ))} + ); })} </>)} <li class="ch-corr-axis" aria-hidden="true"><span></span><span class="ch-corr-track"><span style="left:0">−1</span><span style="left:50%">0</span><span style="left:100%">+1</span></span><span></span></li> @@ -2312,5 +2298,5 @@ const kick = (id) => { const i = sections.findIndex(([x]) => x === id); return ` const [label, r, n] = D.measures[+a.dataset.measure]; const words = Math.abs(r) < 0.2 ? "next to no link" : Math.abs(r) < 0.4 ? "a weak link" : Math.abs(r) < 0.6 ? "a moderate link" : "a strong link"; - return `<b>${esc(label)}</b><span class="ch-tip-row">Correlation with the score<em>${r > 0 ? "+" : "−"}${Math.abs(r).toFixed(2)}</em></span><span class="ch-tip-sub">${words}, ${r >= 0 ? "rising together" : "one falls as the other rises"}; ${n} countries</span><span class="ch-tip-go">See its chart →</span>`; + return `<b>${esc(label)}</b><span class="ch-tip-row">Correlation with the score<em>${r > 0 ? "+" : "−"}${Math.abs(r).toFixed(2)}</em></span><span class="ch-tip-sub">${words}, ${r >= 0 ? "rising together" : "one falls as the other rises"}; ${n} countries</span>${a.matches("a") ? '<span class="ch-tip-go">See its chart or map →</span>' : ""}`; })); // Wikipedia readers: the month under the pointer
src/styles/global.css +2 @@ -2769,5 +2769,5 @@ a.ch-law-cell:hover i, a.ch-law-cell:focus-visible i { transform: scale(1.08); b .ch-corr li { border-bottom: 1px solid var(--border); } .ch-corr li.ch-corr-group { padding: 18px 0 6px; border-bottom: 1px solid var(--text); font: 400 11px var(--mono); text-transform: uppercase; letter-spacing: .08em; color: var(--muted); } -.ch-corr li a, .ch-corr-axis { display: grid; grid-template-columns: 280px minmax(0, 1fr) 64px; gap: 14px; align-items: center; padding: 7px 0; color: var(--text); } +.ch-corr .ch-corr-row, .ch-corr-axis { display: grid; grid-template-columns: 280px minmax(0, 1fr) 64px; gap: 14px; align-items: center; padding: 7px 0; color: var(--text); } .ch-corr li a:hover { background: color-mix(in srgb, var(--text) 5%, transparent); } .ch-corr-track { position: relative; height: 16px; } @@ -2865,5 +2865,5 @@ a.ch-db-track:hover { background: color-mix(in srgb, var(--text) 6%, transparent .ch-party-row { grid-template-columns: 96px minmax(0, 1fr); } .ch-party-name { font-size: 11.5px; } - .ch-corr li a, .ch-corr-axis { grid-template-columns: 120px minmax(0, 1fr) 46px; gap: 8px; } + .ch-corr .ch-corr-row, .ch-corr-axis { grid-template-columns: 120px minmax(0, 1fr) 46px; gap: 8px; } .ch-corr .ch-bar-name { font-size: 11.5px; } .ch-faith { --lane: 5px; }