Files
archicratie-edition/src/pages/glossaire/index-complet.astro
Archicratia d6b4eb82f4
All checks were successful
SMOKE / smoke (push) Successful in 9s
CI / build-and-anchors (push) Successful in 55s
CI / build-and-anchors (pull_request) Successful in 45s
feat(glossaire): enrich entries and refine glossary navigation
2026-03-19 21:53:33 +01:00

223 lines
5.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
import SiteLayout from "../../layouts/SiteLayout.astro";
import { getCollection } from "astro:content";
const entries = await getCollection("glossaire");
const slugOf = (entry) => String(entry.id).replace(/\.(md|mdx)$/i, "");
const hrefOf = (entry) => `/glossaire/${slugOf(entry)}/`;
const collator = new Intl.Collator("fr", { sensitivity: "base", numeric: true });
const kindLabels = {
concept: "Concept",
diagnostic: "Diagnostic",
topologie: "Topologie",
verbe: "Verbe",
paradigme: "Paradigme",
doctrine: "Doctrine",
};
const domainLabels = {
transversal: "Transversal",
theorie: "Théorie",
"cas-ia": "Cas IA",
};
const levelLabels = {
fondamental: "Fondamental",
intermediaire: "Intermédiaire",
avance: "Avancé",
};
const sorted = [...entries].sort((a, b) => collator.compare(a.data.term, b.data.term));
function groupByInitial(list) {
const map = new Map();
for (const entry of list) {
const letter = (entry.data.term || "").trim().charAt(0).toUpperCase() || "#";
if (!map.has(letter)) map.set(letter, []);
map.get(letter).push(entry);
}
return [...map.entries()].sort((a, b) => collator.compare(a[0], b[0]));
}
const groupedAlpha = groupByInitial(sorted);
---
<SiteLayout title="Index complet du glossaire">
<section class="glossary-index-page">
<header class="glossary-index-page__hero">
<p class="glossary-index-page__kicker">Référentiel terminologique</p>
<h1>Index complet du glossaire</h1>
<p class="glossary-index-page__intro">
Cette page rassemble lensemble des entrées du glossaire dans un ordre alphabétique intégral.
Elle complète laccueil conceptuel du glossaire par une navigation plus encyclopédique.
</p>
</header>
<div class="glossary-index-page__topbar">
<a class="glossary-index-page__back" href="/glossaire/">← Retour à laccueil du glossaire</a>
<nav class="glossary-index-page__letters" aria-label="Lettres de lindex">
{groupedAlpha.map(([letter]) => (
<a href={`#letter-${letter}`}>{letter}</a>
))}
</nav>
</div>
<div class="glossary-index-page__groups">
{groupedAlpha.map(([letter, items]) => (
<section class="glossary-index-page__group" id={`letter-${letter}`}>
<h2>{letter}</h2>
<ul class="glossary-index-page__list">
{items.map((entry) => (
<li class="glossary-index-page__item">
<a class="glossary-index-page__term" href={hrefOf(entry)}>
{entry.data.term}
</a>
<p class="glossary-index-page__def">{entry.data.definitionShort}</p>
<p class="glossary-index-page__meta">
<span>{kindLabels[entry.data.kind] ?? entry.data.kind}</span>
<span>{domainLabels[entry.data.domain] ?? entry.data.domain}</span>
<span>{levelLabels[entry.data.level] ?? entry.data.level}</span>
</p>
</li>
))}
</ul>
</section>
))}
</div>
</section>
</SiteLayout>
<style>
.glossary-index-page{
padding: 8px 0 32px;
}
.glossary-index-page__hero{
margin-bottom: 22px;
}
.glossary-index-page__kicker{
margin: 0 0 8px;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
opacity: .72;
}
.glossary-index-page__hero h1{
margin: 0 0 12px;
font-size: clamp(2.2rem, 4vw, 3rem);
line-height: 1.05;
letter-spacing: -.03em;
}
.glossary-index-page__intro{
max-width: 76ch;
margin: 0;
opacity: .92;
}
.glossary-index-page__topbar{
display: flex;
flex-direction: column;
gap: 14px;
margin: 22px 0 28px;
}
.glossary-index-page__back{
display: inline-flex;
width: fit-content;
align-items: center;
border: 1px solid rgba(127,127,127,0.28);
border-radius: 999px;
padding: 7px 14px;
text-decoration: none;
}
.glossary-index-page__letters{
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.glossary-index-page__letters a{
min-width: 34px;
text-align: center;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 10px;
padding: 5px 8px;
text-decoration: none;
}
.glossary-index-page__groups{
display: flex;
flex-direction: column;
gap: 28px;
}
.glossary-index-page__group{
scroll-margin-top: calc(var(--sticky-offset) + 20px);
}
.glossary-index-page__group h2{
margin: 0 0 14px;
font-size: clamp(1.6rem, 2vw, 2rem);
line-height: 1.1;
}
.glossary-index-page__list{
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 12px;
}
.glossary-index-page__item{
border: 1px solid rgba(127,127,127,0.20);
border-radius: 16px;
padding: 14px 16px;
background: rgba(127,127,127,0.04);
}
.glossary-index-page__term{
display: inline-block;
font-weight: 800;
font-size: 1.04rem;
text-decoration: none;
margin-bottom: 6px;
}
.glossary-index-page__def{
margin: 0 0 8px;
line-height: 1.5;
opacity: .94;
}
.glossary-index-page__meta{
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 0;
font-size: 12px;
opacity: .78;
}
.glossary-index-page__meta span{
border: 1px solid rgba(127,127,127,0.20);
border-radius: 999px;
padding: 2px 8px;
}
@media (prefers-color-scheme: dark){
.glossary-index-page__item{
background: rgba(255,255,255,0.04);
}
}
</style>