Cannabis Freedom Index

Changelog b17dfc4tree, with Claude Opus 5.5

Country profile: chips on the context title line, arrows kept with their links

A context section's status chips sit to the right of its title. Link texts ending in an arrow use a no-break space, so the arrow never wraps onto a line of its own.

3 files of code, design or docs +20 −15 lines

Code, design and documents 3 files

src/components/CountryArticle.astro +7 −7
@@ -205,5 +205,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
       <p class="c-disputed"><strong>{c.territory.kind}.</strong> {c.territory.note} See also <a href={`${base}country/${c.territory.country.slug}/`} data-country={c.territory.country.id}>{c.territory.country.flag} {c.territory.country.name}</a>.</p>
     )}
-    <h2 class="d-h">In short <span><a href={`${base}can-i/`}>all countries →</a></span></h2>
+    <h2 class="d-h">In short <span><a href={`${base}can-i/`}>all countries →</a></span></h2>
     <ul class="answers">
       {answers.map((x) => (
@@ -234,5 +234,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
   {glance && (
     <section class="c-sec c-intro" id="overview">
-      <h2 class="d-h">Cannabis in {theName(sub ? sub.name : c.name)} <span>not part of the score{datasetCount > 0 && <> · <a href="#datasets">all {datasetCount} datasets ↓</a></>}</span></h2>
+      <h2 class="d-h">Cannabis in {theName(sub ? sub.name : c.name)} <span>not part of the score{datasetCount > 0 && <> · <a href="#datasets">all {datasetCount} datasets ↓</a></>}</span></h2>
       <CountryIntro c={c} sub={sub} wordRefs={wordRefs} />
     </section>
@@ -333,5 +333,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
               ))}
             </ol>
-            <p><a href={`${base}compare/?c=${compareIds.join(",")}`}>Compare {landNeighbours.length ? "with neighbours" : "them"} →</a></p>
+            <p><a href={`${base}compare/?c=${compareIds.join(",")}`}>Compare {landNeighbours.length ? "with neighbours" : "them"} →</a></p>
           </div>
         )}
@@ -418,5 +418,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
   {culture.length > 0 && (
     <section class="c-sec c-atlas" id="culture">
-      <h2 class="d-h">Culture <span><a href={`${base}culture/`}>the atlas →</a></span></h2>
+      <h2 class="d-h">Culture <span><a href={`${base}culture/`}>the atlas →</a></span></h2>
       {sub && <p class="d-hint">These belong to the whole country, not to {sub.name} alone.</p>}
       {/* cards with the entry's picture; past the first eight they wait behind "Show all" */}
@@ -447,5 +447,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
   {facts.length > 0 && (
     <section class="c-sec c-dyk" id="did-you-know">
-      <h2 class="d-h">Did you know? <span><a href={`${base}did-you-know/`}>all cases →</a></span></h2>
+      <h2 class="d-h">Did you know? <span><a href={`${base}did-you-know/`}>all cases →</a></span></h2>
       <ol class="dyk-facts dyk-all">
         {facts.map((f) => (
@@ -453,5 +453,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
             <p class="dyk-kicker">{f.kicker}</p>
             <p class="dyk-text"><FactText parts={f.parts} here={c.id} /></p>
-            {f.culture ? <a class="dyk-more" href={`${base}${f.culture.url}`}>Read the entry →</a> : f.history && <a class="dyk-more" href={`${base}history/${f.history.id}/`}>The full story →</a>}
+            {f.culture ? <a class="dyk-more" href={`${base}${f.culture.url}`}>Read the entry →</a> : f.history && <a class="dyk-more" href={`${base}history/${f.history.id}/`}>The full story →</a>}
           </li>
         ))}
@@ -470,5 +470,5 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x)));
     <section class="c-sec" id="history">
       <CountryChanges history={history} unitLabel={!sub && group ? group.label : null} showUnit={!sub} scoreLine={!sub}
-        more={sub ? <>Only the entries about {sub.name}. <a href={`${countryUrl}#history`}>All {nationalCount} entries on the national page →</a></> : null} />
+        more={sub ? <>Only the entries about {sub.name}. <a href={`${countryUrl}#history`}>All {nationalCount} entries on the national page →</a></> : null} />
     </section>
   )}

