Merge pull request 'feat(glossaire): harmonize portal pages and sticky reading ux' (#298) from feat/glossaire-portal-polish-final into main
Reviewed-on: #298
This commit was merged in pull request #298.
This commit is contained in:
87
src/components/GlossaryPortalCta.astro
Normal file
87
src/components/GlossaryPortalCta.astro
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
export interface Props {
|
||||
href: string;
|
||||
label: string;
|
||||
icon?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
href,
|
||||
label,
|
||||
icon = "↗",
|
||||
className,
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<a class:list={["glossary-portal-cta", className]} href={href}>
|
||||
<span>{label}</span>
|
||||
<span aria-hidden="true">{icon}</span>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.glossary-portal-cta{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid rgba(0,217,255,0.24);
|
||||
border-radius: 999px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.10), rgba(0,217,255,0.04)),
|
||||
rgba(127,127,127,0.06);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255,255,255,0.05),
|
||||
0 0 0 1px rgba(0,217,255,0.04);
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: .01em;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease,
|
||||
box-shadow 120ms ease;
|
||||
}
|
||||
|
||||
.glossary-portal-cta:hover{
|
||||
transform: translateY(-1px);
|
||||
border-color: rgba(0,217,255,0.34);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.14), rgba(0,217,255,0.06)),
|
||||
rgba(127,127,127,0.08);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255,255,255,0.06),
|
||||
0 0 0 1px rgba(0,217,255,0.08),
|
||||
0 10px 28px rgba(0,0,0,0.18);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-portal-cta:focus-visible{
|
||||
outline: 2px solid rgba(0,217,255,0.28);
|
||||
outline-offset: 4px;
|
||||
}
|
||||
|
||||
@media (max-width: 720px){
|
||||
.glossary-portal-cta{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.glossary-portal-cta{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.12), rgba(0,217,255,0.05)),
|
||||
rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.glossary-portal-cta:hover{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.16), rgba(0,217,255,0.07)),
|
||||
rgba(255,255,255,0.06);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
96
src/components/GlossaryPortalPanel.astro
Normal file
96
src/components/GlossaryPortalPanel.astro
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
export interface Props {
|
||||
id?: string;
|
||||
title: string;
|
||||
count?: string;
|
||||
intro?: string;
|
||||
surface?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
id,
|
||||
title,
|
||||
count,
|
||||
intro,
|
||||
surface = false,
|
||||
className,
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<div
|
||||
class:list={[
|
||||
"glossary-portal-panel",
|
||||
surface && "glossary-portal-panel--surface",
|
||||
className,
|
||||
]}
|
||||
>
|
||||
<div class="glossary-portal-panel__head">
|
||||
<h3 id={id}>{title}</h3>
|
||||
{count && <span class="glossary-portal-panel__count">{count}</span>}
|
||||
</div>
|
||||
|
||||
{intro && <p class="glossary-portal-panel__intro">{intro}</p>}
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.glossary-portal-panel{
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.glossary-portal-panel--surface{
|
||||
padding: 18px 18px 16px;
|
||||
border: 1px solid var(--glossary-border, rgba(127,127,127,0.18));
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
var(--glossary-bg-soft, rgba(127,127,127,0.035));
|
||||
}
|
||||
|
||||
.glossary-portal-panel__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.glossary-portal-panel__head h3{
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 36px);
|
||||
}
|
||||
|
||||
.glossary-portal-panel__count{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
opacity: .78;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.glossary-portal-panel__intro{
|
||||
max-width: 78ch;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.glossary-portal-panel--surface{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
rgba(255,255,255,0.04);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import GlossaryPortalAside from "../../components/GlossaryPortalAside.astro";
|
||||
import GlossaryPortalHero from "../../components/GlossaryPortalHero.astro";
|
||||
import GlossaryPortalSection from "../../components/GlossaryPortalSection.astro";
|
||||
import GlossaryPortalStickySync from "../../components/GlossaryPortalStickySync.astro";
|
||||
import GlossaryPortalPanel from "../../components/GlossaryPortalPanel.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import {
|
||||
buildGlossaryBySlug,
|
||||
@@ -246,20 +247,14 @@ const prolongerLinks = [
|
||||
intro="Ces diagnostics entrent en résonance avec d’autres notions et paradigmes qui permettent de préciser les mécanismes de fermeture, de capture, d’opacification ou de désajustement de la régulation."
|
||||
>
|
||||
{otherEntries.length > 0 && (
|
||||
<div class="dyna-block dyna-block--panel">
|
||||
<div class="dyna-block__head">
|
||||
<h3 id="notions-et-diagnostics-lies">Notions et diagnostics liés</h3>
|
||||
<span class="dyna-block__count">
|
||||
{otherCount} entrée{otherCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="dyna-block__intro">
|
||||
Ces entrées prolongent l’analyse des dérives archicratiques vers
|
||||
des questions d’empêchement, d’invisibilisation, de fermeture ou
|
||||
de capture de la scène régulatrice.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="notions-et-diagnostics-lies"
|
||||
title="Notions et diagnostics liés"
|
||||
count={`${otherCount} entrée${otherCount > 1 ? "s" : ""}`}
|
||||
intro="Ces entrées prolongent l’analyse des dérives archicratiques vers des questions d’empêchement, d’invisibilisation, de fermeture ou de capture de la scène régulatrice."
|
||||
surface={true}
|
||||
className="dyna-block"
|
||||
>
|
||||
<div class="dyna-cards">
|
||||
{otherEntries.map((entry) => (
|
||||
<a class="dyna-card" href={hrefOf(entry)}>
|
||||
@@ -274,24 +269,18 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{paradigmEntries.length > 0 && (
|
||||
<div class="dyna-block dyna-block--panel">
|
||||
<div class="dyna-block__head">
|
||||
<h3 id="paradigmes-mobilises">Paradigmes mobilisés</h3>
|
||||
<span class="dyna-block__count">
|
||||
{paradigmCount} paradigme{paradigmCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="dyna-block__intro">
|
||||
Ces paradigmes servent de ressources comparatives pour penser les
|
||||
processus de rigidification, d’autonomisation et d’opacification
|
||||
des régimes de régulation.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="paradigmes-mobilises"
|
||||
title="Paradigmes mobilisés"
|
||||
count={`${paradigmCount} paradigme${paradigmCount > 1 ? "s" : ""}`}
|
||||
intro="Ces paradigmes servent de ressources comparatives pour penser les processus de rigidification, d’autonomisation et d’opacification des régimes de régulation."
|
||||
surface={true}
|
||||
className="dyna-block"
|
||||
>
|
||||
<div class="dyna-cards">
|
||||
{paradigmEntries.map((entry) => (
|
||||
<a class="dyna-card" href={hrefOf(entry)}>
|
||||
@@ -306,7 +295,7 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
@@ -419,52 +408,6 @@ const prolongerLinks = [
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.dyna-block--panel{
|
||||
padding: 18px 18px 16px;
|
||||
border: 1px solid rgba(127,127,127,0.18);
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
rgba(127,127,127,0.035);
|
||||
}
|
||||
|
||||
.dyna-block__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.dyna-block h3{
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 36px);
|
||||
}
|
||||
|
||||
.dyna-block__count{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
opacity: .78;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dyna-block__intro{
|
||||
max-width: 78ch;
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.dyna-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
|
||||
@@ -8,7 +8,6 @@ import { getCollection } from "astro:content";
|
||||
import { hrefOfGlossaryEntry } from "../../lib/glossary";
|
||||
|
||||
const entries = await getCollection("glossaire");
|
||||
const hrefOf = hrefOfGlossaryEntry;
|
||||
|
||||
const collator = new Intl.Collator("fr", { sensitivity: "base", numeric: true });
|
||||
|
||||
@@ -79,8 +78,7 @@ const prolongerLinks = [
|
||||
{
|
||||
href: "/glossaire/",
|
||||
title: "Accueil du glossaire",
|
||||
text:
|
||||
"Revenir à la cartographie générale du système archicratique.",
|
||||
text: "Revenir à la cartographie générale du système archicratique.",
|
||||
},
|
||||
{
|
||||
href: "/glossaire/concepts-fondamentaux/",
|
||||
@@ -109,13 +107,39 @@ const prolongerLinks = [
|
||||
stickyMode="glossary-portal"
|
||||
>
|
||||
<Fragment slot="aside">
|
||||
<GlossaryPortalAside
|
||||
ariaLabel="Navigation de l’index complet du glossaire"
|
||||
title="Index complet"
|
||||
meta={`${totalEntries} entrée${totalEntries > 1 ? "s" : ""} · ${totalLetters} lettre${totalLetters > 1 ? "s" : ""}`}
|
||||
pageItems={pageItems}
|
||||
usefulLinks={usefulLinks}
|
||||
/>
|
||||
<div class="gic-aside-stack">
|
||||
<GlossaryPortalAside
|
||||
ariaLabel="Navigation de l’index complet du glossaire"
|
||||
title="Index complet"
|
||||
meta={`${totalEntries} entrée${totalEntries > 1 ? "s" : ""} · ${totalLetters} lettre${totalLetters > 1 ? "s" : ""}`}
|
||||
pageItems={pageItems}
|
||||
usefulLinks={usefulLinks}
|
||||
/>
|
||||
|
||||
<div class="gic-aside__block">
|
||||
<h2 class="gic-aside__heading">Repères de lecture</h2>
|
||||
|
||||
<div class="gic-aside__pills" aria-label="Repères de l’index">
|
||||
<span class="gic-aside__pill">
|
||||
{paradigmesCount} paradigme{paradigmesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-aside__pill">
|
||||
{doctrinesCount} doctrine{doctrinesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-aside__pill">
|
||||
{verbesCount} verbe{verbesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-aside__pill">
|
||||
{casIaCount} entrée{casIaCount > 1 ? "s" : ""} cas IA
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="gic-aside__note">
|
||||
Cet index complète les portails thématiques : il permet de retrouver
|
||||
rapidement une fiche, puis de repartir vers les grandes cartographies du glossaire.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
||||
<section class="gic-page">
|
||||
@@ -138,21 +162,6 @@ const prolongerLinks = [
|
||||
count={`${totalEntries} entrée${totalEntries > 1 ? "s" : ""}`}
|
||||
intro="Naviguer par lettre permet de retrouver rapidement chaque fiche du glossaire, tout en conservant ses principaux marqueurs de lecture."
|
||||
>
|
||||
<div class="gic-stats" aria-label="Repères de l’index">
|
||||
<span class="gic-stat-pill">
|
||||
{paradigmesCount} paradigme{paradigmesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-stat-pill">
|
||||
{doctrinesCount} doctrine{doctrinesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-stat-pill">
|
||||
{verbesCount} verbe{verbesCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
<span class="gic-stat-pill">
|
||||
{casIaCount} entrée{casIaCount > 1 ? "s" : ""} cas IA
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<nav class="gic-letters" id="gic-letters-source" aria-label="Lettres de l’index">
|
||||
{groupedAlpha.map(([letter]) => (
|
||||
<a href={`#letter-${letter}`}>{letter}</a>
|
||||
@@ -174,10 +183,10 @@ const prolongerLinks = [
|
||||
|
||||
<div class="gic-groups">
|
||||
{groupedAlpha.map(([letter, items]) => (
|
||||
<section class="gic-group" id={`letter-${letter}`}>
|
||||
<div class="gic-group__head">
|
||||
<h3>{letter}</h3>
|
||||
<span class="gic-group__count">
|
||||
<section class="gic-section gic-group" id={`letter-${letter}`}>
|
||||
<div class="gic-section__head">
|
||||
<h2>{letter}</h2>
|
||||
<span class="gic-section__count">
|
||||
{items.length} entrée{items.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
@@ -185,7 +194,7 @@ const prolongerLinks = [
|
||||
<div class="gic-list">
|
||||
{items.map((entry) => (
|
||||
<article class="gic-item">
|
||||
<a class="gic-term" href={hrefOf(entry)}>
|
||||
<a class="gic-term" href={hrefOfGlossaryEntry(entry)}>
|
||||
{entry.data.term}
|
||||
</a>
|
||||
|
||||
@@ -207,6 +216,7 @@ const prolongerLinks = [
|
||||
id="prolonger-la-lecture"
|
||||
title="Prolonger la lecture"
|
||||
intro="Cet index intégral complète les portails thématiques sans s’y substituer. Il permet de repartir ensuite vers les grandes cartographies déjà stabilisées du glossaire."
|
||||
final={true}
|
||||
>
|
||||
<div class="gic-cards">
|
||||
{prolongerLinks.map((item) => (
|
||||
@@ -217,90 +227,270 @@ const prolongerLinks = [
|
||||
))}
|
||||
</div>
|
||||
</GlossaryPortalSection>
|
||||
|
||||
<GlossaryPortalSection
|
||||
id="portee-densemble"
|
||||
title="Portée d’ensemble"
|
||||
final={true}
|
||||
>
|
||||
<p>
|
||||
L’index complet ne remplace pas les parcours thématiques : il les complète.
|
||||
Il offre une entrée alphabétique stable dans le lexique archicratique, afin
|
||||
de retrouver rapidement une fiche, puis de repartir vers les grands portails
|
||||
conceptuels, topologiques, dynamiques ou théoriques du glossaire.
|
||||
</p>
|
||||
</GlossaryPortalSection>
|
||||
</section>
|
||||
|
||||
<GlossaryPortalStickySync
|
||||
heroMoreId="gic-hero-more"
|
||||
heroToggleId="gic-hero-toggle"
|
||||
sectionHeadSelector=".glossary-portal-section__head, .gic-group__head"
|
||||
/>
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const boot = () => {
|
||||
const body = document.body;
|
||||
const root = document.documentElement;
|
||||
const follow = document.getElementById("reading-follow");
|
||||
const lettersSource = document.getElementById("gic-letters-source");
|
||||
const lettersFollow = document.getElementById("gic-follow-letters");
|
||||
const groupSections = Array.from(document.querySelectorAll(".gic-group"));
|
||||
|
||||
if (!body) return;
|
||||
body.classList.add("is-index-complet-page");
|
||||
if (!body || !root || !follow || !lettersSource || !lettersFollow || groupSections.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!follow || !lettersSource || !lettersFollow) return;
|
||||
|
||||
const DOCKED_CLASS = "gic-letters-docked";
|
||||
const BODY_CLASS = "is-index-complet-page";
|
||||
const LETTERS_DOCKED_CLASS = "gic-letters-docked";
|
||||
const ACTIVE_CLASS = "is-active";
|
||||
const mqMobile = window.matchMedia("(max-width: 860px)");
|
||||
let raf = 0;
|
||||
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
||||
const EXTRA_GAP = 12;
|
||||
const MAX_CORRECTION_PASSES = 8;
|
||||
|
||||
const hideFollowLetters = () => {
|
||||
body.classList.remove(DOCKED_CLASS);
|
||||
lettersFollow.hidden = true;
|
||||
lettersFollow.setAttribute("aria-hidden", "true");
|
||||
lettersFollow.style.top = "";
|
||||
const sourceLinks = Array.from(lettersSource.querySelectorAll("a"));
|
||||
const followLinks = Array.from(lettersFollow.querySelectorAll("a"));
|
||||
const allLetterLinks = [...sourceLinks, ...followLinks];
|
||||
|
||||
body.classList.add(BODY_CLASS);
|
||||
|
||||
const computeFollowOn = () =>
|
||||
!mqMobile.matches &&
|
||||
follow.classList.contains("is-on") &&
|
||||
follow.style.display !== "none" &&
|
||||
follow.getAttribute("aria-hidden") !== "true";
|
||||
|
||||
const setAnchorOffset = (value) => {
|
||||
root.style.setProperty(
|
||||
"--gic-follow-letters-offset",
|
||||
`${Math.max(0, Math.round(value))}px`
|
||||
);
|
||||
};
|
||||
|
||||
const sync = () => {
|
||||
const syncFollowLettersTop = () => {
|
||||
const inner = follow.querySelector(".reading-follow__inner");
|
||||
const followIsOn =
|
||||
!mqMobile.matches &&
|
||||
follow.classList.contains("is-on") &&
|
||||
follow.style.display !== "none" &&
|
||||
follow.getAttribute("aria-hidden") !== "true";
|
||||
|
||||
if (!followIsOn) {
|
||||
hideFollowLetters();
|
||||
return;
|
||||
}
|
||||
|
||||
const inner = follow.querySelector(".reading-follow__inner");
|
||||
if (!inner) {
|
||||
hideFollowLetters();
|
||||
if (!followIsOn || !inner) {
|
||||
lettersFollow.style.top = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const followRect = follow.getBoundingClientRect();
|
||||
const innerRect = inner.getBoundingClientRect();
|
||||
const sourceRect = lettersSource.getBoundingClientRect();
|
||||
const top = followRect.top + innerRect.height;
|
||||
|
||||
lettersFollow.style.top = `${Math.round(followRect.top + innerRect.height)}px`;
|
||||
|
||||
const shouldDock = sourceRect.top <= innerRect.bottom + 6;
|
||||
|
||||
body.classList.toggle(DOCKED_CLASS, shouldDock);
|
||||
lettersFollow.hidden = !shouldDock;
|
||||
lettersFollow.setAttribute("aria-hidden", shouldDock ? "false" : "true");
|
||||
lettersFollow.style.top = `${Math.round(top)}px`;
|
||||
};
|
||||
|
||||
const syncLettersDockState = () => {
|
||||
if (mqMobile.matches || !computeFollowOn()) {
|
||||
body.classList.remove(LETTERS_DOCKED_CLASS);
|
||||
lettersFollow.hidden = true;
|
||||
lettersFollow.setAttribute("aria-hidden", "true");
|
||||
setAnchorOffset(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const inner = follow.querySelector(".reading-follow__inner");
|
||||
if (!inner) {
|
||||
body.classList.remove(LETTERS_DOCKED_CLASS);
|
||||
lettersFollow.hidden = true;
|
||||
lettersFollow.setAttribute("aria-hidden", "true");
|
||||
setAnchorOffset(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceRect = lettersSource.getBoundingClientRect();
|
||||
const innerRect = inner.getBoundingClientRect();
|
||||
const shouldDock = sourceRect.top <= (innerRect.bottom + 6);
|
||||
|
||||
body.classList.toggle(LETTERS_DOCKED_CLASS, shouldDock);
|
||||
lettersFollow.hidden = !shouldDock;
|
||||
lettersFollow.setAttribute("aria-hidden", shouldDock ? "false" : "true");
|
||||
|
||||
if (shouldDock) {
|
||||
const dockedHeight = lettersFollow.getBoundingClientRect().height || 0;
|
||||
setAnchorOffset(dockedHeight + EXTRA_GAP);
|
||||
} else {
|
||||
setAnchorOffset(0);
|
||||
}
|
||||
};
|
||||
|
||||
const getAnchorViewportTop = () => {
|
||||
const inner = follow.querySelector(".reading-follow__inner");
|
||||
const followOn = computeFollowOn();
|
||||
|
||||
if (!followOn || !inner) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
const followLettersVisible =
|
||||
!lettersFollow.hidden &&
|
||||
lettersFollow.getAttribute("aria-hidden") === "false";
|
||||
|
||||
if (followLettersVisible) {
|
||||
return Math.round(lettersFollow.getBoundingClientRect().bottom + EXTRA_GAP);
|
||||
}
|
||||
|
||||
return Math.round(inner.getBoundingClientRect().bottom + EXTRA_GAP);
|
||||
};
|
||||
|
||||
const getTargetHead = (section) =>
|
||||
section?.querySelector(".gic-section__head") || section;
|
||||
|
||||
const correctAnchorAlignment = (section, pass = 0) => {
|
||||
if (!section || pass >= MAX_CORRECTION_PASSES) return;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
syncFollowLettersTop();
|
||||
syncLettersDockState();
|
||||
|
||||
const head = getTargetHead(section);
|
||||
if (!head) return;
|
||||
|
||||
const wantedTop = getAnchorViewportTop();
|
||||
const headTop = head.getBoundingClientRect().top;
|
||||
const delta = headTop - wantedTop;
|
||||
|
||||
if (Math.abs(delta) <= 1) return;
|
||||
|
||||
window.scrollBy({
|
||||
top: delta,
|
||||
behavior: "auto",
|
||||
});
|
||||
|
||||
correctAnchorAlignment(section, pass + 1);
|
||||
});
|
||||
};
|
||||
|
||||
const scrollToLetterTarget = (targetId) => {
|
||||
const section = document.getElementById(targetId);
|
||||
if (!section) return;
|
||||
|
||||
const head = getTargetHead(section);
|
||||
if (!head) return;
|
||||
|
||||
syncFollowLettersTop();
|
||||
syncLettersDockState();
|
||||
|
||||
const targetTop = getAnchorViewportTop();
|
||||
const rect = head.getBoundingClientRect();
|
||||
const absoluteTop = window.scrollY + rect.top - targetTop;
|
||||
|
||||
if (window.location.hash !== `#${targetId}`) {
|
||||
history.pushState(null, "", `#${targetId}`);
|
||||
}
|
||||
|
||||
window.scrollTo({
|
||||
top: Math.max(0, Math.round(absoluteTop)),
|
||||
behavior: reducedMotion.matches ? "auto" : "smooth",
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
correctAnchorAlignment(section, 0);
|
||||
});
|
||||
});
|
||||
|
||||
window.setTimeout(() => correctAnchorAlignment(section, 0), 120);
|
||||
window.setTimeout(() => correctAnchorAlignment(section, 0), 260);
|
||||
};
|
||||
|
||||
const syncActiveLetter = () => {
|
||||
let activeId = null;
|
||||
|
||||
const inner = follow.querySelector(".reading-follow__inner");
|
||||
const followOn = computeFollowOn();
|
||||
const followBottom = followOn && inner
|
||||
? inner.getBoundingClientRect().bottom
|
||||
: 0;
|
||||
|
||||
const dockedHeight =
|
||||
!lettersFollow.hidden && lettersFollow.getAttribute("aria-hidden") === "false"
|
||||
? lettersFollow.getBoundingClientRect().height
|
||||
: 0;
|
||||
|
||||
const threshold = followBottom > 0
|
||||
? followBottom + dockedHeight + 12
|
||||
: 140;
|
||||
|
||||
for (const section of groupSections) {
|
||||
const rect = section.getBoundingClientRect();
|
||||
if (rect.top <= threshold) {
|
||||
activeId = section.id;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!activeId && groupSections[0]) {
|
||||
activeId = groupSections[0].id;
|
||||
}
|
||||
|
||||
const applyState = (links) => {
|
||||
links.forEach((link) => {
|
||||
const isActive = link.getAttribute("href") === `#${activeId}`;
|
||||
link.classList.toggle(ACTIVE_CLASS, isActive);
|
||||
|
||||
if (isActive) {
|
||||
link.setAttribute("aria-current", "true");
|
||||
} else {
|
||||
link.removeAttribute("aria-current");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
applyState(sourceLinks);
|
||||
applyState(followLinks);
|
||||
};
|
||||
|
||||
const handleLetterClick = (event) => {
|
||||
const link = event.currentTarget;
|
||||
const href = link?.getAttribute("href") || "";
|
||||
|
||||
if (!href.startsWith("#letter-")) return;
|
||||
|
||||
event.preventDefault();
|
||||
scrollToLetterTarget(href.slice(1));
|
||||
};
|
||||
|
||||
allLetterLinks.forEach((link) => {
|
||||
link.addEventListener("click", handleLetterClick);
|
||||
});
|
||||
|
||||
let raf = 0;
|
||||
const schedule = () => {
|
||||
if (raf) return;
|
||||
raf = requestAnimationFrame(() => {
|
||||
raf = 0;
|
||||
sync();
|
||||
syncFollowLettersTop();
|
||||
syncLettersDockState();
|
||||
syncActiveLetter();
|
||||
});
|
||||
};
|
||||
|
||||
const onScroll = () => {
|
||||
schedule();
|
||||
};
|
||||
|
||||
const onHashChange = () => {
|
||||
const id = window.location.hash.replace(/^#/, "");
|
||||
if (!id.startsWith("letter-")) return;
|
||||
scrollToLetterTarget(id);
|
||||
};
|
||||
|
||||
const followObserver = new MutationObserver(schedule);
|
||||
followObserver.observe(follow, {
|
||||
attributes: true,
|
||||
@@ -308,9 +498,10 @@ const prolongerLinks = [
|
||||
subtree: false,
|
||||
});
|
||||
|
||||
window.addEventListener("scroll", schedule, { passive: true });
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
window.addEventListener("resize", schedule);
|
||||
window.addEventListener("pageshow", schedule);
|
||||
window.addEventListener("hashchange", onHashChange);
|
||||
|
||||
if (document.fonts?.ready) {
|
||||
document.fonts.ready.then(schedule).catch(() => {});
|
||||
@@ -322,7 +513,22 @@ const prolongerLinks = [
|
||||
mqMobile.addListener(schedule);
|
||||
}
|
||||
|
||||
if (reducedMotion.addEventListener) {
|
||||
reducedMotion.addEventListener("change", schedule);
|
||||
} else if (reducedMotion.addListener) {
|
||||
reducedMotion.addListener(schedule);
|
||||
}
|
||||
|
||||
setAnchorOffset(0);
|
||||
schedule();
|
||||
|
||||
if (window.location.hash.startsWith("#letter-")) {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
scrollToLetterTarget(window.location.hash.slice(1));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
@@ -336,28 +542,53 @@ const prolongerLinks = [
|
||||
|
||||
<style>
|
||||
.gic-page{
|
||||
--gic-follow-letters-offset: 0px;
|
||||
padding: 8px 0 24px;
|
||||
}
|
||||
|
||||
.gic-stats{
|
||||
.gic-aside-stack{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 14px;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.gic-stat-pill{
|
||||
.gic-aside__block{
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 16px;
|
||||
padding: 12px;
|
||||
background: rgba(127,127,127,0.05);
|
||||
}
|
||||
|
||||
.gic-aside__heading{
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.gic-aside__pills{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.gic-aside__pill{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 30px;
|
||||
padding: 0 11px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
padding: 4px 9px;
|
||||
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.2;
|
||||
line-height: 1.3;
|
||||
opacity: .9;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gic-aside__note{
|
||||
margin: 10px 0 0;
|
||||
font-size: 12px;
|
||||
line-height: 1.45;
|
||||
opacity: .78;
|
||||
}
|
||||
|
||||
.gic-letters{
|
||||
@@ -378,7 +609,9 @@ const prolongerLinks = [
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease;
|
||||
border-color 120ms ease,
|
||||
box-shadow 120ms ease,
|
||||
color 120ms ease;
|
||||
}
|
||||
|
||||
.gic-letters a:hover,
|
||||
@@ -389,28 +622,37 @@ const prolongerLinks = [
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.gic-letters a.is-active,
|
||||
.gic-follow-letters a.is-active,
|
||||
.gic-letters a[aria-current="true"],
|
||||
.gic-follow-letters a[aria-current="true"]{
|
||||
border-color: rgba(0,217,255,0.34);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.14), rgba(0,217,255,0.06)),
|
||||
rgba(127,127,127,0.10);
|
||||
color: var(--glossary-accent, #00d9ff);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255,255,255,0.05),
|
||||
0 0 0 1px rgba(0,217,255,0.06);
|
||||
}
|
||||
|
||||
.gic-follow-letters{
|
||||
position: fixed;
|
||||
left: var(--reading-left);
|
||||
width: var(--reading-width);
|
||||
box-sizing: border-box;
|
||||
z-index: 59;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
padding: 8px 12px 10px;
|
||||
border: 1px solid rgba(127,127,127,.20);
|
||||
border-top: 0;
|
||||
border-radius: 0 0 14px 14px;
|
||||
|
||||
background: rgba(255,255,255,.86);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
|
||||
box-shadow: 0 10px 22px rgba(0,0,0,.06);
|
||||
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
pointer-events: none;
|
||||
@@ -423,7 +665,7 @@ const prolongerLinks = [
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
:global(body.is-index-complet-page.is-glossary-portal-page.glossary-portal-follow-on.gic-letters-docked #reading-follow .reading-follow__inner){
|
||||
:global(body.is-index-complet-page.gic-letters-docked #reading-follow .reading-follow__inner){
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
@@ -432,33 +674,38 @@ const prolongerLinks = [
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.gic-group{
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 28px);
|
||||
scroll-margin-top: calc(
|
||||
var(--sticky-offset-px, 96px) + 28px + var(--gic-follow-letters-offset, 0px)
|
||||
);
|
||||
}
|
||||
|
||||
.gic-group h3{
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 28px);
|
||||
.gic-section{
|
||||
margin-top: 34px;
|
||||
}
|
||||
|
||||
.gic-group__head{
|
||||
.gic-section__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 10px;
|
||||
scroll-margin-top: calc(
|
||||
var(--sticky-offset-px, 96px) + 28px + var(--gic-follow-letters-offset, 0px)
|
||||
);
|
||||
}
|
||||
|
||||
.gic-group__head h3{
|
||||
.gic-section__head h2{
|
||||
margin: 0;
|
||||
font-size: clamp(1.15rem, 1.8vw, 1.35rem);
|
||||
line-height: 1.2;
|
||||
scroll-margin-top: calc(
|
||||
var(--sticky-offset-px, 96px) + 28px + var(--gic-follow-letters-offset, 0px)
|
||||
);
|
||||
}
|
||||
|
||||
.gic-group__count{
|
||||
.gic-section__count{
|
||||
font-size: 13px;
|
||||
opacity: .72;
|
||||
white-space: nowrap;
|
||||
@@ -478,11 +725,11 @@ const prolongerLinks = [
|
||||
|
||||
.gic-term{
|
||||
display: inline-block;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 800;
|
||||
font-size: 1.04rem;
|
||||
line-height: 1.3;
|
||||
text-decoration: none;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.gic-def{
|
||||
@@ -522,10 +769,7 @@ const prolongerLinks = [
|
||||
border-radius: 16px;
|
||||
background: rgba(127,127,127,0.05);
|
||||
text-decoration: none;
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease;
|
||||
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
|
||||
}
|
||||
|
||||
.gic-card:hover{
|
||||
@@ -553,21 +797,31 @@ const prolongerLinks = [
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.gic-stat-pill,
|
||||
.gic-aside__block,
|
||||
.gic-aside__pill,
|
||||
.gic-item,
|
||||
.gic-card,
|
||||
.gic-follow-letters{
|
||||
.gic-card{
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.gic-follow-letters{
|
||||
background: rgba(0,0,0,.58);
|
||||
box-shadow: 0 10px 22px rgba(0,0,0,.18);
|
||||
}
|
||||
|
||||
.gic-letters a:hover,
|
||||
.gic-follow-letters a:hover,
|
||||
.gic-card:hover{
|
||||
background: rgba(255,255,255,0.07);
|
||||
}
|
||||
|
||||
.gic-follow-letters{
|
||||
box-shadow: 0 10px 22px rgba(0,0,0,.18);
|
||||
.gic-letters a.is-active,
|
||||
.gic-follow-letters a.is-active,
|
||||
.gic-letters a[aria-current="true"],
|
||||
.gic-follow-letters a[aria-current="true"]{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.18), rgba(0,217,255,0.08)),
|
||||
rgba(255,255,255,0.06);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -274,6 +274,7 @@ const approfondirPortalItems = [
|
||||
>
|
||||
<GlossaryPortalGrid items={approfondirPortalItems} secondary={true} />
|
||||
</GlossaryHomeSection>
|
||||
</section>
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
|
||||
@@ -4,6 +4,8 @@ import GlossaryPortalAside from "../../components/GlossaryPortalAside.astro";
|
||||
import GlossaryPortalHero from "../../components/GlossaryPortalHero.astro";
|
||||
import GlossaryPortalSection from "../../components/GlossaryPortalSection.astro";
|
||||
import GlossaryPortalStickySync from "../../components/GlossaryPortalStickySync.astro";
|
||||
import GlossaryPortalPanel from "../../components/GlossaryPortalPanel.astro";
|
||||
import GlossaryPortalCta from "../../components/GlossaryPortalCta.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import {
|
||||
buildGlossaryBySlug,
|
||||
@@ -133,15 +135,15 @@ const doctrineEntries = resolveOrderedEntries([
|
||||
|
||||
const tensionEntries = resolveOrderedEntries([
|
||||
"subsistance-vivante-et-captation-capitalistique",
|
||||
"regulation-technique-et-legitimation-democratique",
|
||||
"souverainetes-territoriales-et-interdependances-globales",
|
||||
"memoire-symbolique-et-instantaneite-computationnelle",
|
||||
"coexistence-ontologique-et-necessite-regulatrice",
|
||||
"travail-vivant-et-abstraction-de-la-valeur",
|
||||
"egalisation-normative-et-differenciation-singuliere",
|
||||
"liberte-daction-et-regimes-de-securite-algorithmique",
|
||||
"visibilite-mediatique-et-reconnaissance-symbolique",
|
||||
"egalisation-normative-et-differenciation-singuliere",
|
||||
"pluralite-natalite-action",
|
||||
"technodiversite-et-cosmotechnie",
|
||||
"regulation-technique-et-legitimation-democratique",
|
||||
"souverainetes-territoriales-et-interdependances-globales",
|
||||
"formes-de-vie-et-cadres-dhabitabilite",
|
||||
"memoire-symbolique-et-instantaneite-computationnelle",
|
||||
"coexistence-ontologique-et-necessite-regulatrice",
|
||||
]);
|
||||
|
||||
const casIaEntries = resolveOrderedEntries([
|
||||
@@ -366,20 +368,14 @@ const usefulLinks = [
|
||||
intro="Le paradigme ne se réduit pas à un noyau abstrait. Il déploie une architecture interne faite de scènes, de topologies, de dynamiques, de pathologies, de figures et d’opérateurs méthodologiques."
|
||||
>
|
||||
{sceneEntries.length > 0 && (
|
||||
<div class="pa-block">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="scenes-topologies-et-instituabilite">Scènes, topologies et instituabilité</h3>
|
||||
<span class="pa-block__count">
|
||||
{sceneEntries.length} entrée{sceneEntries.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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
|
||||
cette régulation peut comparaître ou se dérober.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="scenes-topologies-et-instituabilite"
|
||||
title="Scènes, topologies et instituabilité"
|
||||
count={`${sceneEntries.length} entrée${sceneEntries.length > 1 ? "s" : ""}`}
|
||||
intro="Le paradigme archicratique ne pense pas seulement ce qui régule, mais aussi les lieux, les formats et les conditions par lesquels cette régulation peut comparaître ou se dérober."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{sceneEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -394,24 +390,18 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{dynamicEntries.length > 0 && (
|
||||
<div class="pa-block">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="dynamiques-et-pathologies">Dynamiques et pathologies</h3>
|
||||
<span class="pa-block__count">
|
||||
{dynamicEntries.length} entrée{dynamicEntries.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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
|
||||
des formes, mais aussi leurs trajectoires.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="dynamiques-et-pathologies"
|
||||
title="Dynamiques et pathologies"
|
||||
count={`${dynamicEntries.length} entrée${dynamicEntries.length > 1 ? "s" : ""}`}
|
||||
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 des formes, mais aussi leurs trajectoires."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{dynamicEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -420,24 +410,18 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{methodEntries.length > 0 && (
|
||||
<div class="pa-block">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="figures-et-operateurs-methodologiques">Figures et opérateurs méthodologiques</h3>
|
||||
<span class="pa-block__count">
|
||||
{methodEntries.length} entrée{methodEntries.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="pa-block__intro">
|
||||
Le paradigme suppose enfin des figures, des qualifications et des
|
||||
instruments d’analyse capables de rendre la régulation lisible,
|
||||
diagnosable, cartographiable et politiquement adressable.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="figures-et-operateurs-methodologiques"
|
||||
title="Figures et opérateurs méthodologiques"
|
||||
count={`${methodEntries.length} entrée${methodEntries.length > 1 ? "s" : ""}`}
|
||||
intro="Le paradigme suppose enfin des figures, des qualifications et des instruments d’analyse capables de rendre la régulation lisible, diagnosable, cartographiable et politiquement adressable."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{methodEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -446,7 +430,7 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
@@ -455,6 +439,7 @@ const usefulLinks = [
|
||||
<GlossaryPortalSection
|
||||
id="constellation-theorique"
|
||||
title="Constellation théorique"
|
||||
count={`${constellationCount} entrée${constellationCount > 1 ? "s" : ""}`}
|
||||
intro="Le paradigme archicratique s’ouvre vers une constellation plus large : typologie des régimes de co-viabilité, traditions concurrentes ou complémentaires et doctrines fondatrices à partir desquelles ses déplacements deviennent plus nettement comparables."
|
||||
>
|
||||
<div class="pa-theory-hub">
|
||||
@@ -491,29 +476,23 @@ const usefulLinks = [
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a class="pa-theory-button" href="/glossaire/paradigmes/">
|
||||
<span>Ouvrir la cartographie théorique</span>
|
||||
<span aria-hidden="true">↗</span>
|
||||
</a>
|
||||
<GlossaryPortalCta
|
||||
href="/glossaire/paradigmes/"
|
||||
label="Ouvrir la cartographie théorique"
|
||||
className="pa-theory-hub__cta"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{typologyEntries.length > 0 && (
|
||||
<div class="pa-block pa-block--panel">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="typologie-des-regimes-de-co-viabilite">Typologie des régimes de co-viabilité</h3>
|
||||
<span class="pa-block__count">
|
||||
{typologyEntries.length} entrée{typologyEntries.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="pa-block__intro">
|
||||
Le paradigme ne vaut pas seulement comme noyau conceptuel. Il
|
||||
s’ouvre aussi sur une typologie des formes de régulation et sur
|
||||
les grandes matrices à partir desquelles les sociétés organisent
|
||||
leur tenue collective.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="typologie-des-regimes-de-co-viabilite"
|
||||
title="Typologie des régimes de co-viabilité"
|
||||
count={`${typologyEntries.length} entrée${typologyEntries.length > 1 ? "s" : ""}`}
|
||||
intro="Le paradigme ne vaut pas seulement comme noyau conceptuel. Il s’ouvre aussi sur une typologie des formes de régulation et sur les grandes matrices à partir desquelles les sociétés organisent leur tenue collective."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{typologyEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -522,25 +501,18 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{paradigmEntries.length > 0 && (
|
||||
<div class="pa-block pa-block--panel">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="paradigmes-mobilises">Paradigmes mobilisés</h3>
|
||||
<span class="pa-block__count">
|
||||
{featuredParadigmCount} repère{featuredParadigmCount > 1 ? "s" : ""} mis en avant
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="pa-block__intro">
|
||||
L’archicratie ne s’élabore pas dans un vide théorique. Elle
|
||||
dialogue avec plusieurs paradigmes qui éclairent ses voisinages,
|
||||
ses contrastes et ses points d’appui. Le portail central en
|
||||
retient ici quelques-uns, choisis pour leur portée comparative.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="paradigmes-mobilises"
|
||||
title="Paradigmes mobilisés"
|
||||
count={`${featuredParadigmCount} repère${featuredParadigmCount > 1 ? "s" : ""} mis en avant`}
|
||||
intro="L’archicratie ne s’élabore pas dans un vide théorique. Elle dialogue avec plusieurs paradigmes qui éclairent ses voisinages, ses contrastes et ses points d’appui. Le portail central en retient ici quelques-uns, choisis pour leur portée comparative."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{paradigmEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -555,25 +527,18 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{doctrineEntries.length > 0 && (
|
||||
<div class="pa-block pa-block--panel">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="doctrines-fondatrices">Doctrines fondatrices</h3>
|
||||
<span class="pa-block__count">
|
||||
{featuredDoctrineCount} repère{featuredDoctrineCount > 1 ? "s" : ""} mis en avant
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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
|
||||
reprend, les déplace et les resitue dans une écologie plus large
|
||||
de la régulation.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="doctrines-fondatrices"
|
||||
title="Doctrines fondatrices"
|
||||
count={`${featuredDoctrineCount} repère${featuredDoctrineCount > 1 ? "s" : ""} mis en avant`}
|
||||
intro="Certaines doctrines classiques continuent de servir de contrepoints ou de points de départ obligés. Le paradigme archicratique les reprend, les déplace et les resitue dans une écologie plus large de la régulation."
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{doctrineEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -588,7 +553,7 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
@@ -619,14 +584,13 @@ const usefulLinks = [
|
||||
intro="L’un des intérêts majeurs du paradigme archicratique est de permettre des traductions institutionnelles concrètes. Dans le cas des systèmes d’IA, il donne lieu à des dispositifs destinés à rouvrir les chaînes de décision, documenter les justifications et reconstruire de véritables scènes de comparution."
|
||||
>
|
||||
{casIaEntries.length > 0 && (
|
||||
<div class="pa-block pa-block--panel">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="traduction-contemporaine-cas-ia">Traduction contemporaine : Cas IA</h3>
|
||||
<span class="pa-block__count">
|
||||
{casIaEntries.length} dispositif{casIaEntries.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="traduction-contemporaine-cas-ia"
|
||||
title="Traduction contemporaine : Cas IA"
|
||||
count={`${casIaEntries.length} dispositif${casIaEntries.length > 1 ? "s" : ""}`}
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{casIaEntries.map((entry) => (
|
||||
<a class="pa-card" href={hrefOf(entry)}>
|
||||
@@ -635,18 +599,17 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{portalLinks.length > 0 && (
|
||||
<div class="pa-block pa-block--panel">
|
||||
<div class="pa-block__head">
|
||||
<h3 id="portails-voisins-deja-stabilises">Portails voisins déjà stabilisés</h3>
|
||||
<span class="pa-block__count">
|
||||
{portalLinks.length} portail{portalLinks.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="portails-voisins-deja-stabilises"
|
||||
title="Portails voisins déjà stabilisés"
|
||||
count={`${portalLinks.length} portail${portalLinks.length > 1 ? "s" : ""}`}
|
||||
surface={true}
|
||||
className="pa-block"
|
||||
>
|
||||
<div class="pa-cards">
|
||||
{portalLinks.map((item) => (
|
||||
<a class="pa-card" href={item.href}>
|
||||
@@ -655,7 +618,7 @@ const usefulLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
@@ -762,53 +725,6 @@ const usefulLinks = [
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.pa-block--panel{
|
||||
padding: 18px 18px 16px;
|
||||
border: 1px solid rgba(127,127,127,0.18);
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
rgba(127,127,127,0.035);
|
||||
}
|
||||
|
||||
.pa-block__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.pa-block h3{
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 36px);
|
||||
}
|
||||
|
||||
.pa-block__count{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
opacity: .78;
|
||||
white-space: nowrap;
|
||||
background: rgba(127,127,127,0.04);
|
||||
}
|
||||
|
||||
.pa-block__intro{
|
||||
max-width: 78ch;
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.pa-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
@@ -976,49 +892,8 @@ const usefulLinks = [
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.pa-theory-button{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 38px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid rgba(0,217,255,0.24);
|
||||
border-radius: 999px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.10), rgba(0,217,255,0.04)),
|
||||
rgba(127,127,127,0.06);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255,255,255,0.05),
|
||||
0 0 0 1px rgba(0,217,255,0.04);
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: .01em;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease,
|
||||
box-shadow 120ms ease;
|
||||
}
|
||||
|
||||
.pa-theory-button:hover{
|
||||
transform: translateY(-1px);
|
||||
border-color: rgba(0,217,255,0.34);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.14), rgba(0,217,255,0.06)),
|
||||
rgba(127,127,127,0.08);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255,255,255,0.06),
|
||||
0 0 0 1px rgba(0,217,255,0.08),
|
||||
0 10px 28px rgba(0,0,0,0.18);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.pa-theory-button:focus-visible{
|
||||
outline: 2px solid rgba(0,217,255,0.28);
|
||||
outline-offset: 4px;
|
||||
.pa-theory-hub__cta{
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 900px){
|
||||
@@ -1026,7 +901,7 @@ const usefulLinks = [
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.pa-theory-button{
|
||||
.pa-theory-hub__cta{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1045,12 +920,6 @@ const usefulLinks = [
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.pa-block--panel{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.015)),
|
||||
rgba(255,255,255,0.025);
|
||||
}
|
||||
|
||||
.pa-theory-hub{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.015)),
|
||||
@@ -1069,17 +938,5 @@ const usefulLinks = [
|
||||
.pa-chip--link:hover{
|
||||
background: rgba(0,217,255,0.08);
|
||||
}
|
||||
|
||||
.pa-theory-button{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.12), rgba(0,217,255,0.05)),
|
||||
rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.pa-theory-button:hover{
|
||||
background:
|
||||
linear-gradient(180deg, rgba(0,217,255,0.16), rgba(0,217,255,0.07)),
|
||||
rgba(255,255,255,0.06);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import GlossaryPortalAside from "../../components/GlossaryPortalAside.astro";
|
||||
import GlossaryPortalHero from "../../components/GlossaryPortalHero.astro";
|
||||
import GlossaryPortalSection from "../../components/GlossaryPortalSection.astro";
|
||||
import GlossaryPortalStickySync from "../../components/GlossaryPortalStickySync.astro";
|
||||
import GlossaryPortalPanel from "../../components/GlossaryPortalPanel.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import {
|
||||
buildGlossaryBySlug,
|
||||
@@ -224,20 +225,14 @@ const prolongerLinks = [
|
||||
intro="Cette notion dialogue avec plusieurs diagnostics et paradigmes qui permettent d’en préciser la portée politique, symbolique et régulatrice."
|
||||
>
|
||||
{otherEntries.length > 0 && (
|
||||
<div class="scene-block scene-block--panel">
|
||||
<div class="scene-block__head">
|
||||
<h3 id="notions-et-diagnostics-lies">Notions et diagnostics liés</h3>
|
||||
<span class="scene-block__count">
|
||||
{otherCount} entrée{otherCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="scene-block__intro">
|
||||
Ces entrées prolongent la scène d’épreuve vers des questions
|
||||
d’instituabilité, de fermeture, d’empêchement ou de visibilité
|
||||
de la régulation.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="notions-et-diagnostics-lies"
|
||||
title="Notions et diagnostics liés"
|
||||
count={`${otherCount} entrée${otherCount > 1 ? "s" : ""}`}
|
||||
intro="Ces entrées prolongent la scène d’épreuve vers des questions d’instituabilité, de fermeture, d’empêchement ou de visibilité de la régulation."
|
||||
surface={true}
|
||||
className="scene-block"
|
||||
>
|
||||
<div class="scene-cards">
|
||||
{otherEntries.map((entry) => (
|
||||
<a class="scene-card" href={hrefOf(entry)}>
|
||||
@@ -252,25 +247,18 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
|
||||
{paradigmEntries.length > 0 && (
|
||||
<div class="scene-block scene-block--panel">
|
||||
<div class="scene-block__head">
|
||||
<h3 id="paradigmes-mobilises">Paradigmes mobilisés</h3>
|
||||
<span class="scene-block__count">
|
||||
{paradigmCount} paradigme{paradigmCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="scene-block__intro">
|
||||
Ces paradigmes servent de points d’appui comparatifs pour mieux
|
||||
comprendre ce qui, dans la scène archicratique, relève de la
|
||||
conflictualité, de l’apparition publique ou de la mise en litige
|
||||
de la régulation.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="paradigmes-mobilises"
|
||||
title="Paradigmes mobilisés"
|
||||
count={`${paradigmCount} paradigme${paradigmCount > 1 ? "s" : ""}`}
|
||||
intro="Ces paradigmes servent de points d’appui comparatifs pour mieux comprendre ce qui, dans la scène archicratique, relève de la conflictualité, de l’apparition publique ou de la mise en litige de la régulation."
|
||||
surface={true}
|
||||
className="scene-block"
|
||||
>
|
||||
<div class="scene-cards">
|
||||
{paradigmEntries.map((entry) => (
|
||||
<a class="scene-card" href={hrefOf(entry)}>
|
||||
@@ -285,7 +273,7 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
)}
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
@@ -388,56 +376,6 @@ const prolongerLinks = [
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.scene-block--panel{
|
||||
padding: 18px 18px 16px;
|
||||
border: 1px solid rgba(127,127,127,0.18);
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
rgba(127,127,127,0.035);
|
||||
}
|
||||
|
||||
.scene-block + .scene-block{
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.scene-block__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.scene-block h3{
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 36px);
|
||||
}
|
||||
|
||||
.scene-block__count{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
opacity: .78;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scene-block__intro{
|
||||
max-width: 78ch;
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.scene-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
@@ -490,16 +428,8 @@ const prolongerLinks = [
|
||||
opacity: .82;
|
||||
}
|
||||
|
||||
@media (max-width: 720px){
|
||||
.scene-block--panel{
|
||||
padding: 16px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.scene-focus-card,
|
||||
.scene-block--panel,
|
||||
.scene-card{
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import GlossaryPortalAside from "../../components/GlossaryPortalAside.astro";
|
||||
import GlossaryPortalHero from "../../components/GlossaryPortalHero.astro";
|
||||
import GlossaryPortalSection from "../../components/GlossaryPortalSection.astro";
|
||||
import GlossaryPortalStickySync from "../../components/GlossaryPortalStickySync.astro";
|
||||
import GlossaryPortalPanel from "../../components/GlossaryPortalPanel.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import {
|
||||
buildGlossaryBySlug,
|
||||
@@ -122,8 +123,6 @@ const irreducibleTensions = [
|
||||
}));
|
||||
|
||||
const tensionsCount = irreducibleTensions.length;
|
||||
const foundationCount = foundationEntries.length;
|
||||
const resonanceCount = resonanceEntries.length;
|
||||
|
||||
const pageItems = [
|
||||
{ href: "#orientation", label: "Orientation" },
|
||||
@@ -247,23 +246,16 @@ const prolongerLinks = [
|
||||
<GlossaryPortalSection
|
||||
id="articulations-fondamentales"
|
||||
title="Articulations fondamentales"
|
||||
count={`${foundationCount} notion${foundationCount > 1 ? "s" : ""}`}
|
||||
count={`${foundationEntries.length} notion${foundationEntries.length > 1 ? "s" : ""}`}
|
||||
intro="Ces tensions ne prennent sens, dans le glossaire, qu’en relation avec quelques notions cardinales : la tension elle-même, la scène d’épreuve, l’archicration, la co-viabilité et l’archicratie."
|
||||
>
|
||||
<div class="tir-block tir-block--panel">
|
||||
<div class="tir-block__head">
|
||||
<h3 id="noyau-structural">Noyau structural de la régulation</h3>
|
||||
<span class="tir-block__count">
|
||||
{foundationCount} entrée{foundationCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="tir-block__intro">
|
||||
Ces notions donnent la grammaire minimale à partir de laquelle les
|
||||
tensions irréductibles peuvent être exposées, disputées et rendues
|
||||
politiquement traitables.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="notions-cardinales"
|
||||
title="Notions cardinales"
|
||||
count={`${foundationEntries.length} repère${foundationEntries.length > 1 ? "s" : ""}`}
|
||||
surface={true}
|
||||
className="tir-block"
|
||||
>
|
||||
<div class="tir-link-cards">
|
||||
{foundationEntries.map((entry) => (
|
||||
<a class="tir-link-card" href={hrefOf(entry)}>
|
||||
@@ -278,7 +270,7 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
|
||||
@@ -286,23 +278,16 @@ const prolongerLinks = [
|
||||
<GlossaryPortalSection
|
||||
id="resonances-theoriques"
|
||||
title="Résonances théoriques"
|
||||
count={`${resonanceCount} entrée${resonanceCount > 1 ? "s" : ""}`}
|
||||
count={`${resonanceEntries.length} entrée${resonanceEntries.length > 1 ? "s" : ""}`}
|
||||
intro="Plusieurs paradigmes déjà présents dans le glossaire permettent d’éclairer certains versants de ces tensions : gouvernementalité algorithmique, préemption, cosmopolitique, technodiversité, pharmacologie technique ou légitimation démocratique."
|
||||
>
|
||||
<div class="tir-block tir-block--panel">
|
||||
<div class="tir-block__head">
|
||||
<h3 id="points-dappui-comparatifs">Points d’appui comparatifs</h3>
|
||||
<span class="tir-block__count">
|
||||
{resonanceCount} entrée{resonanceCount > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="tir-block__intro">
|
||||
Ces entrées ne remplacent pas la cartographie des tensions
|
||||
irréductibles. Elles en éclairent certains versants en fournissant
|
||||
des ressources d’analyse déjà stabilisées ailleurs dans le glossaire.
|
||||
</p>
|
||||
|
||||
<GlossaryPortalPanel
|
||||
id="paradigmes-et-resonances"
|
||||
title="Paradigmes et résonances"
|
||||
count={`${resonanceEntries.length} entrée${resonanceEntries.length > 1 ? "s" : ""}`}
|
||||
surface={true}
|
||||
className="tir-block"
|
||||
>
|
||||
<div class="tir-link-cards">
|
||||
{resonanceEntries.map((entry) => (
|
||||
<a class="tir-link-card" href={hrefOf(entry)}>
|
||||
@@ -317,7 +302,7 @@ const prolongerLinks = [
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlossaryPortalPanel>
|
||||
</GlossaryPortalSection>
|
||||
)}
|
||||
|
||||
@@ -385,6 +370,10 @@ const prolongerLinks = [
|
||||
opacity: .92;
|
||||
}
|
||||
|
||||
.tir-block{
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.tir-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
@@ -405,10 +394,7 @@ const prolongerLinks = [
|
||||
|
||||
.tir-card--link{
|
||||
text-decoration: none;
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease;
|
||||
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
|
||||
}
|
||||
|
||||
.tir-card--link:hover{
|
||||
@@ -438,56 +424,6 @@ const prolongerLinks = [
|
||||
opacity: .92;
|
||||
}
|
||||
|
||||
.tir-block{
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.tir-block--panel{
|
||||
padding: 18px 18px 16px;
|
||||
border: 1px solid rgba(127,127,127,0.18);
|
||||
border-radius: 18px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
|
||||
rgba(127,127,127,0.035);
|
||||
}
|
||||
|
||||
.tir-block__head{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tir-block h3{
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 36px);
|
||||
}
|
||||
|
||||
.tir-block__count{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
opacity: .78;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tir-block__intro{
|
||||
max-width: 78ch;
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.tir-link-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
@@ -504,10 +440,7 @@ const prolongerLinks = [
|
||||
border-radius: 16px;
|
||||
background: rgba(127,127,127,0.05);
|
||||
text-decoration: none;
|
||||
transition:
|
||||
transform 120ms ease,
|
||||
background 120ms ease,
|
||||
border-color 120ms ease;
|
||||
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
|
||||
}
|
||||
|
||||
.tir-link-card:hover{
|
||||
@@ -534,17 +467,9 @@ const prolongerLinks = [
|
||||
opacity: .72;
|
||||
}
|
||||
|
||||
@media (max-width: 720px){
|
||||
.tir-block--panel{
|
||||
padding: 16px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.tir-note-card,
|
||||
.tir-card,
|
||||
.tir-block--panel,
|
||||
.tir-link-card{
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
@@ -214,29 +214,29 @@ const usefulLinks = [
|
||||
];
|
||||
|
||||
const prolongerLinks = [
|
||||
{
|
||||
href: "/glossaire/scene-depreuve/",
|
||||
title: "Scène d’épreuve",
|
||||
text:
|
||||
"Revenir à la notion-pivot de comparution, d’exposition et de mise en discussion régulatrice.",
|
||||
},
|
||||
{
|
||||
href: "/glossaire/scenes-archicratiques/",
|
||||
title: "Scènes archicratiques",
|
||||
text:
|
||||
"Retrouver le portail synthétique des scènes, topologies et formats de comparution.",
|
||||
"Revenir aux formes de comparution, d’épreuve, d’empêchement et de réouverture de la régulation.",
|
||||
},
|
||||
{
|
||||
href: "/glossaire/dynamiques-archicratiques/",
|
||||
title: "Dynamiques archicratiques",
|
||||
text:
|
||||
"Explorer les processus de fermeture, de capture, d’oblitération et de dérive des scènes.",
|
||||
"Explorer les processus de fermeture, d’oblitération ou de dérive auxquels les verbes de la scène donnent une texture plus fine.",
|
||||
},
|
||||
{
|
||||
href: "/glossaire/paradigme-archicratique/",
|
||||
title: "Paradigme archicratique",
|
||||
text:
|
||||
"Replacer ce mini-glossaire opératoire dans l’architecture générale du système archicratique.",
|
||||
},
|
||||
{
|
||||
href: "/glossaire/index-complet/",
|
||||
title: "Index complet",
|
||||
text:
|
||||
"Retrouver l’ensemble des entrées du glossaire dans une navigation alphabétique intégrale.",
|
||||
"Retrouver toutes les entrées du glossaire dans une navigation alphabétique intégrale.",
|
||||
},
|
||||
];
|
||||
---
|
||||
@@ -295,11 +295,12 @@ const prolongerLinks = [
|
||||
<GlossaryPortalSection
|
||||
id="prolonger-la-lecture"
|
||||
title="Prolonger la lecture"
|
||||
intro="Cette page forme un mini-glossaire d’action. Elle permet de mieux qualifier ce qui arrive concrètement aux scènes archicratiques et prolonge la lecture vers les pages de concepts, de topologies et de dynamiques."
|
||||
intro="Ce mini-glossaire opératoire complète les portails conceptuels du site. Il permet de décrire plus finement les opérations concrètes qui affectent une scène de régulation."
|
||||
>
|
||||
<div class="verbs-cards">
|
||||
{prolongerLinks.map((item) => (
|
||||
<a class="verbs-card verbs-card--link" href={item.href}>
|
||||
<div class="verbs-card__index">↗</div>
|
||||
<h3>{item.title}</h3>
|
||||
<p class="verbs-card__definition">{item.text}</p>
|
||||
</a>
|
||||
@@ -349,10 +350,7 @@ const prolongerLinks = [
|
||||
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;
|
||||
transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
|
||||
}
|
||||
|
||||
.verbs-card--link{
|
||||
@@ -360,8 +358,7 @@ const prolongerLinks = [
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.verbs-card:hover,
|
||||
.verbs-card--link:hover{
|
||||
.verbs-card:hover{
|
||||
transform: translateY(-1px);
|
||||
background: rgba(127,127,127,0.08);
|
||||
border-color: rgba(0,217,255,0.16);
|
||||
@@ -394,8 +391,7 @@ const prolongerLinks = [
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.verbs-card:hover,
|
||||
.verbs-card--link:hover{
|
||||
.verbs-card:hover{
|
||||
background: rgba(255,255,255,0.07);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user