Changelog 242f874tree, with Claude Opus 5.5
Profiles: context headings explain on hover, dataset names link to their pages
A context section's name shows what the section covers on hover or focus and leads to the topic's page on a click, without the separate info button; the status chips beside it are labels rather than links. A dataset card's name leads to /datasets/<slug>/, replacing its Map, Chart and About links.
3 files of code, design or docs +19 −26 lines
Code, design and documents 3 files
src/components/CountryArticle.astro +8 −12
@@ -18,5 +18,4 @@ import { references, citeParts, citedKeys } from "../lib/cite.js"; import { PLANTING_STATUS, STATUS_SECTIONS, PLANTING_TRADE } from "../lib/segment-ids.js"; import { TREATMENT, punishmentText, punishmentExtra } from "../lib/penalties.js"; -import { viewByMetric } from "../lib/map-views.js"; import { Icon } from "astro-icon/components"; import PenaltyTable from "./PenaltyTable.astro"; @@ -69,7 +68,4 @@ const ctxParts = ctxList ? Object.fromEntries(ctxList.filter(Boolean).map((x) => // a maximum fine in the profile's currency: "€5,500", "$300" const money = (n, currency) => new Intl.NumberFormat("en-GB", { style: "currency", currency, maximumFractionDigits: 0 }).format(n); -// a chip inside a context section leads to the world map coloured by the same status -const mapOf = (metric) => (viewByMetric[metric] ? `${base}map/${viewByMetric[metric].slug}/` : undefined); -const onMap = (help) => `${help} · See the world map`; // the recreational and medical status chips lead to their own context sections, where those exist const ctxHas = (key) => Boolean(ctxList?.some((x) => x?.key === key)); @@ -373,23 +369,23 @@ const uncited = srcList.filter((x) => !citedSet.has(refKey(x))); {list.map((x) => ( <div class="segrow ctx-tile" data-seg={`ctx-${x.key}`} id={`seg-ctx-${x.key}`}> - <div class="segrow-top"><span>{CONTEXT_ICONS[x.key] && <Icon name={CONTEXT_ICONS[x.key]} class="ctx-icon" aria-hidden="true" />}{x.key === "products" ? x.name : <a class="ctx-topic" href={`${base}context/${x.key.replace(/_/g, "-")}/`} title={`${x.name} in every country`}>{x.name}</a>}<SourceTip label="What this covers" inline>{x.help}</SourceTip></span></div> + <div class="segrow-top"><span>{CONTEXT_ICONS[x.key] && <Icon name={CONTEXT_ICONS[x.key]} class="ctx-icon" aria-hidden="true" />}<span class="src-tip src-tip-inline ctx-topic-tip">{x.key === "products" ? x.name : <a class="ctx-topic" href={`${base}context/${x.key.replace(/_/g, "-")}/`}>{x.name}</a>}<span class="src-tip-pop" role="tooltip"><b>What this covers</b> {x.help}{x.key !== "products" && <i>Select for every country</i>}</span></span></span></div> {x.national && <p class="ctx ctx-general">For all of {c.name}; nothing written for {sub.name} yet.</p>} {x.key === "recreational" && ( - <div class="d-chips"><a class={`chip s-${v.rec}`} href={mapOf("status:rec")} title={onMap(REC_HELP[v.rec])}>Recreational: {REC_LABEL[v.rec]}</a></div> + <div class="d-chips"><span class={`chip s-${v.rec}`} title={REC_HELP[v.rec]}>Recreational: {REC_LABEL[v.rec]}</span></div> )} {x.key === "medical" && ( - <div class="d-chips"><a class={`chip s-${v.med}`} href={mapOf("status:med")} title={onMap(MED_HELP[v.med])}>Medical: {MED_LABEL[v.med]}</a></div> + <div class="d-chips"><span class={`chip s-${v.med}`} title={MED_HELP[v.med]}>Medical: {MED_LABEL[v.med]}</span></div> )} {x.status && ( <div class="d-chips"> - <a class={`chip s-${STATUS_SECTIONS[x.kind].statuses[x.status].tone}`} href={mapOf(`status:${x.kind}`)} title={onMap(STATUS_SECTIONS[x.kind].statuses[x.status].help)}>{STATUS_SECTIONS[x.kind].chip}: {STATUS_SECTIONS[x.kind].statuses[x.status].label}</a> + <span class={`chip s-${STATUS_SECTIONS[x.kind].statuses[x.status].tone}`} title={STATUS_SECTIONS[x.kind].statuses[x.status].help}>{STATUS_SECTIONS[x.kind].chip}: {STATUS_SECTIONS[x.kind].statuses[x.status].label}</span> </div> )} {x.seeds && ( <div class="d-chips"> - <a class={`chip s-${PLANTING_STATUS[x.seeds].tone}`} href={mapOf("plant:seeds")} title={onMap(PLANTING_STATUS[x.seeds].help[0])}>Seeds: {PLANTING_STATUS[x.seeds].label}</a> - <a class={`chip s-${PLANTING_TRADE[x.seeds_trade].tone}`} href={mapOf("plant:seeds_trade")} title={onMap(PLANTING_TRADE[x.seeds_trade].help[0])}>Seed sales: {PLANTING_TRADE[x.seeds_trade].label}</a> - <a class={`chip s-${PLANTING_STATUS[x.clones].tone}`} href={mapOf("plant:clones")} title={onMap(PLANTING_STATUS[x.clones].help[1])}>Clones: {PLANTING_STATUS[x.clones].label}</a> - <a class={`chip s-${PLANTING_TRADE[x.clones_trade].tone}`} href={mapOf("plant:clones_trade")} title={onMap(PLANTING_TRADE[x.clones_trade].help[1])}>Clone sales: {PLANTING_TRADE[x.clones_trade].label}</a> + <span class={`chip s-${PLANTING_STATUS[x.seeds].tone}`} title={PLANTING_STATUS[x.seeds].help[0]}>Seeds: {PLANTING_STATUS[x.seeds].label}</span> + <span class={`chip s-${PLANTING_TRADE[x.seeds_trade].tone}`} title={PLANTING_TRADE[x.seeds_trade].help[0]}>Seed sales: {PLANTING_TRADE[x.seeds_trade].label}</span> + <span class={`chip s-${PLANTING_STATUS[x.clones].tone}`} title={PLANTING_STATUS[x.clones].help[1]}>Clones: {PLANTING_STATUS[x.clones].label}</span> + <span class={`chip s-${PLANTING_TRADE[x.clones_trade].tone}`} title={PLANTING_TRADE[x.clones_trade].help[1]}>Clone sales: {PLANTING_TRADE[x.clones_trade].label}</span> </div> )}
src/components/CountryDatasetTab.astro +4 −11
@@ -4,10 +4,9 @@ // name, one headline figure and a line of further figures, written as set under `profile` in // datasets.yaml; the figure over the years; where the country stands among every country the -// dataset covers; and links to its map and its entry on the sources page. +// dataset covers. Its name leads to the dataset's page across every country (/datasets/<slug>/). import SourceTip from "./SourceTip.astro"; import { USE_COMPARISON_NOTE } from "../lib/use-labels.js"; import { DATASETS, datasetsOf } from "../lib/datasets.js"; -import { viewByMetric } from "../lib/map-views.js"; -import { figure as figureOf, fill as fillOf, headline as headlineOf, headField, TONES, POLARITY, toneAt, CHART_OF, GROUPS, groupOf, standing as standingOf } from "../lib/dataset-text.js"; +import { figure as figureOf, fill as fillOf, headline as headlineOf, headField, TONES, POLARITY, toneAt, GROUPS, groupOf, standing as standingOf } from "../lib/dataset-text.js"; const { c } = Astro.props; @@ -18,5 +17,4 @@ const figure = (d, row, name) => figureOf(c, d, row, name); const fill = (d, row, template) => fillOf(c, d, row, template); const headline = (d, row) => headlineOf(c, d, row); -const mapHref = (d) => (d.map ? `${base}map/${viewByMetric[`data:${d.id}`].slug}/` : (d.pages ?? []).filter((p) => p.path.startsWith("map/")).map((p) => `${base}${p.path}`)[0]); // The headline's figure over the years, for a small line chart: [{ year, v, t }] with at least two @@ -58,5 +56,5 @@ const groups = GROUPS.map((name) => ({ name, rows: rows.filter((r) => groupOf(r. <section class="c-ds"> <h2 class="d-h">Datasets <span>not part of the score</span></h2> - <p class="d-hint">What other organisations publish about {c.name}, and where it stands among the countries each one covers. Every file is published in full on the <a href={`${base}sources/#datasets`}>sources page</a>.</p> + <p class="d-hint">What other organisations publish about {c.name}, and where it stands among the countries each one covers. Each dataset has a <a href={`${base}datasets/`}>page of its own</a>, with a world map and every country's figure.</p> {groups.length > 1 && ( <nav class="ds-nav" aria-label="Dataset groups"> @@ -72,5 +70,5 @@ const groups = GROUPS.map((name) => ({ name, rows: rows.filter((r) => groupOf(r. style={stand ? (POLARITY[d.id] ? `--ds:${toneAt(stand.at, POLARITY[d.id])};--lo:var(--t${POLARITY[d.id] > 0 ? 1 : 5});--hi:var(--t${POLARITY[d.id] > 0 ? 5 : 1})` : `--ds:var(--u${stand.step})`) : d.id === "cannabis_use" ? "position:relative" : undefined}> <p class="ds-kicker"><span>{d.credit ?? d.publisher}{year != null && ` · ${year}`}</span></p> - <h4>{d.name}</h4> + <h4><a href={`${base}datasets/${d.id.replace(/_/g, "-")}/`}>{d.name}</a></h4> <p class:list={["ds-figure", { words: d.fields[headField(d)]?.type === "text" }]} title={stand?.label ? `On the map: ${stand.label}` : undefined}><b>{head[0]}</b>{head[1] && <span>{head[1]}</span>}</p> {chart && ( @@ -97,9 +95,4 @@ const groups = GROUPS.map((name) => ({ name, rows: rows.filter((r) => groupOf(r. {details && <p class="ds-details">{details}</p>} {note && (d.id === "cannabis_use" ? <SourceTip>{note}</SourceTip> : <p class="ds-details ds-note">{note}</p>)} - <p class="ds-links"> - {mapHref(d) && <a href={mapHref(d)}>Map</a>} - {CHART_OF[d.id] && <a href={`${base}charts/#${CHART_OF[d.id]}`}>Chart</a>} - <a href={`${base}sources/#dataset-${d.id}`}>About the data</a> - </p> </li> ))}
src/styles/global.css +7 −3
@@ -1251,7 +1251,7 @@ details.segrow .segrow-top > span, .segrow:not(details) .segrow-top > span { fon .ds-details { margin: 2px 0 0; color: var(--muted); font-size: 12.5px; line-height: 1.5; } .ds-note { color: var(--muted); } -.ds-links { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0; padding-top: 4px; font: 400 10.5px var(--mono); text-transform: uppercase; letter-spacing: .06em; } -.ds-links a { color: var(--muted); } -.ds-links a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; } +/* the dataset's name leads to its page across every country */ +.ds-card h4 a { color: inherit; } +.ds-card h4 a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; } @media (max-width: 640px) { .ds-figure b { font-size: 24px; } } .cd-stack { display: flex; height: 10px; overflow: hidden; border-radius: var(--r); background: var(--border); } @@ -3504,4 +3504,8 @@ a.ch-db-track:hover { background: color-mix(in srgb, var(--text) 6%, transparent a.ctx-topic { color: inherit; } a.ctx-topic:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; } +/* a context section's name: what the section covers on hover or focus, the topic's page on a click */ +.src-tip.ctx-topic-tip { margin-left: 0; vertical-align: baseline; } +.ctx-topic-tip:has(a:focus-visible) .src-tip-pop { display: block; } +.ctx-topic-tip .src-tip-pop i { display: block; margin-top: 6px; font: 400 10.5px var(--mono); font-style: normal; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); } /* the row of topics at the top of the context pages */ .ctxp-menu { margin: 18px 0 0; border-bottom: 1px solid var(--border); }