feat(glossaire): polish sticky entry flow and aside navigation
All checks were successful
SMOKE / smoke (push) Successful in 18s
CI / build-and-anchors (push) Successful in 48s
CI / build-and-anchors (pull_request) Successful in 48s

This commit is contained in:
2026-03-24 00:29:39 +01:00
parent e39a0c547d
commit 87955adf5d
18 changed files with 3639 additions and 584 deletions

View File

@@ -272,7 +272,8 @@ const relationSections = [
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">Portails</h2>
<ul class="glossary-aside__list">
<li><a href="/glossaire/">Index général</a></li>
<li><a href="/glossaire/">Accueil du glossaire</a></li>
<li><a href="/glossaire/index-complet/">Index complet</a></li>
<li><a href="/glossaire/paradigme-archicratique/">Paradigme archicratique</a></li>
<li><a href="/glossaire/archicrations/">Archicrations</a></li>
<li><a href="/glossaire/paradigmes/">Paradigmes et doctrines</a></li>
@@ -363,47 +364,48 @@ const relationSections = [
.glossary-aside__block{
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
padding: 12px;
padding: 14px;
background: rgba(127,127,127,0.05);
}
.glossary-aside__block--intro{
padding-top: 11px;
padding-bottom: 11px;
padding-top: 13px;
padding-bottom: 13px;
}
.glossary-aside__back{
display: inline-block;
margin-bottom: 8px;
font-size: 13px;
margin-bottom: 10px;
font-size: 14px;
font-weight: 700;
line-height: 1.35;
text-decoration: none;
}
.glossary-aside__title{
font-size: 14px;
font-size: 16px;
font-weight: 800;
letter-spacing: .2px;
line-height: 1.25;
line-height: 1.3;
}
.glossary-aside__pills{
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 8px;
gap: 7px;
margin-top: 10px;
}
.glossary-aside__pill{
display: inline-flex;
align-items: center;
padding: 4px 9px;
padding: 5px 10px;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 999px;
background: rgba(127,127,127,0.04);
font-size: 12px;
line-height: 1.3;
opacity: .9;
font-size: 13px;
line-height: 1.35;
opacity: .92;
}
.glossary-aside__pill--family{
@@ -412,17 +414,19 @@ const relationSections = [
}
.glossary-aside__heading{
margin: 0 0 10px;
font-size: 13px;
margin: 0 0 11px;
font-size: 14px;
font-weight: 800;
opacity: .9;
line-height: 1.35;
opacity: .94;
}
.glossary-aside__subheading{
margin: 12px 0 8px;
font-size: 12px;
margin: 13px 0 8px;
font-size: 12.5px;
font-weight: 800;
opacity: .8;
line-height: 1.35;
opacity: .82;
text-transform: uppercase;
letter-spacing: .04em;
}
@@ -434,13 +438,13 @@ const relationSections = [
}
.glossary-aside__list li{
margin: 6px 0;
margin: 7px 0;
}
.glossary-aside__list a{
text-decoration: none;
font-size: 13px;
line-height: 1.3;
font-size: 14px;
line-height: 1.4;
}
.glossary-aside__list a.is-active{

View File

@@ -74,6 +74,7 @@ const metaRegimesCount = allEntries.filter((entry) => familyOf(entry) === "meta-
const portalLinks = [
{ href: "/glossaire/concepts-fondamentaux/", label: "Concepts fondamentaux" },
{ href: "/glossaire/index-complet/", label: "Index complet" },
{ href: "/glossaire/paradigme-archicratique/", label: "Paradigme archicratique" },
{ href: "/glossaire/scenes-archicratiques/", label: "Scènes archicratiques" },
{ href: "/glossaire/dynamiques-archicratiques/", label: "Dynamiques archicratiques" },
@@ -81,7 +82,6 @@ const portalLinks = [
{ href: "/glossaire/archicrations/", label: "Méta-régimes archicratiques" },
{ href: "/glossaire/paradigmes/", label: "Paradigmes et doctrines" },
{ href: "/glossaire/verbes-de-la-scene/", label: "Verbes de la scène" },
{ href: "/glossaire/index-complet/", label: "Index complet" },
];
---
@@ -101,7 +101,6 @@ const portalLinks = [
</div>
</div>
<section class="glossary-home-aside__block">
<h2 class="glossary-home-aside__heading">Parcours du glossaire</h2>
<ul class="glossary-home-aside__list">
@@ -133,53 +132,54 @@ const portalLinks = [
.glossary-home-aside__block{
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
padding: 12px;
padding: 14px;
background: rgba(127,127,127,0.05);
}
.glossary-home-aside__block--intro{
padding-top: 11px;
padding-bottom: 11px;
padding-top: 13px;
padding-bottom: 13px;
}
.glossary-home-aside__title{
font-size: 14px;
font-size: 16px;
font-weight: 800;
letter-spacing: .2px;
line-height: 1.25;
line-height: 1.3;
}
.glossary-home-aside__meta{
margin-top: 8px;
font-size: 12px;
line-height: 1.35;
opacity: .78;
font-size: 13px;
line-height: 1.4;
opacity: .8;
}
.glossary-home-aside__pills{
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 10px;
gap: 7px;
margin-top: 11px;
}
.glossary-home-aside__pill{
display: inline-flex;
align-items: center;
padding: 4px 9px;
padding: 5px 10px;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 999px;
background: rgba(127,127,127,0.04);
font-size: 12px;
line-height: 1.3;
opacity: .9;
font-size: 13px;
line-height: 1.35;
opacity: .92;
}
.glossary-home-aside__heading{
margin: 0 0 10px;
font-size: 13px;
margin: 0 0 11px;
font-size: 14px;
font-weight: 800;
opacity: .9;
line-height: 1.35;
opacity: .94;
}
.glossary-home-aside__list{
@@ -189,13 +189,13 @@ const portalLinks = [
}
.glossary-home-aside__list li{
margin: 6px 0;
margin: 7px 0;
}
.glossary-home-aside__list a{
text-decoration: none;
font-size: 13px;
line-height: 1.3;
font-size: 14px;
line-height: 1.4;
}
@media (prefers-color-scheme: dark){

View File

@@ -17,7 +17,7 @@ opposedTo: ["archicratie"]
seeAlso: ["tension", "hyperarcalite", "hypercratialite", "institution-invisible"]
---
Lautarchicratie désigne une dérive dun régime archicratique dans laquelle les architectures régulatrices continuent dopérer tout en devenant de plus en plus autonomes, opaques et soustraites à la scène dépreuve.
Lautarchicratie désigne une dérive dun méta-régime archicratique dans laquelle les architectures régulatrices continuent dopérer tout en devenant de plus en plus autonomes, opaques et soustraites à la scène dépreuve.
Dans une configuration autarchicratique, les dispositifs techniques, administratifs, normatifs ou organisationnels qui assurent la régulation des dynamiques collectives restent actifs et parfois efficaces, mais leur fonctionnement devient de moins en moins intelligible, discutable et transformable pour la société quils structurent.

View File

@@ -53,7 +53,7 @@ La co-viabilité peut être compromise par :
- laccumulation non régulée des tensions ;
- la rupture des architectures de régulation ;
- lincompatibilisation durable de dynamiques sociales majeures ;
- lincompatibili durable de dynamiques sociales majeures ;
- la dérive autarchicratique ;
- les formes de domination qui bloquent la révision des structures.

View File

@@ -52,7 +52,7 @@ La désarchicration peut conduire :
## Enjeu politique
Nommer une désarchicration, cest identifier un lieu où la régulation doit être rouvrie plutôt que simplement dénoncée.
Nommer une désarchicration, cest identifier un lieu où la régulation doit être réouverte plutôt que simplement dénoncée.
Le diagnostic a donc une portée stratégique : il repère les zones où une réinstitution des scènes est encore possible.

View File

@@ -1529,27 +1529,39 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
return headerH() + PAGE_GAP + localH + (followH || 0) + HYST;
}
function hasCrossed(el, lineY) {
function hasCrossedTop(el, lineY) {
return Boolean(el && el.getBoundingClientRect().top <= lineY);
}
function hasCrossedBottom(el, lineY) {
return Boolean(el && el.getBoundingClientRect().bottom <= lineY);
}
function getH2DisplayEl(item) {
return item?.h2 || item?.marker || item?.anchor || null;
}
function getH3DisplayEl(item) {
return item?.el || null;
}
function pickH2(lineY) {
if (!H2.length) return null;
let cand = null;
for (const t of H2) {
if (hasCrossed(t.marker, lineY)) cand = t;
const box = getH2DisplayEl(t);
if (hasCrossedBottom(box, lineY)) cand = t;
else break;
}
// Tant quaucun H2 na franchi la ligne de suivi,
// on ne montre rien.
if (!cand) return null;
const down = (window.scrollY || 0) >= lastY;
if (!down && cand && curH2 && cand.id !== curH2.id) {
const topNew = cand.marker.getBoundingClientRect().top;
if (topNew > lineY - (HYST * 2)) cand = curH2;
const box = getH2DisplayEl(cand);
const bottomNew = box ? box.getBoundingClientRect().bottom : Infinity;
if (bottomNew > lineY + (HYST * 2)) cand = curH2;
}
return cand;
@@ -1586,7 +1598,8 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
let cand = null;
for (const t of scoped) {
if (hasCrossed(t.el, lineY)) cand = t;
const box = getH3DisplayEl(t);
if (hasCrossedBottom(box, lineY)) cand = t;
else break;
}
@@ -1596,7 +1609,7 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
function maybeOpenActiveSection(activeH2, lineY) {
if (!activeH2 || !activeH2.id) return;
const pre = activeH2.marker.getBoundingClientRect().top <= (lineY + 140);
const pre = hasCrossedTop(activeH2.marker, lineY + 140);
if (!pre) return;
if (activeH2.id !== lastOpenedH2) {
@@ -1625,13 +1638,13 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
curH3 = nextH3;
if (rfH2) {
const show = Boolean(curH2 && hasCrossed(curH2.marker, lineY));
const show = Boolean(curH2 && hasCrossedBottom(getH2DisplayEl(curH2), lineY));
rfH2.hidden = !show;
if (show) rfH2.textContent = curH2.title;
}
if (rfH3) {
const show = Boolean(curH3 && hasCrossed(curH3.el, lineY));
const show = Boolean(curH3 && hasCrossedBottom(getH3DisplayEl(curH3), lineY));
rfH3.hidden = !show;
if (show) rfH3.textContent = curH3.title;
}

View File

@@ -65,13 +65,15 @@ const slugOf = (item) =>
const hrefOf = (item) => `/glossaire/${slugOf(item)}/`;
const collator = new Intl.Collator("fr", { sensitivity: "base", numeric: true });
const bySlug = new Map(allEntries.map((item) => [slugOf(item), item]));
const bySlug = new Map(
allEntries.map((item) => [slugOf(item).toLowerCase(), item])
);
function resolveEntries(slugs = []) {
const seen = new Set();
return slugs
.map((slug) => bySlug.get(String(slug || "").trim()))
.map((slug) => bySlug.get(String(slug || "").trim().toLowerCase()))
.filter(Boolean)
.filter((item) => {
const slug = slugOf(item);
@@ -125,6 +127,10 @@ const kindLabels = {
verbe: "Verbe",
paradigme: "Paradigme",
doctrine: "Doctrine",
dispositif: "Dispositif",
figure: "Figure",
qualification: "Qualification",
epistemologie: "Épistémologie",
};
const domainLabels = {
@@ -145,13 +151,13 @@ const displayFamily =
kindLabels[entry.data.kind] ??
"Fiche";
const displayDomain =
domainLabels[entry.data.domain] ??
entry.data.domain;
const displayDomain = entry.data.domain
? (domainLabels[entry.data.domain] ?? entry.data.domain)
: "";
const displayLevel =
levelLabels[entry.data.level] ??
entry.data.level;
const displayLevel = entry.data.level
? (levelLabels[entry.data.level] ?? entry.data.level)
: "";
const hasScholarlyMeta =
(entry.data.mobilizedAuthors?.length ?? 0) > 0 ||
@@ -161,6 +167,7 @@ const hasScholarlyMeta =
<GlossaryLayout
title={entry.data.title}
version={entry.data.version}
stickyMode="glossary-entry"
>
<Fragment slot="aside">
<GlossaryAside currentEntry={entry} allEntries={allEntries} />
@@ -173,41 +180,52 @@ const hasScholarlyMeta =
</p>
)}
<header class="glossary-entry-head">
<h1>{entry.data.term}</h1>
<p class="glossary-entry-dek">
<em>{entry.data.definitionShort}</em>
</p>
<header class="glossary-entry-head" data-ge-hero>
<div class="glossary-entry-head__title">
<h1>{entry.data.term}</h1>
</div>
<div class="glossary-entry-signals" aria-label="Repères de lecture">
<span class="glossary-pill glossary-pill--family">
<strong>Famille :</strong> {displayFamily}
</span>
<span class="glossary-pill">
<strong>Domaine :</strong> {displayDomain}
</span>
<span class="glossary-pill">
<strong>Niveau :</strong> {displayLevel}
</span>
<div class="glossary-entry-summary">
<p class="glossary-entry-dek">
<em>{entry.data.definitionShort}</em>
</p>
<div class="glossary-entry-signals" aria-label="Repères de lecture">
<span class="glossary-pill glossary-pill--family">
<strong>Famille :</strong> {displayFamily}
</span>
{displayDomain && (
<span class="glossary-pill">
<strong>Domaine :</strong> {displayDomain}
</span>
)}
{displayLevel && (
<span class="glossary-pill">
<strong>Niveau :</strong> {displayLevel}
</span>
)}
</div>
{hasScholarlyMeta && (
<div class="glossary-entry-meta">
{(entry.data.mobilizedAuthors?.length ?? 0) > 0 && (
<p>
<strong>Auteurs mobilisés :</strong> {entry.data.mobilizedAuthors.join(" / ")}
</p>
)}
{(entry.data.comparisonTraditions?.length ?? 0) > 0 && (
<p>
<strong>Traditions de comparaison :</strong> {entry.data.comparisonTraditions.join(" / ")}
</p>
)}
</div>
)}
</div>
</header>
{hasScholarlyMeta && (
<div class="glossary-entry-meta">
{(entry.data.mobilizedAuthors?.length ?? 0) > 0 && (
<p>
<strong>Auteurs mobilisés :</strong> {entry.data.mobilizedAuthors.join(" / ")}
</p>
)}
{(entry.data.comparisonTraditions?.length ?? 0) > 0 && (
<p>
<strong>Traditions de comparaison :</strong> {entry.data.comparisonTraditions.join(" / ")}
</p>
)}
</div>
)}
<div class="glossary-entry-body">
<Content />
</div>
@@ -235,6 +253,117 @@ const hasScholarlyMeta =
)}
</GlossaryLayout>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-ge-hero]");
const follow = document.getElementById("reading-follow");
const mqMobile = window.matchMedia("(max-width: 860px)");
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-glossary-entry-page";
const FOLLOW_ON_CLASS = "glossary-entry-follow-on";
let lastHeight = -1;
let lastFollowOn = null;
let raf = 0;
body.classList.add(BODY_CLASS);
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const stripLocalSticky = () => {
document
.querySelectorAll(
".glossary-entry-body h2, .glossary-entry-body h3, .glossary-relations h2, .glossary-relations h3"
)
.forEach((el) => {
el.classList.remove("is-sticky");
el.removeAttribute("data-sticky-active");
});
};
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
if (h === lastHeight) return;
lastHeight = h;
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
}
};
const syncFollowState = () => {
const on = computeFollowOn();
if (on === lastFollowOn) return;
lastFollowOn = on;
body.classList.toggle(FOLLOW_ON_CLASS, on);
};
const syncAll = () => {
stripLocalSticky();
syncFollowState();
applyLocalStickyHeight();
};
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
syncAll();
});
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
});
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
: null;
heroResizeObserver?.observe(hero);
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
}
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
<style>
.glossary-legacy-note{
padding: 10px 12px;
@@ -247,25 +376,57 @@ const hasScholarlyMeta =
}
.glossary-entry-head{
margin-bottom: 18px;
position: sticky;
top: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px));
z-index: 11;
margin: 0 0 24px;
border: 1px solid rgba(127,127,127,0.18);
border-radius: 28px;
background:
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.92)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
overflow: hidden;
transition:
border-radius 180ms ease,
box-shadow 180ms ease,
border-color 180ms ease;
}
.glossary-entry-head__title{
padding: 18px 18px 16px;
}
.glossary-entry-head h1{
margin-bottom: 10px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
}
.glossary-entry-summary{
display: grid;
gap: 14px;
padding: 16px 18px 18px;
border-top: 1px solid rgba(127,127,127,0.14);
background: rgba(255,255,255,0.02);
}
.glossary-entry-dek{
margin: 0 0 14px;
font-size: 1.02rem;
line-height: 1.6;
opacity: .95;
margin: 0;
max-width: 76ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
}
.glossary-entry-signals{
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 0 0 6px;
margin: 0;
}
.glossary-pill{
@@ -286,7 +447,7 @@ const hasScholarlyMeta =
}
.glossary-entry-meta{
margin: 0 0 18px;
margin: 0;
padding: 10px 12px;
border: 1px solid rgba(127,127,127,0.18);
border-radius: 12px;
@@ -307,6 +468,13 @@ const hasScholarlyMeta =
margin-bottom: 28px;
}
.glossary-entry-body h2,
.glossary-entry-body h3,
.glossary-relations h2,
.glossary-relations h3{
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 18px);
}
.glossary-relations{
margin-top: 26px;
padding-top: 18px;
@@ -356,6 +524,59 @@ const hasScholarlyMeta =
opacity: .9;
}
:global(body.is-glossary-entry-page #reading-follow){
z-index: 10;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-head){
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-summary){
gap: 10px;
padding-top: 12px;
padding-bottom: 10px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-signals){
gap: 6px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-meta){
padding: 8px 10px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on #reading-follow){
transform: translateY(-1px);
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on #reading-follow .reading-follow__inner){
margin-top: -1px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
:global(body.is-glossary-entry-page .glossary-entry-body h2.is-sticky),
:global(body.is-glossary-entry-page .glossary-entry-body h2[data-sticky-active="true"]),
:global(body.is-glossary-entry-page .glossary-entry-body h3.is-sticky),
:global(body.is-glossary-entry-page .glossary-entry-body h3[data-sticky-active="true"]),
:global(body.is-glossary-entry-page .glossary-relations h2.is-sticky),
:global(body.is-glossary-entry-page .glossary-relations h2[data-sticky-active="true"]),
:global(body.is-glossary-entry-page .glossary-relations h3.is-sticky),
:global(body.is-glossary-entry-page .glossary-relations h3[data-sticky-active="true"]){
position: static !important;
top: auto !important;
z-index: auto !important;
padding: 0 !important;
border: 0 !important;
background: transparent !important;
box-shadow: none !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
}
@media (max-width: 720px){
.glossary-entry-signals{
gap: 6px;
@@ -366,6 +587,32 @@ const hasScholarlyMeta =
}
}
@media (max-width: 860px){
.glossary-entry-head{
position: static;
border-radius: 22px;
margin-bottom: 20px;
}
.glossary-entry-head__title{
padding: 14px 14px 12px;
}
.glossary-entry-summary{
gap: 12px;
padding: 14px;
}
.glossary-entry-dek{
max-width: none;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-head){
margin-bottom: 20px;
border-radius: 22px;
}
}
@media (prefers-color-scheme: dark){
.glossary-entry-meta{
background: rgba(255,255,255,0.03);

View File

@@ -112,20 +112,43 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
</Fragment>
<section class="archi-page" data-archi-page>
<div class="archi-hero" data-archi-hero>
<div class="archi-hero glossary-page-hero" data-archi-hero>
<p class="archi-kicker">Topologie archicratique</p>
<h1>Archicrations</h1>
<p class="archi-intro">
Cette page rassemble les principales formes darchicration distinguées
dans le glossaire. Elle propose une vue densemble des grands régimes de
co-viabilité à partir desquels un collectif se stabilise, se transmet,
se transforme ou se recompose.
</p>
<p class="archi-intro">
Les catégories proposées ci-dessous ne valent pas comme cases closes,
mais comme repères de lecture permettant de situer les différentes
topologies de régulation et leurs articulations.
</p>
<div class="archi-hero-collapsible">
<div
class="archi-hero-more"
id="archi-hero-more"
data-archi-more
aria-hidden="false"
>
<p class="archi-intro">
Les catégories proposées ci-dessous ne valent pas comme cases closes,
mais comme repères de lecture permettant de situer les différentes
topologies de régulation et leurs articulations.
</p>
</div>
<button
class="archi-hero-toggle"
id="archi-hero-toggle"
data-archi-more-toggle
type="button"
aria-controls="archi-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
{sections.map((section) => (
@@ -181,12 +204,20 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-archi-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("archi-hero-more");
const heroToggle = document.getElementById("archi-hero-toggle");
if (!body || !root || !hero) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-archicrations-page";
const FOLLOW_ON_CLASS = "archi-follow-on";
const EXPANDED_CLASS = "archi-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
@@ -200,6 +231,12 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
@@ -211,22 +248,121 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
};
const syncFollowState = () => {
const follow = document.getElementById("reading-follow");
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const followOn =
!mqMobile.matches &&
!!follow &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
@@ -238,13 +374,17 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
});
};
const follow = document.getElementById("reading-follow");
const followObserver =
follow
? new MutationObserver(schedule)
: null;
heroToggle?.addEventListener("click", () => {
expandHero();
});
followObserver?.observe(follow, {
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
@@ -257,6 +397,7 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -294,30 +435,23 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
margin: 0 0 24px;
padding: 18px 18px 20px;
border: 1px solid rgba(127,127,127,0.18);
border-radius: 28px 28px 28px 28px;
border-radius: 28px;
background:
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.92)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.92)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
}
:global(body.is-archicrations-page:not(.archi-follow-on) .archi-hero){
margin-bottom: 24px;
border-radius: 28px 28px 28px 28px;
}
:global(body.is-archicrations-page.archi-follow-on .archi-hero){
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
margin-bottom 180ms ease,
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.archi-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -325,23 +459,75 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
}
.archi-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.archi-intro{
max-width: 76ch;
margin: 0;
max-width: 72ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.archi-intro + .archi-intro{
margin-top: 14px;
.archi-hero-collapsible{
display: grid;
row-gap: 6px;
}
.archi-hero-more{
display: grid;
row-gap: 14px;
max-height: 18rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.archi-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.archi-hero-toggle:hover{
opacity: .84;
}
.archi-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.archi-hero-toggle[hidden]{
display: none !important;
}
.archi-section{
@@ -486,10 +672,33 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
:global(body.is-archicrations-page.archi-follow-on .archi-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-archicrations-page.archi-follow-on .archi-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-archicrations-page.archi-follow-on .archi-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-archicrations-page.archi-follow-on:not(.archi-hero-expanded) .archi-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-archicrations-page.archi-follow-on:not(.archi-hero-expanded) .archi-hero-toggle){
display: inline-flex;
}
:global(body.is-archicrations-page.archi-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -513,11 +722,29 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.archi-intro{
max-width: none;
}
.archi-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.archi-hero-toggle{
display: none !important;
}
:global(body.is-archicrations-page.archi-follow-on .archi-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}

View File

@@ -121,21 +121,44 @@ const readingSteps = [
</Fragment>
<section class="cf-page" data-cf-page>
<div class="cf-hero" data-cf-hero>
<div class="cf-hero glossary-page-hero" data-cf-hero>
<p class="cf-kicker">Portail du glossaire</p>
<h1>Concepts fondamentaux</h1>
<p class="cf-intro">
Cette page rassemble la grammaire minimale de larchicratie. Elle ne
remplace pas les fiches détaillées, mais elle en organise la lecture en
montrant comment les six notions cardinales se répondent, se distinguent
et composent ensemble un même système.
</p>
<p class="cf-intro">
Ces concepts ne valent pas comme unités isolées. Ils forment un noyau de
lecture à partir duquel peuvent ensuite se comprendre les scènes
archicratiques, les dynamiques, les tensions et les méta-régimes de
co-viabilité.
</p>
<div class="cf-hero-collapsible">
<div
class="cf-hero-more"
id="cf-hero-more"
data-cf-more
aria-hidden="false"
>
<p class="cf-intro">
Ces concepts ne valent pas comme unités isolées. Ils forment un noyau de
lecture à partir duquel peuvent ensuite se comprendre les scènes
archicratiques, les dynamiques, les tensions et les méta-régimes de
co-viabilité.
</p>
</div>
<button
class="cf-hero-toggle"
id="cf-hero-toggle"
data-cf-more-toggle
type="button"
aria-controls="cf-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
<section class="cf-section">
@@ -369,12 +392,20 @@ const readingSteps = [
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-cf-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("cf-hero-more");
const heroToggle = document.getElementById("cf-hero-toggle");
if (!body || !root || !hero) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-concepts-fondamentaux-page";
const FOLLOW_ON_CLASS = "cf-follow-on";
const EXPANDED_CLASS = "cf-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
@@ -388,6 +419,12 @@ const readingSteps = [
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
@@ -399,22 +436,121 @@ const readingSteps = [
};
const syncFollowState = () => {
const follow = document.getElementById("reading-follow");
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const followOn =
!mqMobile.matches &&
!!follow &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
@@ -426,13 +562,17 @@ const readingSteps = [
});
};
const follow = document.getElementById("reading-follow");
const followObserver =
follow
? new MutationObserver(schedule)
: null;
heroToggle?.addEventListener("click", () => {
expandHero();
});
followObserver?.observe(follow, {
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
@@ -445,6 +585,7 @@ const readingSteps = [
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -488,13 +629,17 @@ const readingSteps = [
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.cf-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -502,11 +647,12 @@ const readingSteps = [
}
.cf-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.cf-intro{
@@ -515,10 +661,61 @@ const readingSteps = [
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.cf-intro + .cf-intro{
margin-top: 14px;
.cf-hero-collapsible{
display: grid;
row-gap: 6px;
}
.cf-hero-more{
display: grid;
row-gap: 14px;
max-height: 12rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.cf-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.cf-hero-toggle:hover{
opacity: .84;
}
.cf-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.cf-hero-toggle[hidden]{
display: none !important;
}
.cf-section{
@@ -784,10 +981,33 @@ const readingSteps = [
:global(body.is-concepts-fondamentaux-page.cf-follow-on .cf-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on .cf-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on .cf-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on:not(.cf-hero-expanded) .cf-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on:not(.cf-hero-expanded) .cf-hero-toggle){
display: inline-flex;
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -826,11 +1046,29 @@ const readingSteps = [
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.cf-intro{
max-width: none;
}
.cf-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.cf-hero-toggle{
display: none !important;
}
:global(body.is-concepts-fondamentaux-page.cf-follow-on .cf-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}

View File

@@ -118,9 +118,10 @@ const constellationCount = relatedEntries.length;
</Fragment>
<section class="dyna-page" data-dyna-page>
<div class="dyna-hero" data-dyna-hero>
<div class="dyna-hero glossary-page-hero" data-dyna-hero>
<p class="dyna-kicker">Parcours du glossaire</p>
<h1>Dynamiques archicratiques</h1>
<p class="dyna-intro">
Les dynamiques archicratiques désignent les processus par lesquels une
régulation se déplace, se ferme, se rigidifie ou se soustrait à sa
@@ -128,12 +129,34 @@ const constellationCount = relatedEntries.length;
dun régime, mais aussi ses dérives, ses opacifications et ses
pathologies.
</p>
<p class="dyna-intro">
Elles décrivent ainsi le versant processuel de larchicratie : non plus
seulement ce qui tient, mais la manière dont cela se transforme,
saltère, sautonomise ou devient de moins en moins exposable à
lépreuve collective.
</p>
<div class="dyna-hero-collapsible">
<div
class="dyna-hero-more"
id="dyna-hero-more"
data-dyna-more
aria-hidden="false"
>
<p class="dyna-intro">
Elles décrivent ainsi le versant processuel de larchicratie : non plus
seulement ce qui tient, mais la manière dont cela se transforme,
saltère, sautonomise ou devient de moins en moins exposable à
lépreuve collective.
</p>
</div>
<button
class="dyna-hero-toggle"
id="dyna-hero-toggle"
data-dyna-more-toggle
type="button"
aria-controls="dyna-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
<section class="dyna-section">
@@ -239,7 +262,7 @@ const constellationCount = relatedEntries.length;
{otherEntries.length > 0 && (
<div class="dyna-block">
<h3>Notions et diagnostics liés</h3>
<h3 id="notions-et-diagnostics-lies">Notions et diagnostics liés</h3>
<div class="dyna-cards">
{otherEntries.map((entry) => (
<a class="dyna-card" href={hrefOf(entry)}>
@@ -259,7 +282,7 @@ const constellationCount = relatedEntries.length;
{paradigmEntries.length > 0 && (
<div class="dyna-block">
<h3>Paradigmes mobilisés</h3>
<h3 id="paradigmes-mobilises">Paradigmes mobilisés</h3>
<div class="dyna-cards">
{paradigmEntries.map((entry) => (
<a class="dyna-card" href={hrefOf(entry)}>
@@ -340,95 +363,225 @@ const constellationCount = relatedEntries.length;
<script is:inline>
(() => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-dyna-hero]");
if (!body || !root || !hero) return;
const BODY_CLASS = "is-dynamiques-archicratiques-page";
const FOLLOW_ON_CLASS = "dyna-follow-on";
const mqMobile = window.matchMedia("(max-width: 860px)");
body.classList.add(BODY_CLASS);
const setRootVar = (name, value) => {
root.style.setProperty(name, value);
};
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const stripLocalSticky = () => {
document.querySelectorAll(".dyna-section__head").forEach((el) => {
el.classList.remove("is-sticky");
el.removeAttribute("data-sticky-active");
});
};
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
setRootVar("--glossary-local-sticky-h", `${h}px`);
}
};
const syncFollowState = () => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-dyna-hero]");
const follow = document.getElementById("reading-follow");
if (!follow) {
body.classList.remove(FOLLOW_ON_CLASS);
return;
}
const heroMore = document.getElementById("dyna-hero-more");
const heroToggle = document.getElementById("dyna-hero-toggle");
const followOn =
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-dynamiques-archicratiques-page";
const FOLLOW_ON_CLASS = "dyna-follow-on";
const EXPANDED_CLASS = "dyna-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const stripLocalSticky = () => {
document.querySelectorAll(".dyna-section__head").forEach((el) => {
el.classList.remove("is-sticky");
el.removeAttribute("data-sticky-active");
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
};
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
};
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
}
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
requestAnimationFrame(syncAll);
const syncFollowState = () => {
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
requestAnimationFrame(syncAll);
});
};
heroToggle?.addEventListener("click", () => {
expandHero();
});
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
});
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
: null;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
}
schedule();
};
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
: null;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
}
schedule();
})();
</script>
</GlossaryLayout>
@@ -451,13 +604,17 @@ const constellationCount = relatedEntries.length;
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.dyna-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -465,23 +622,75 @@ const constellationCount = relatedEntries.length;
}
.dyna-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.dyna-intro{
max-width: 76ch;
margin: 0;
max-width: 72ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.dyna-intro + .dyna-intro{
margin-top: 14px;
.dyna-hero-collapsible{
display: grid;
row-gap: 6px;
}
.dyna-hero-more{
display: grid;
row-gap: 14px;
max-height: 18rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.dyna-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.dyna-hero-toggle:hover{
opacity: .84;
}
.dyna-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.dyna-hero-toggle[hidden]{
display: none !important;
}
.dyna-section{
@@ -699,10 +908,33 @@ const constellationCount = relatedEntries.length;
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on .dyna-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on .dyna-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on .dyna-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on:not(.dyna-hero-expanded) .dyna-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on:not(.dyna-hero-expanded) .dyna-hero-toggle){
display: inline-flex;
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -726,11 +958,29 @@ const constellationCount = relatedEntries.length;
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.dyna-intro{
max-width: none;
}
.dyna-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.dyna-hero-toggle{
display: none !important;
}
:global(body.is-dynamiques-archicratiques-page.dyna-follow-on .dyna-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -87,7 +87,11 @@ const paradigmesPageHref = "/glossaire/paradigmes/";
const indexCompletPageHref = "/glossaire/index-complet/";
---
<GlossaryLayout title="Glossaire archicratique" version="1.0">
<GlossaryLayout
title="Glossaire archicratique"
version="1.0"
stickyMode="glossary-home"
>
<Fragment slot="aside">
<GlossaryHomeAside allEntries={entries} />
</Fragment>

View File

@@ -254,9 +254,10 @@ const translationCount = casIaEntries.length;
</Fragment>
<section class="pa-page" data-pa-page>
<div class="pa-hero" data-pa-hero>
<div class="pa-hero glossary-page-hero" data-pa-hero>
<p class="pa-kicker">Parcours du glossaire</p>
<h1>Paradigme archicratique</h1>
<p class="pa-intro">
Le paradigme archicratique propose dintelligibiliser les sociétés
humaines à partir de leurs <strong>architectures de régulation</strong> :
@@ -265,20 +266,43 @@ const translationCount = casIaEntries.length;
ordre collectif se fonde, seffectue, se met en scène, se ferme,
sexpose ou se réouvre.
</p>
<p class="pa-intro">
Il ne réduit donc jamais la régulation à une seule logique. Il cherche
au contraire à penser ensemble les prises de fondation, les chaînes
deffectuation, les scènes de comparution, les dynamiques de fermeture
ou doblitération et les conditions de la co-viabilité dun monde
commun.
</p>
<p class="pa-intro">
Cette page sert de portail de synthèse. Elle organise une vue densemble
du système archicratique : son noyau conceptuel, son architecture
interne, ses formes typologiques, ses comparaisons théoriques, ses
tensions irréductibles et ses traductions contemporaines, notamment
dans le cas des systèmes dIA.
</p>
<div class="pa-hero-collapsible">
<div
class="pa-hero-more"
id="pa-hero-more"
data-pa-more
aria-hidden="false"
>
<p class="pa-intro">
Il ne réduit donc jamais la régulation à une seule logique. Il cherche
au contraire à penser ensemble les prises de fondation, les chaînes
deffectuation, les scènes de comparution, les dynamiques de fermeture
ou doblitération et les conditions de la co-viabilité dun monde
commun.
</p>
<p class="pa-intro">
Cette page sert de portail de synthèse. Elle organise une vue densemble
du système archicratique : son noyau conceptuel, son architecture
interne, ses formes typologiques, ses comparaisons théoriques, ses
tensions irréductibles et ses traductions contemporaines, notamment
dans le cas des systèmes dIA.
</p>
</div>
<button
class="pa-hero-toggle"
id="pa-hero-toggle"
data-pa-more-toggle
type="button"
aria-controls="pa-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
<section class="pa-section">
@@ -399,7 +423,7 @@ const translationCount = casIaEntries.length;
{sceneEntries.length > 0 && (
<div class="pa-block">
<h3>Scènes, topologies et instituabilité</h3>
<h3 id="scenes-topologies-et-instituabilite">Scènes, topologies et instituabilité</h3>
<p class="pa-block__intro">
Le paradigme archicratique ne pense pas seulement ce qui régule,
mais aussi les lieux, les formats et les conditions par lesquels
@@ -425,7 +449,7 @@ const translationCount = casIaEntries.length;
{dynamicEntries.length > 0 && (
<div class="pa-block">
<h3>Dynamiques et pathologies</h3>
<h3 id="dynamiques-et-pathologies">Dynamiques et pathologies</h3>
<p class="pa-block__intro">
Toute architecture de régulation se transforme, se ferme, se
dégrade ou se réouvre. Le paradigme ne décrit donc pas seulement
@@ -445,7 +469,7 @@ const translationCount = casIaEntries.length;
{methodEntries.length > 0 && (
<div class="pa-block">
<h3>Figures et opérateurs méthodologiques</h3>
<h3 id="figures-et-operateurs-methodologiques">Figures et opérateurs méthodologiques</h3>
<p class="pa-block__intro">
Le paradigme suppose enfin des figures, des qualifications et des
instruments danalyse capables de rendre la régulation lisible,
@@ -483,7 +507,7 @@ const translationCount = casIaEntries.length;
{typologyEntries.length > 0 && (
<div class="pa-block">
<h3>Typologie des régimes de co-viabilité</h3>
<h3 id="typologie-des-regimes-de-co-viabilite">Typologie des régimes de co-viabilité</h3>
<p class="pa-block__intro">
Le paradigme ne vaut pas seulement comme noyau conceptuel. Il
souvre aussi sur une typologie des formes de régulation et sur
@@ -504,7 +528,7 @@ const translationCount = casIaEntries.length;
{paradigmEntries.length > 0 && (
<div class="pa-block">
<h3>Paradigmes mobilisés</h3>
<h3 id="paradigmes-mobilises">Paradigmes mobilisés</h3>
<p class="pa-block__intro">
Larchicratie ne sélabore pas dans un vide théorique. Elle
dialogue avec plusieurs paradigmes qui éclairent ses voisinages,
@@ -530,7 +554,7 @@ const translationCount = casIaEntries.length;
{doctrineEntries.length > 0 && (
<div class="pa-block">
<h3>Doctrines fondatrices</h3>
<h3 id="doctrines-fondatrices">Doctrines fondatrices</h3>
<p class="pa-block__intro">
Certaines doctrines classiques continuent de servir de contrepoints
ou de points de départ obligés. Le paradigme archicratique les
@@ -603,7 +627,7 @@ const translationCount = casIaEntries.length;
{casIaEntries.length > 0 && (
<div class="pa-block">
<h3>Traduction contemporaine : Cas IA</h3>
<h3 id="traduction-contemporaine-cas-ia">Traduction contemporaine : Cas IA</h3>
<div class="pa-cards">
{casIaEntries.map((entry) => (
<a class="pa-card" href={hrefOf(entry)}>
@@ -617,7 +641,7 @@ const translationCount = casIaEntries.length;
{portalLinks.length > 0 && (
<div class="pa-block">
<h3>Portails voisins déjà stabilisés</h3>
<h3 id="portails-voisins-deja-stabilises">Portails voisins déjà stabilisés</h3>
<div class="pa-cards">
{portalLinks.map((item) => (
<a class="pa-card" href={item.href}>
@@ -670,104 +694,229 @@ const translationCount = casIaEntries.length;
</section>
</section>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-pa-hero]");
const follow = document.getElementById("reading-follow");
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-pa-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("pa-hero-more");
const heroToggle = document.getElementById("pa-hero-toggle");
if (!body || !root || !hero || !follow) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-paradigme-archicratique-page";
const FOLLOW_ON_CLASS = "pa-follow-on";
const mqMobile = window.matchMedia("(max-width: 860px)");
const BODY_CLASS = "is-paradigme-archicratique-page";
const FOLLOW_ON_CLASS = "pa-follow-on";
const EXPANDED_CLASS = "pa-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
body.classList.add(BODY_CLASS);
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
body.classList.add(BODY_CLASS);
const stripLocalSticky = () => {
document.querySelectorAll(".pa-section__head").forEach((el) => {
el.classList.remove("is-sticky");
el.removeAttribute("data-sticky-active");
});
};
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
}
};
const syncFollowState = () => {
const followOn =
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
requestAnimationFrame(syncAll);
});
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
const stripLocalSticky = () => {
document.querySelectorAll(".pa-section__head").forEach((el) => {
el.classList.remove("is-sticky");
el.removeAttribute("data-sticky-active");
});
};
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
: null;
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
heroResizeObserver?.observe(hero);
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
}
};
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
const syncFollowState = () => {
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
})();
</script>
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
requestAnimationFrame(syncAll);
});
};
heroToggle?.addEventListener("click", () => {
expandHero();
});
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
});
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
: null;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
}
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
@@ -780,24 +929,21 @@ const translationCount = casIaEntries.length;
top: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px));
z-index: 11;
margin: 0 0 24px;
padding:
var(--portal-hero-pad-top)
var(--portal-hero-pad-x)
var(--portal-hero-pad-bottom);
padding: 18px 18px 20px;
border: 1px solid rgba(127,127,127,0.18);
border-radius: 28px;
background:
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.92)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.92)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: var(--portal-hero-gap);
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
margin-bottom 180ms ease,
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.pa-kicker{
@@ -810,7 +956,7 @@ const translationCount = casIaEntries.length;
.pa-hero h1{
margin: 0;
font-size: var(--portal-hero-h1-size);
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
@@ -819,23 +965,65 @@ const translationCount = casIaEntries.length;
.pa-intro{
margin: 0;
max-width: var(--portal-hero-intro-maxw);
font-size: var(--portal-hero-intro-size);
line-height: var(--portal-hero-intro-lh);
max-width: 72ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease,
max-height 220ms ease,
opacity 180ms ease,
margin-top 180ms ease;
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.pa-intro + .pa-intro{
.pa-hero-collapsible{
display: grid;
row-gap: 6px;
}
.pa-hero-more{
display: grid;
row-gap: 14px;
max-height: 28rem;
overflow: hidden;
max-height: var(--portal-hero-secondary-max-h);
opacity: var(--portal-hero-secondary-opacity);
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.pa-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.pa-hero-toggle:hover{
opacity: .84;
}
.pa-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.pa-hero-toggle[hidden]{
display: none !important;
}
.pa-section{
@@ -1058,13 +1246,36 @@ const translationCount = casIaEntries.length;
:global(body.is-paradigme-archicratique-page #reading-follow){
z-index: 10;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on .pa-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on .pa-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-paradigme-archicratique-page.pa-follow-on .pa-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on:not(.pa-hero-expanded) .pa-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on:not(.pa-hero-expanded) .pa-hero-toggle){
display: inline-flex;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -1085,16 +1296,34 @@ const translationCount = casIaEntries.length;
@media (max-width: 860px){
.pa-hero{
position: static;
border-radius: 22px;
margin-bottom: 20px;
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.pa-intro{
max-width: none;
}
.pa-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.pa-hero-toggle{
display: none !important;
}
:global(body.is-paradigme-archicratique-page.pa-follow-on .pa-hero){
border-radius: 22px;
margin-bottom: 20px;
}
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}
@media (prefers-color-scheme: dark){
.pa-focus-card,

View File

@@ -66,21 +66,44 @@ const paradigmesCount = paradigmes.length;
</Fragment>
<section class="theo-page" data-theo-page>
<div class="theo-hero" data-theo-hero>
<div class="theo-hero glossary-page-hero" data-theo-hero>
<p class="theo-kicker">Cartographie théorique</p>
<h1>Paradigmes et doctrines</h1>
<p class="theo-intro">
Larchicratie ne se déploie pas dans le vide. Elle sinscrit dans un
paysage intellectuel plus large où se croisent des doctrines
fondatrices de lordre et des paradigmes de régulation des collectifs.
</p>
<p class="theo-intro">
On appellera ici <strong>doctrines fondatrices</strong> les formulations
qui posent un principe premier de légitimité, de souveraineté ou dordre
politique. On appellera <strong>paradigmes régulateurs</strong> les
cadres théoriques qui décrivent des modes de tenue, de conflictualité,
dadministration, de reproduction ou de transformation des sociétés.
</p>
<div class="theo-hero-collapsible">
<div
class="theo-hero-more"
id="theo-hero-more"
data-theo-more
aria-hidden="false"
>
<p class="theo-intro">
On appellera ici <strong>doctrines fondatrices</strong> les formulations
qui posent un principe premier de légitimité, de souveraineté ou dordre
politique. On appellera <strong>paradigmes régulateurs</strong> les
cadres théoriques qui décrivent des modes de tenue, de conflictualité,
dadministration, de reproduction ou de transformation des sociétés.
</p>
</div>
<button
class="theo-hero-toggle"
id="theo-hero-toggle"
data-theo-more-toggle
type="button"
aria-controls="theo-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
{doctrines.length > 0 && (
@@ -227,12 +250,20 @@ const paradigmesCount = paradigmes.length;
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-theo-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("theo-hero-more");
const heroToggle = document.getElementById("theo-hero-toggle");
if (!body || !root || !hero) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-paradigmes-page";
const FOLLOW_ON_CLASS = "theo-follow-on";
const EXPANDED_CLASS = "theo-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
@@ -246,6 +277,12 @@ const paradigmesCount = paradigmes.length;
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
@@ -257,22 +294,121 @@ const paradigmesCount = paradigmes.length;
};
const syncFollowState = () => {
const follow = document.getElementById("reading-follow");
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const followOn =
!mqMobile.matches &&
!!follow &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
@@ -284,13 +420,17 @@ const paradigmesCount = paradigmes.length;
});
};
const follow = document.getElementById("reading-follow");
const followObserver =
follow
? new MutationObserver(schedule)
: null;
heroToggle?.addEventListener("click", () => {
expandHero();
});
followObserver?.observe(follow, {
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
@@ -303,6 +443,7 @@ const paradigmesCount = paradigmes.length;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -346,13 +487,17 @@ const paradigmesCount = paradigmes.length;
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.theo-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -360,23 +505,75 @@ const paradigmesCount = paradigmes.length;
}
.theo-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.theo-intro{
max-width: 76ch;
margin: 0;
max-width: 72ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.theo-intro + .theo-intro{
margin-top: 14px;
.theo-hero-collapsible{
display: grid;
row-gap: 6px;
}
.theo-hero-more{
display: grid;
row-gap: 14px;
max-height: 18rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.theo-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.theo-hero-toggle:hover{
opacity: .84;
}
.theo-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.theo-hero-toggle[hidden]{
display: none !important;
}
.theo-section{
@@ -521,10 +718,33 @@ const paradigmesCount = paradigmes.length;
:global(body.is-paradigmes-page.theo-follow-on .theo-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-paradigmes-page.theo-follow-on .theo-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-paradigmes-page.theo-follow-on .theo-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-paradigmes-page.theo-follow-on:not(.theo-hero-expanded) .theo-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-paradigmes-page.theo-follow-on:not(.theo-hero-expanded) .theo-hero-toggle){
display: inline-flex;
}
:global(body.is-paradigmes-page.theo-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -548,11 +768,29 @@ const paradigmesCount = paradigmes.length;
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.theo-intro{
max-width: none;
}
.theo-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.theo-hero-toggle{
display: none !important;
}
:global(body.is-paradigmes-page.theo-follow-on .theo-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}

View File

@@ -107,21 +107,44 @@ const constellationCount = relatedEntries.length;
</Fragment>
<section class="scene-page" data-scene-page>
<div class="scene-hero" data-scene-hero>
<p class="scene-kicker">Parcours du glossaire</p>
<h1>Scènes archicratiques</h1>
<p class="scene-intro">
Les scènes archicratiques désignent les espaces de comparution,
dexposition, de contestation et de révision par lesquels une
architecture régulatrice cesse dêtre purement opaque pour devenir
visible, discutable et transformable.
</p>
<p class="scene-intro">
Dans léconomie générale du paradigme, elles sont ce qui empêche la
régulation de se refermer sur elle-même. Elles ouvrent un espace où les
tensions peuvent apparaître, être qualifiées, disputées et réorganisées.
</p>
<div class="scene-hero glossary-page-hero" data-scene-hero>
<p class="scene-kicker">Parcours du glossaire</p>
<h1>Scènes archicratiques</h1>
<p class="scene-intro">
Les scènes archicratiques désignent les espaces de comparution,
dexposition, de contestation et de révision par lesquels une
architecture régulatrice cesse dêtre purement opaque pour devenir
visible, discutable et transformable.
</p>
<div class="scene-hero-collapsible">
<div
class="scene-hero-more"
id="scene-hero-more"
data-scene-more
aria-hidden="false"
>
<p class="scene-intro">
Dans léconomie générale du paradigme, elles sont ce qui empêche la
régulation de se refermer sur elle-même. Elles ouvrent un espace où les
tensions peuvent apparaître, être qualifiées, disputées et réorganisées.
</p>
</div>
<button
class="scene-hero-toggle"
id="scene-hero-toggle"
data-scene-more-toggle
type="button"
aria-controls="scene-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
<section class="scene-section">
<div class="scene-section__head">
@@ -310,23 +333,29 @@ const constellationCount = relatedEntries.length;
</section>
</section>
<script is:inline>
(() => {
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-scene-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("scene-hero-more");
const heroToggle = document.getElementById("scene-hero-toggle");
if (!body || !root || !hero) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-scenes-archicratiques-page";
const FOLLOW_ON_CLASS = "scene-follow-on";
const EXPANDED_CLASS = "scene-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
const setRootVar = (name, value) => {
root.style.setProperty(name, value);
};
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
@@ -337,18 +366,137 @@ const constellationCount = relatedEntries.length;
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
} else {
setRootVar("--glossary-local-sticky-h", `${h}px`);
root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
}
};
const syncFollowState = () => {
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
@@ -361,6 +509,22 @@ const constellationCount = relatedEntries.length;
});
};
heroToggle?.addEventListener("click", () => {
expandHero();
});
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
});
const heroResizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(schedule)
@@ -368,6 +532,7 @@ const constellationCount = relatedEntries.length;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -382,8 +547,15 @@ const constellationCount = relatedEntries.length;
}
schedule();
})();
</script>
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
@@ -404,13 +576,17 @@ const constellationCount = relatedEntries.length;
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.scene-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -418,11 +594,12 @@ const constellationCount = relatedEntries.length;
}
.scene-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.scene-intro{
@@ -431,12 +608,62 @@ const constellationCount = relatedEntries.length;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.scene-intro + .scene-intro{
margin-top: 14px;
.scene-hero-collapsible{
display: grid;
row-gap: 6px;
}
.scene-hero-more{
display: grid;
row-gap: 14px;
max-height: 28rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.scene-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.scene-hero-toggle:hover{
opacity: .84;
}
.scene-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.scene-hero-toggle[hidden]{
display: none !important;
}
.scene-section{
margin-top: 34px;
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 28px);
@@ -640,6 +867,40 @@ const constellationCount = relatedEntries.length;
line-height: 1.3;
}
:global(body.is-scenes-archicratiques-page.scene-follow-on .scene-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-scenes-archicratiques-page.scene-follow-on .scene-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-scenes-archicratiques-page.scene-follow-on .scene-intro){
max-width: 72ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-scenes-archicratiques-page.scene-follow-on:not(.scene-hero-expanded) .scene-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-scenes-archicratiques-page.scene-follow-on:not(.scene-hero-expanded) .scene-hero-toggle){
display: inline-flex;
}
:global(body.is-scenes-archicratiques-page.scene-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
}
:global(body.is-scenes-archicratiques-page #reading-follow){
z-index: 10;
}
@@ -662,6 +923,17 @@ const constellationCount = relatedEntries.length;
position: static;
border-radius: 22px;
margin-bottom: 20px;
row-gap: 12px;
}
.scene-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.scene-hero-toggle{
display: none !important;
}
}

View File

@@ -158,9 +158,10 @@ const tensionsCount = irreducibleTensions.length;
</Fragment>
<section class="tir-page" data-tir-page>
<div class="tir-hero" data-tir-hero>
<div class="tir-hero glossary-page-hero" data-tir-hero>
<p class="tir-kicker">Parcours du glossaire</p>
<h1>Tensions irréductibles</h1>
<p class="tir-intro">
Cette page rassemble les dix tensions que le chapitre 5 présente comme
<strong> ontologiquement irréductibles</strong> et politiquement fondatrices.
@@ -168,11 +169,33 @@ const tensionsCount = irreducibleTensions.length;
elles désignent des lignes de conflictualité plus profondes, à partir
desquelles une scène archicratique doit organiser la co-viabilité.
</p>
<p class="tir-intro">
Le point décisif nest donc pas de dresser un inventaire conjoncturel
des crises, mais didentifier des foyers structuraux suffisamment
fondamentaux pour traverser durablement les régulations collectives.
</p>
<div class="tir-hero-collapsible">
<div
class="tir-hero-more"
id="tir-hero-more"
data-tir-more
aria-hidden="false"
>
<p class="tir-intro">
Le point décisif nest donc pas de dresser un inventaire conjoncturel
des crises, mais didentifier des foyers structuraux suffisamment
fondamentaux pour traverser durablement les régulations collectives.
</p>
</div>
<button
class="tir-hero-toggle"
id="tir-hero-toggle"
data-tir-more-toggle
type="button"
aria-controls="tir-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
<section class="tir-section">
@@ -360,12 +383,19 @@ const tensionsCount = irreducibleTensions.length;
const root = document.documentElement;
const hero = document.querySelector("[data-tir-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("tir-hero-more");
const heroToggle = document.getElementById("tir-hero-toggle");
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-tensions-irreductibles-page";
const FOLLOW_ON_CLASS = "tir-follow-on";
const EXPANDED_CLASS = "tir-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
@@ -379,6 +409,12 @@ const tensionsCount = irreducibleTensions.length;
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
@@ -390,19 +426,121 @@ const tensionsCount = irreducibleTensions.length;
};
const syncFollowState = () => {
const followOn =
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
@@ -414,6 +552,15 @@ const tensionsCount = irreducibleTensions.length;
});
};
heroToggle?.addEventListener("click", () => {
expandHero();
});
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
@@ -428,6 +575,7 @@ const tensionsCount = irreducibleTensions.length;
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -471,13 +619,17 @@ const tensionsCount = irreducibleTensions.length;
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.tir-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -485,23 +637,75 @@ const tensionsCount = irreducibleTensions.length;
}
.tir-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.tir-intro{
max-width: 76ch;
margin: 0;
max-width: 72ch;
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.tir-intro + .tir-intro{
margin-top: 14px;
.tir-hero-collapsible{
display: grid;
row-gap: 6px;
}
.tir-hero-more{
display: grid;
row-gap: 14px;
max-height: 18rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.tir-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.tir-hero-toggle:hover{
opacity: .84;
}
.tir-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.tir-hero-toggle[hidden]{
display: none !important;
}
.tir-section{
@@ -718,10 +922,33 @@ const tensionsCount = irreducibleTensions.length;
:global(body.is-tensions-irreductibles-page.tir-follow-on .tir-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-tensions-irreductibles-page.tir-follow-on .tir-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-tensions-irreductibles-page.tir-follow-on .tir-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-tensions-irreductibles-page.tir-follow-on:not(.tir-hero-expanded) .tir-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-tensions-irreductibles-page.tir-follow-on:not(.tir-hero-expanded) .tir-hero-toggle){
display: inline-flex;
}
:global(body.is-tensions-irreductibles-page.tir-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -745,11 +972,29 @@ const tensionsCount = irreducibleTensions.length;
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.tir-intro{
max-width: none;
}
.tir-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.tir-hero-toggle{
display: none !important;
}
:global(body.is-tensions-irreductibles-page.tir-follow-on .tir-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}

View File

@@ -230,19 +230,42 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
</Fragment>
<section class="verbs-page" data-verbs-page>
<div class="verbs-hero" data-verbs-hero>
<div class="verbs-hero glossary-page-hero" data-verbs-hero>
<p class="verbs-kicker">Mini-glossaire systémique</p>
<h1>Verbes de la scène archicratique</h1>
<p class="verbs-intro">
Cette page ne rassemble pas des notions de régime, de topologie ou de processus,
mais des verbes danalyse. Elle sert à qualifier ce qui arrive à une scène :
comment elle souvre, comment elle séloigne, comment elle se ferme,
comment elle est capturée, et comment un archicrate peut encore y répondre.
</p>
<p class="verbs-intro">
Elle constitue ainsi un outil de description fin, complémentaire des fiches
consacrées aux scènes, aux topologies et aux dynamiques archicratiques.
</p>
<div class="verbs-hero-collapsible">
<div
class="verbs-hero-more"
id="verbs-hero-more"
data-verbs-more
aria-hidden="false"
>
<p class="verbs-intro">
Elle constitue ainsi un outil de description fin, complémentaire des fiches
consacrées aux scènes, aux topologies et aux dynamiques archicratiques.
</p>
</div>
<button
class="verbs-hero-toggle"
id="verbs-hero-toggle"
data-verbs-more-toggle
type="button"
aria-controls="verbs-hero-more"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
</div>
{sections.map((section) => (
@@ -290,12 +313,20 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-verbs-hero]");
const follow = document.getElementById("reading-follow");
const heroMore = document.getElementById("verbs-hero-more");
const heroToggle = document.getElementById("verbs-hero-toggle");
if (!body || !root || !hero) return;
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-verbes-de-la-scene-page";
const FOLLOW_ON_CLASS = "verbs-follow-on";
const EXPANDED_CLASS = "verbs-hero-expanded";
const mqMobile = window.matchMedia("(max-width: 860px)");
const AUTO_COLLAPSE_DELTA = 160;
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
body.classList.add(BODY_CLASS);
@@ -309,6 +340,12 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
});
};
const computeFollowOn = () =>
!mqMobile.matches &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
@@ -320,22 +357,121 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
};
const syncFollowState = () => {
const follow = document.getElementById("reading-follow");
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
return on;
};
const followOn =
!mqMobile.matches &&
!!follow &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
body.classList.toggle(FOLLOW_ON_CLASS, followOn);
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "true");
}
if (heroToggle) {
heroToggle.hidden = false;
heroToggle.setAttribute("aria-expanded", "false");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const expandHero = () => {
body.classList.add(EXPANDED_CLASS);
expandedAtY = window.scrollY || 0;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "true");
}
try {
window.__archiUpdateFollow?.();
} catch {}
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
if (!followOn || mqMobile.matches) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
return;
}
if (heroMore) {
heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
}
if (heroToggle) {
heroToggle.hidden = !collapsed;
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
lastScrollY = window.scrollY || 0;
return;
}
if (!body.classList.contains(EXPANDED_CLASS)) {
lastScrollY = window.scrollY || 0;
return;
}
if (expandedAtY == null) {
lastScrollY = window.scrollY || 0;
return;
}
const currentY = window.scrollY || 0;
const scrollingDown = currentY > lastScrollY;
const delta = currentY - expandedAtY;
if (scrollingDown && delta >= AUTO_COLLAPSE_DELTA) {
collapseHero();
}
lastScrollY = currentY;
};
const syncAll = () => {
stripLocalSticky();
applyLocalStickyHeight();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
};
let raf = 0;
@@ -347,13 +483,17 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
});
};
const follow = document.getElementById("reading-follow");
const followObserver =
follow
? new MutationObserver(schedule)
: null;
heroToggle?.addEventListener("click", () => {
expandHero();
});
followObserver?.observe(follow, {
const onScroll = () => {
maybeAutoCollapseOnScroll();
schedule();
};
const followObserver = new MutationObserver(schedule);
followObserver.observe(follow, {
attributes: true,
attributeFilter: ["class", "style", "aria-hidden"],
subtree: false,
@@ -366,6 +506,7 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
@@ -409,13 +550,17 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease;
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
}
.verbs-kicker{
margin: 0 0 10px;
margin: 0;
font-size: 12px;
letter-spacing: .08em;
text-transform: uppercase;
@@ -423,11 +568,12 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
}
.verbs-hero h1{
margin: 0 0 14px;
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition: font-size 180ms ease;
}
.verbs-intro{
@@ -436,10 +582,61 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
}
.verbs-intro + .verbs-intro{
margin-top: 14px;
.verbs-hero-collapsible{
display: grid;
row-gap: 6px;
}
.verbs-hero-more{
display: grid;
row-gap: 14px;
max-height: 12rem;
overflow: hidden;
opacity: 1;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.verbs-hero-toggle{
display: none;
align-self: flex-start;
width: fit-content;
margin: 0;
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
line-height: 1.2;
letter-spacing: .01em;
text-transform: none;
opacity: .56;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
}
.verbs-hero-toggle:hover{
opacity: .84;
}
.verbs-hero-toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.verbs-hero-toggle[hidden]{
display: none !important;
}
.verbs-section{
@@ -488,6 +685,13 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
background: rgba(127,127,127,0.05);
transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.verbs-card:hover{
transform: translateY(-1px);
background: rgba(127,127,127,0.08);
border-color: rgba(0,217,255,0.16);
}
.verbs-card__index{
@@ -580,10 +784,33 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
:global(body.is-verbes-de-la-scene-page.verbs-follow-on .verbs-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on .verbs-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on .verbs-intro){
max-width: 68ch;
font-size: .98rem;
line-height: 1.48;
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on:not(.verbs-hero-expanded) .verbs-hero-more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on:not(.verbs-hero-expanded) .verbs-hero-toggle){
display: inline-flex;
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on #reading-follow .reading-follow__inner){
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -607,11 +834,29 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
.verbs-intro{
max-width: none;
}
.verbs-hero-more{
max-height: none;
opacity: 1;
overflow: visible;
}
.verbs-hero-toggle{
display: none !important;
}
:global(body.is-verbes-de-la-scene-page.verbs-follow-on .verbs-hero){
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
}
}
@@ -620,5 +865,9 @@ const totalCount = sections.reduce((sum, section) => sum + section.items.length,
.verbs-aside__block{
background: rgba(255,255,255,0.04);
}
.verbs-card:hover{
background: rgba(255,255,255,0.07);
}
}
</style>

View File

@@ -442,10 +442,10 @@ html{ scroll-behavior: smooth; }
opacity: .96;
}
.rf-h3{
font-size: var(--rf-h3-size);
line-height: var(--rf-h3-lh);
font-weight: var(--rf-h3-fw);
opacity: .92;
font-size: calc(var(--rf-h2-size, 1.5rem) * 0.72);
line-height: calc(var(--rf-h2-lh, 1.25) * 0.9);
font-weight: var(--rf-h3-fw, 650);
opacity: .86;
}
.rf-line:hover{ text-decoration: underline; }