src/components/CountryIntro.astro +8 −8
@@ -31,5 +31,5 @@ const ord = (n) => n + (n % 100 >= 11 && n % 100 <= 13 ? "th" : ["th", "st", "nd
 const rankWord = (n, word) => (n === 1 ? word : `${ord(n)} ${word}`);
 const median = (xs) => { const s = [...xs].sort((a, b) => a - b), m = s.length >> 1; return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2; };
-// 48,000,000 → "48 million", 770,000 → "770,000"
+// 48,000,000 → "48 million", 770,000 → "770,000"
 const people = (n) => (n >= 1e6 ? `${+(n / 1e6).toPrecision(2)} million` : n.toLocaleString("en-GB"));
 const name = theName(sub ? sub.name : c.name);
@@ -41,5 +41,5 @@ const unitUse = sub?.use ?? null;
 const useFrom = use?.estimate_from ? countries.find((x) => x.id === use.estimate_from.toUpperCase()) : null;
 const share = use ? use.prevalence : unitUse?.share;
-const pct = (n) => `${(+n).toFixed(1)}%`; // 26.38 → "26.4%", 9 → "9.0%"
+const pct = (n) => `${(+n).toFixed(1)}%`; // 26.38 → "26.4%", 9 → "9.0%"
 const ages = use ? useAges(use) : unitUse?.ages;
 const users = use ? use.users : unitUse?.users;
@@ -118,5 +118,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
                 : useFrom
                 ? <>{useFrom.name}'s figure from the <a href="https://www.unodc.org/unodc/en/data-and-analysis/world-drug-report-2026-annex.html" target="_blank" rel="noopener noreferrer">UNODC World Drug Report 2026</a>; the population aged 15–64 is this place's total times {useFrom.name}'s share of those ages</>
-                : <>A median computed on this site from surveyed countries in {c.region}, using <a href="https://www.unodc.org/unodc/en/data-and-analysis/world-drug-report-2026-annex.html" target="_blank" rel="noopener noreferrer">UNODC World Drug Report 2026</a> figures</>}{use.users != null && <>. Population from the <a href="https://data.worldbank.org/" target="_blank" rel="noopener noreferrer">World Bank</a>, aged {useAges({ ages: use.population_ages || use.ages })}</>}. <a href={`${base}sources/#dataset-cannabis_use`}>The whole dataset →</a></SourceTip>
+                : <>A median computed on this site from surveyed countries in {c.region}, using <a href="https://www.unodc.org/unodc/en/data-and-analysis/world-drug-report-2026-annex.html" target="_blank" rel="noopener noreferrer">UNODC World Drug Report 2026</a> figures</>}{use.users != null && <>. Population from the <a href="https://data.worldbank.org/" target="_blank" rel="noopener noreferrer">World Bank</a>, aged {useAges({ ages: use.population_ages || use.ages })}</>}. <a href={`${base}sources/#dataset-cannabis_use`}>The whole dataset →</a></SourceTip>
         : <SourceTip>{unitUse.source[1] ? <a href={unitUse.source[1]} target="_blank" rel="noopener noreferrer">{unitUse.source[0]}</a> : unitUse.source[0]}</SourceTip>}
     </div>
@@ -134,5 +134,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
           ))}
         </ol>
-        <p class="intro-note">Past-year use, latest survey of each. Survey years and ages differ. <a href={`${base}map/${viewByMetric.prevalence.slug}/`}>On the map →</a></p>
+        <p class="intro-note">Past-year use, latest survey of each. Survey years and ages differ. <a href={`${base}map/${viewByMetric.prevalence.slug}/`}>On the map →</a></p>
       </div>
     )}
