Files
archicratie-edition/src/pages/glossaire/index.astro
Archicratia 9f88112aca
All checks were successful
SMOKE / smoke (push) Successful in 13s
CI / build-and-anchors (push) Successful in 1m4s
CI / build-and-anchors (pull_request) Successful in 35s
feat(glossary): add step 21 smart navigation
2026-04-26 13:03:45 +02:00

916 lines
26 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 GlossaryLayout from "../../layouts/GlossaryLayout.astro";
import GlossaryHomeAside from "../../components/GlossaryHomeAside.astro";
import GlossaryHomeHero from "../../components/GlossaryHomeHero.astro";
import GlossaryHomeSection from "../../components/GlossaryHomeSection.astro";
import GlossaryCardGrid from "../../components/GlossaryCardGrid.astro";
import GlossaryPortalGrid from "../../components/GlossaryPortalGrid.astro";
import { getCollection } from "astro:content";
import {
buildGlossaryBySlug,
countGlossaryEntriesByKind,
familyOf,
getGlossaryEntriesByFamily,
hrefOfGlossaryEntry,
sortGlossaryEntries,
} from "../../lib/glossary";
const entries = await getCollection("glossaire");
const bySlug = buildGlossaryBySlug(entries);
const fondamentaux = getGlossaryEntriesByFamily(entries, "concept-fondamental");
const scenes = getGlossaryEntriesByFamily(entries, "scene");
const dynamiques = sortGlossaryEntries(
entries.filter((entry) =>
["dynamique", "pathologie"].includes(familyOf(entry)),
),
);
const metaRegimes = getGlossaryEntriesByFamily(entries, "meta-regime");
const paradigmesCount = countGlossaryEntriesByKind(entries, "paradigme");
const doctrinesCount = countGlossaryEntriesByKind(entries, "doctrine");
const metaRegimesPreview = metaRegimes.slice(0, 6);
const arcalite = bySlug.get("arcalite");
const cratialite = bySlug.get("cratialite");
const tension = bySlug.get("tension");
const sceneDepreuve = bySlug.get("scene-depreuve");
const archicration = bySlug.get("archicration");
const conceptsPageHref = "/glossaire/concepts-fondamentaux/";
const scenesPageHref = "/glossaire/scenes-archicratiques/";
const dynamiquesPageHref = "/glossaire/dynamiques-archicratiques/";
const paradigmeArchicratiquePageHref = "/glossaire/paradigme-archicratique/";
const metaRegimesPageHref = "/glossaire/archicrations/";
const tensionsPageHref = "/glossaire/tensions-irreductibles/";
const verbesPageHref = "/glossaire/verbes-de-la-scene/";
const paradigmesPageHref = "/glossaire/paradigmes/";
const indexCompletPageHref = "/glossaire/index-complet/";
const paradigmePortalItems = [
{
href: paradigmeArchicratiquePageHref,
title: "Paradigme archicratique",
description:
"Saisir la logique densemble du système archicratique : de larcalité et de la cratialité jusquaux scènes, aux tensions, aux formes de co-viabilité et aux traditions de comparaison mobilisées.",
meta: "Portail de synthèse générale",
},
];
const approfondirPortalItems = [
{
href: tensionsPageHref,
title: "Tensions irréductibles",
description:
"Parcourir les dix tensions ontologiquement irréductibles et politiquement fondatrices à partir desquelles la co-viabilité doit être pensée.",
meta: "10 tensions structurantes",
},
{
href: verbesPageHref,
title: "Verbes de la scène",
description:
"Disposer dun mini-glossaire opératoire pour décrire louverture, lentrave, la capture, la fermeture ou la remise en scène des architectures régulatrices.",
meta: "19 verbes danalyse",
},
{
href: paradigmesPageHref,
title: "Cartographie théorique",
description:
"Situer larchicratie dans son paysage de doctrines fondatrices et de paradigmes régulateurs.",
meta: `${doctrinesCount} doctrine${doctrinesCount > 1 ? "s" : ""} · ${paradigmesCount} paradigme${paradigmesCount > 1 ? "s" : ""}`,
},
{
href: indexCompletPageHref,
title: "Index complet",
description:
"Retrouver lensemble des entrées du glossaire dans une navigation alphabétique intégrale.",
meta: `${entries.length} entrée${entries.length > 1 ? "s" : ""}`,
},
];
---
<GlossaryLayout
title="Glossaire archicratique"
version="1.0"
stickyMode="glossary-home"
>
<Fragment slot="aside">
<GlossaryHomeAside allEntries={entries} />
</Fragment>
<section class="glossary-home">
<GlossaryHomeHero />
<section
class="glossary-map-block glossary-section"
aria-labelledby="glossary-map-title"
>
<div class="glossary-map-block__head">
<h2
id="glossary-map-title"
data-follow-section="Cartographie du système archicratique"
>
Cartographie du système archicratique
</h2>
<p>
La lecture la plus simple du système part de deux vecteurs premiers,
larcalité et la cratialité, dont la rencontre produit des tensions.
Ces tensions doivent être mises en scène, traitées par larchicration,
puis stabilisées dans des méta-régimes de co-viabilité.
</p>
</div>
<div class="glossary-map" aria-label="Carte conceptuelle du glossaire">
<div class="glossary-map__stage">
<div class="glossary-map__title">Forces en composition</div>
<div class="glossary-map__roots">
{arcalite ? (
<a class="glossary-map__node" href={hrefOfGlossaryEntry(arcalite)}>
ARCALITÉ
</a>
) : (
<span class="glossary-map__node">ARCALITÉ</span>
)}
{cratialite ? (
<a class="glossary-map__node" href={hrefOfGlossaryEntry(cratialite)}>
CRATIALITÉ
</a>
) : (
<span class="glossary-map__node">CRATIALITÉ</span>
)}
</div>
</div>
<div class="glossary-map__arrow" aria-hidden="true">↓</div>
<div class="glossary-map__stage">
<div class="glossary-map__title">Phénomène transversal</div>
{tension ? (
<a
class="glossary-map__node glossary-map__node--wide"
href={hrefOfGlossaryEntry(tension)}
>
TENSION
</a>
) : (
<span class="glossary-map__node glossary-map__node--wide">
TENSION
</span>
)}
</div>
<div class="glossary-map__arrow" aria-hidden="true">↓</div>
<div class="glossary-map__stage">
<div class="glossary-map__title">Comparution</div>
{sceneDepreuve ? (
<a
class="glossary-map__node glossary-map__node--wide"
href={hrefOfGlossaryEntry(sceneDepreuve)}
>
MISE EN SCÈNE
</a>
) : (
<span class="glossary-map__node glossary-map__node--wide">
MISE EN SCÈNE
</span>
)}
</div>
<div class="glossary-map__arrow" aria-hidden="true">↓</div>
<div class="glossary-map__stage">
<div class="glossary-map__title">Opérateur régulateur</div>
{archicration ? (
<a
class="glossary-map__node glossary-map__node--wide"
href={hrefOfGlossaryEntry(archicration)}
>
ARCHICRATION
</a>
) : (
<span class="glossary-map__node glossary-map__node--wide">
ARCHICRATION
</span>
)}
</div>
<div class="glossary-map__arrow" aria-hidden="true">↓</div>
<div class="glossary-map__stage">
<div class="glossary-map__title">Formes de stabilisation</div>
<a
class="glossary-map__node glossary-map__node--wide"
href={metaRegimesPageHref}
>
MÉTA-RÉGIMES
</a>
</div>
</div>
</section>
{fondamentaux.length > 0 && (
<GlossaryHomeSection
id="concepts-fondamentaux"
title="Concepts fondamentaux"
followSection="Concepts fondamentaux"
intro="Ces notions forment la grammaire minimale de larchicratie. Elles donnent accès à la structure générale du système."
ctaHref={conceptsPageHref}
ctaLabel="Ouvrir le portail"
>
<GlossaryCardGrid entries={fondamentaux} />
</GlossaryHomeSection>
)}
<GlossaryHomeSection
id="paradigme-archicratique"
title="Paradigme archicratique"
followSection="Paradigme archicratique"
intro="Cette page de synthèse offre une vue densemble du système archicratique. Elle articule le noyau conceptuel, les scènes de comparution, les dynamiques, les tensions irréductibles, les méta-régimes de co-viabilité et le paysage théorique dans lequel larchicratie se situe et se distingue."
ctaHref={paradigmeArchicratiquePageHref}
ctaLabel="Ouvrir la synthèse"
>
<GlossaryPortalGrid items={paradigmePortalItems} />
</GlossaryHomeSection>
{scenes.length > 0 && (
<GlossaryHomeSection
id="scenes-archicratiques"
title="Scènes archicratiques"
followSection="Scènes archicratiques"
intro="Les scènes archicratiques rendent possible la comparution des architectures de régulation. Elles sont le lieu où lordre peut être exposé, discuté et révisé."
ctaHref={scenesPageHref}
ctaLabel="Ouvrir le portail"
>
<GlossaryCardGrid entries={scenes} wide={true} />
</GlossaryHomeSection>
)}
{dynamiques.length > 0 && (
<GlossaryHomeSection
id="dynamiques-archicratiques"
title="Dynamiques archicratiques"
followSection="Dynamiques archicratiques"
intro="Cette famille rassemble les processus de déplacement, les dérives et les formes de pathologisation de la régulation archicratique."
ctaHref={dynamiquesPageHref}
ctaLabel="Ouvrir le portail"
>
<GlossaryCardGrid entries={dynamiques} />
</GlossaryHomeSection>
)}
<GlossaryHomeSection
id="meta-regimes-archicratiques"
title="Méta-régimes archicratiques"
followSection="Méta-régimes archicratiques"
intro="Les méta-régimes décrivent les grandes formes historiques et topologiques par lesquelles une société organise durablement ses tensions et sa co-viabilité."
ctaHref={metaRegimesPageHref}
ctaLabel="Explorer la cartographie complète"
>
{metaRegimesPreview.length > 0 && (
<GlossaryCardGrid entries={metaRegimesPreview} />
)}
</GlossaryHomeSection>
<GlossaryHomeSection
id="approfondir"
title="Prolonger la lecture"
followSection="Prolonger la lecture"
intro="Quatre parcours complémentaires permettent délargir la lecture : lun vers les tensions irréductibles, lun vers les verbes de la scène archicratique, lun vers le paysage théorique dans lequel larchicratie se situe et se distingue, lautre vers lensemble alphabétique complet des entrées du glossaire."
>
<GlossaryPortalGrid items={approfondirPortalItems} secondary={true} />
</GlossaryHomeSection>
</section>
<script is:inline>
(() => {
const header = document.querySelector("header");
const hero = document.getElementById("glossary-hero");
const follow = document.getElementById("glossary-hero-follow");
const intro = document.getElementById("glossary-hero-intro");
const toggle = document.getElementById("glossary-hero-toggle");
const headings = Array.from(document.querySelectorAll("[data-follow-section]"));
if (!header || !hero || !follow || !intro || !toggle || headings.length === 0) return;
let raf = 0;
let activeHeading = null;
let clearTimer = 0;
function syncStickyTop() {
const headerHeight = header.getBoundingClientRect().height || 0;
document.documentElement.style.setProperty(
"--glossary-sticky-top",
`${Math.round(headerHeight + 8)}px`
);
}
function applyHeadingMetrics(fromEl, toEl) {
const cs = window.getComputedStyle(fromEl);
const sourceFontSize = Number.parseFloat(cs.fontSize) || 40;
const sourceLineHeight =
Number.parseFloat(cs.lineHeight) ||
Math.round(sourceFontSize * 1.06 * 100) / 100;
const scaledFontSize = Math.max(28, sourceFontSize * 0.9);
const scaledLineHeight = Math.max(scaledFontSize * 1.04, sourceLineHeight * 0.92);
toEl.style.fontSize = `${scaledFontSize}px`;
toEl.style.lineHeight = `${scaledLineHeight}px`;
toEl.style.fontWeight = cs.fontWeight;
toEl.style.letterSpacing = cs.letterSpacing;
toEl.style.fontFamily = cs.fontFamily;
document.documentElement.style.setProperty(
"--glossary-follow-height",
`${Math.ceil(scaledLineHeight)}px`
);
}
function getCurrentHeading() {
const heroRect = hero.getBoundingClientRect();
const heroBottom = heroRect.bottom;
let candidate = null;
for (const heading of headings) {
const rect = heading.getBoundingClientRect();
const trigger =
heroBottom - Math.min(Math.max(rect.height * 0.55, 18), 34);
if (rect.top <= trigger) {
candidate = heading;
} else {
break;
}
}
return candidate;
}
function hideFollow() {
if (!follow.classList.contains("is-visible")) return;
follow.classList.remove("is-visible");
follow.setAttribute("aria-hidden", "true");
window.clearTimeout(clearTimer);
clearTimer = window.setTimeout(() => {
if (!follow.classList.contains("is-visible")) {
follow.textContent = "";
}
}, 260);
}
function showFollow(heading) {
const nextText = (heading.dataset.followSection || heading.textContent || "").trim();
if (!nextText) {
hideFollow();
return;
}
if (activeHeading !== heading) {
activeHeading = heading;
follow.textContent = nextText;
applyHeadingMetrics(heading, follow);
}
window.clearTimeout(clearTimer);
if (!follow.classList.contains("is-visible")) {
requestAnimationFrame(() => {
follow.classList.add("is-visible");
follow.setAttribute("aria-hidden", "false");
});
} else {
follow.setAttribute("aria-hidden", "false");
}
}
function collapseIntro() {
if (!document.body.classList.contains("glossary-home-follow-on")) return;
if (document.body.classList.contains("glossary-home-hero-expanded")) return;
intro.setAttribute("aria-hidden", "true");
toggle.hidden = false;
toggle.setAttribute("aria-expanded", "false");
}
function expandIntro() {
document.body.classList.add("glossary-home-hero-expanded");
intro.setAttribute("aria-hidden", "false");
toggle.hidden = true;
toggle.setAttribute("aria-expanded", "true");
}
function resetIntro() {
document.body.classList.remove("glossary-home-hero-expanded");
intro.setAttribute("aria-hidden", "false");
toggle.hidden = true;
toggle.setAttribute("aria-expanded", "false");
}
function updateFollow() {
syncStickyTop();
const heroRect = hero.getBoundingClientRect();
const active = getCurrentHeading();
const stickyTop =
parseFloat(
getComputedStyle(document.documentElement)
.getPropertyValue("--glossary-sticky-top")
) || 64;
const hasStartedScrolling = (window.scrollY || window.pageYOffset || 0) > 8;
const heroDocked = Math.abs(heroRect.top - stickyTop) <= 6;
const heroOut = hasStartedScrolling && heroDocked;
document.body.classList.toggle("glossary-home-follow-on", heroOut);
if (!active) {
activeHeading = null;
hideFollow();
resetIntro();
return;
}
const activeRect = active.getBoundingClientRect();
const showThreshold =
heroRect.bottom - Math.min(Math.max(activeRect.height * 0.58, 18), 34);
const shouldShow = heroOut && activeRect.top <= showThreshold;
if (!shouldShow) {
activeHeading = null;
hideFollow();
resetIntro();
return;
}
collapseIntro();
showFollow(active);
}
function schedule() {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
updateFollow();
});
}
toggle.addEventListener("click", expandIntro);
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
schedule();
})();
</script>
<style>
:root{
--glossary-accent: #00d9ff;
--glossary-bg-soft: rgba(127,127,127,0.05);
--glossary-bg-soft-strong: rgba(127,127,127,0.08);
--glossary-border: rgba(127,127,127,0.22);
--glossary-border-strong: rgba(127,127,127,0.30);
--glossary-sticky-top: 64px;
--glossary-follow-height: 2.5rem;
}
.glossary-home{
min-width: 0;
overflow-x: clip;
}
.glossary-home > *{
min-width: 0;
}
.glossary-map-block,
.glossary-section,
.glossary-map,
.glossary-map__stage,
.glossary-map__roots,
.glossary-map__node{
min-width: 0;
}
.glossary-map-block__head h2,
.glossary-section h2{
margin: 0;
font-size: clamp(1.8rem, 3vw, 2.55rem);
line-height: 1.06;
letter-spacing: -.03em;
font-weight: 800;
text-wrap: balance;
}
.glossary-map-block{
padding: 18px 18px 20px;
border: 1px solid var(--glossary-border);
border-radius: 24px;
background: rgba(127,127,127,0.04);
}
.glossary-map-block__head p{
max-width: 76ch;
margin: 12px 0 0;
font-size: 1rem;
line-height: 1.55;
opacity: .94;
text-wrap: pretty;
}
.glossary-map{
display: grid;
justify-items: center;
gap: 10px;
margin-top: 18px;
}
.glossary-map__stage{
width: min(580px, 100%);
display: grid;
justify-items: center;
gap: 10px;
}
.glossary-map__title{
width: 100%;
text-align: center;
font-size: 1.08rem;
line-height: 1.25;
font-weight: 800;
letter-spacing: -.01em;
opacity: .96;
text-wrap: balance;
}
.glossary-map__roots{
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
}
.glossary-map__node{
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 50px;
padding: 10px 14px;
border: 1px solid var(--glossary-border-strong);
border-radius: 999px;
background: var(--glossary-bg-soft);
color: var(--glossary-accent);
text-decoration: none;
text-align: center;
font-size: .99rem;
font-weight: 800;
letter-spacing: .04em;
line-height: 1.2;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease;
}
.glossary-map__node:hover{
background: var(--glossary-bg-soft-strong);
border-color: rgba(0,217,255,0.22);
text-decoration: none;
transform: translateY(-1px);
}
.glossary-map__node--wide{
width: 100%;
max-width: 100%;
}
.glossary-map__arrow{
font-size: 1.45rem;
line-height: 1;
opacity: .72;
}
.glossary-portal-card strong{
color: var(--glossary-accent);
font-size: 1.08rem;
line-height: 1.28;
}
.glossary-portal-card span{
color: inherit;
font-size: 1rem;
line-height: 1.5;
opacity: .94;
}
.glossary-portal-card small{
color: var(--glossary-accent);
font-size: .94rem;
line-height: 1.35;
opacity: .9;
}
@media (max-width: 980px){
.glossary-map-block{
padding: 16px 16px 18px;
border-radius: 20px;
}
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.8rem, 5vw, 2.3rem);
line-height: 1.04;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .96rem;
line-height: 1.44;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
grid-template-columns: 1fr;
gap: 10px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 13px 14px;
border-radius: 15px;
}
}
@media (max-width: 760px){
.glossary-hero{
top: calc(var(--glossary-sticky-top) - 2px);
padding: 12px 14px 16px;
}
.glossary-map-block{
padding: 16px 16px 18px;
border-radius: 20px;
}
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.5rem, 7vw, 1.95rem);
line-height: 1.04;
letter-spacing: -.022em;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .9rem;
line-height: 1.34;
}
.glossary-section__head{
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.glossary-cta{
width: fit-content;
}
.glossary-map{
gap: 7px;
margin-top: 12px;
}
.glossary-map__stage{
gap: 7px;
width: 100%;
}
.glossary-map__title{
font-size: .9rem;
line-height: 1.2;
}
.glossary-map__roots{
grid-template-columns: 1fr;
gap: 6px;
}
.glossary-map__node{
min-height: 38px;
padding: 8px 10px;
font-size: .84rem;
line-height: 1.15;
}
.glossary-map__arrow{
font-size: 1rem;
opacity: .62;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-map-block{
padding: 10px 10px 12px;
border-radius: 14px;
}
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.18rem, 3.2vw, 1.42rem);
line-height: 1.04;
letter-spacing: -.02em;
text-wrap: pretty;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .82rem;
line-height: 1.24;
}
.glossary-section{
margin-top: 24px;
}
.glossary-section__head{
gap: 10px;
margin-bottom: 10px;
}
.glossary-map{
gap: 5px;
margin-top: 10px;
}
.glossary-map__stage{
gap: 5px;
}
.glossary-map__title{
font-size: .8rem;
line-height: 1.12;
}
.glossary-map__node{
min-height: 32px;
padding: 6px 8px;
font-size: .74rem;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 10px 11px;
border-radius: 12px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .9rem;
line-height: 1.2;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span,
.glossary-home .glossary-portal-card small{
font-size: .8rem;
line-height: 1.22;
}
}
@media (prefers-color-scheme: dark){
.glossary-map-block,
.glossary-map__node,
.glossary-card,
.glossary-portal-card{
background: rgba(255,255,255,0.04);
}
.glossary-map__node:hover,
.glossary-card:hover,
.glossary-portal-card:hover,
.glossary-cta:hover{
background: rgba(255,255,255,0.07);
}
}
/* =========================================================
LOT 17.A.5 — Recalage follow + densité mobile finale
========================================================= */
.glossary-home{
min-width: 0;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
min-width: 0;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
min-width: 0;
}
@media (max-width: 760px){
.glossary-section{
margin-top: 30px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 108px);
}
.glossary-section__head{
gap: 10px;
margin-bottom: 10px;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
gap: 9px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 12px 13px;
border-radius: 14px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .98rem;
line-height: 1.2;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span{
font-size: .92rem;
line-height: 1.36;
}
.glossary-home .glossary-portal-card small{
font-size: .82rem;
line-height: 1.2;
}
.glossary-cta{
min-height: 36px;
padding: 6px 12px;
font-size: .92rem;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-section{
margin-top: 20px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 84px);
}
.glossary-section__head{
gap: 8px;
margin-bottom: 8px;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
gap: 8px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 9px 10px;
border-radius: 12px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .86rem;
line-height: 1.14;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span,
.glossary-home .glossary-portal-card small{
font-size: .76rem;
line-height: 1.16;
}
.glossary-cta{
min-height: 30px;
padding: 4px 10px;
font-size: .8rem;
}
}
</style>
</GlossaryLayout>