@@ -148,5 +148,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
           {pewParts.map(([label, v, color]) => <li><i class="sw" style={`background:${color}`}></i>{label} <b>{v}%</b></li>)}
         </ul>
-        <p class="intro-note">The {pewPlace <= pewList.length / 2 ? rankWord(pewPlace, "most") : rankWord(pewLeast, "least")} disapproving of the {pewList.length} countries surveyed, where the median is {pewMedian}%.{PEW.notes[c.slug] && ` ${PEW.notes[c.slug]}`} <a href={mapHref("pew_marijuana")}>On the map →</a></p>
+        <p class="intro-note">The {pewPlace <= pewList.length / 2 ? rankWord(pewPlace, "most") : rankWord(pewLeast, "least")} disapproving of the {pewList.length} countries surveyed, where the median is {pewMedian}%.{PEW.notes[c.slug] && ` ${PEW.notes[c.slug]}`} <a href={mapHref("pew_marijuana")}>On the map →</a></p>
         <SourceTip><a href={PEW.url} target="_blank" rel="noopener noreferrer">{PEW.publisher}</a>, {PEW.when}, {pew.sample.toLocaleString("en-GB")} adults (<a href={PEW.data_url} target="_blank" rel="noopener noreferrer">{PEW.data_label}</a>).</SourceTip>
       </div>
@@ -160,5 +160,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
           <i style={`width:${gallupNow.legal}%;background:var(--t5)`}></i>
         </div>
-        <p class="intro-note">Gallup poll of {gallupNow.date}. <a href={`${base}charts/#opinion-gap`}>The whole trend →</a></p>
+        <p class="intro-note">Gallup poll of {gallupNow.date}. <a href={`${base}charts/#opinion-gap`}>The whole trend →</a></p>
         <SourceTip><a href={GALLUP.url} target="_blank" rel="noopener noreferrer">{GALLUP.title}</a>.</SourceTip>
       </div>
@@ -179,5 +179,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
           ))}
         </ul>
-        <p class="intro-note">The dot: where it stands among the countries each dataset covers, lowest to highest. <a href="#datasets">All datasets ↓</a></p>
+        <p class="intro-note">The dot: where it stands among the countries each dataset covers, lowest to highest. <a href="#datasets">All datasets ↓</a></p>
       </div>
     )}
@@ -192,5 +192,5 @@ const tiles = 1 + [near.length >= 3, pew, gallup, highlights.length > 0, SHOW_PR
               <small>{w.lang}{w.say && <> · <span class="intro-say">{w.say}</span></>}</small>
               {w.meaning && <span class="intro-means">{w.meaning}</span>}
-              {w.atlas && <a class="intro-atlas" href={`${base}culture/language/${w.atlas}/`}>In the atlas →</a>}
+              {w.atlas && <a class="intro-atlas" href={`${base}culture/language/${w.atlas}/`}>In the atlas →</a>}
             </li>
           ))}

src/styles/global.css +5 −0
@@ -1426,4 +1426,9 @@ details.segrow .segrow-top > span, .segrow:not(details) .segrow-top > span { fon
 .segrow.ctx-tile { break-inside: avoid; padding: 16px 0 18px; border-bottom: 0; border-top: 1px solid var(--border); }
 .ctx-grid > .ctx-tile:first-child { border-top: 0; padding-top: 6px; }
+/* a section's status chips sit on its title line, to the right; several wrap there */
+.ctx-grid > .ctx-tile { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 14px; align-items: start; }
+.ctx-grid > .ctx-tile > * { grid-column: 1 / -1; }
+.ctx-grid > .ctx-tile > .segrow-top { grid-column: 1; margin-bottom: 4px; }
+.ctx-grid > .ctx-tile > .d-chips { grid-column: 2; grid-row: 1; justify-content: flex-end; max-width: 300px; margin: 2px 0 6px; }
 .ctx-wide { margin-top: 18px; }
 .ctx-wide > .ctx-tile { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 0 clamp(32px, 4vw, 64px); border-top: 1px solid var(--text); }

    ↑↓ to move, ↵ to open.