Synchronise les contenus glossaire et ajoute les scripts de conversion DOCX/MDX
All checks were successful
SMOKE / smoke (push) Successful in 4s
CI / build-and-anchors (push) Successful in 37s
CI / build-and-anchors (pull_request) Successful in 34s

This commit is contained in:
2026-04-23 12:04:31 +02:00
parent fa46971e76
commit 5b427d5602
34 changed files with 6781 additions and 1084 deletions

241
scripts/convert_docx_to_mdx.py Executable file
View File

@@ -0,0 +1,241 @@
#!/usr/bin/env python3
import argparse
import os
import re
import shutil
import subprocess
import sys
from pathlib import Path
try:
import yaml
except ImportError:
print("Erreur : PyYAML n'est pas installé. Lance : pip3 install pyyaml")
sys.exit(1)
EDITION = "archicrat-ia"
STATUS = "essai_these"
VERSION = "0.1.0"
ORDER_MAP = {
"prologue": 10,
"chapitre-1": 20,
"chapitre-2": 30,
"chapitre-3": 40,
"chapitre-4": 50,
"chapitre-5": 60,
"conclusion": 70,
}
TITLE_MAP = {
"prologue": "Prologue — Fondation, finalité sociopolitique et historique",
"chapitre-1": "Chapitre 1 — Fondements épistémologiques et modélisation",
"chapitre-2": "Chapitre 2 — Archéogenèse des régimes de co-viabilité",
"chapitre-3": "Chapitre 3 — Philosophies du pouvoir et archicration",
"chapitre-4": "Chapitre 4 — Histoire archicratique des révolutions industrielles",
"chapitre-5": "Chapitre 5 — Tensions, co-viabilités et régulations",
"conclusion": "Conclusion — ArchiCraT-IA",
}
def slugify_name(path: Path) -> str:
stem = path.stem.lower().strip()
replacements = {
" ": "-",
"_": "-",
"": "-",
"": "-",
"é": "e",
"è": "e",
"ê": "e",
"ë": "e",
"à": "a",
"â": "a",
"ä": "a",
"î": "i",
"ï": "i",
"ô": "o",
"ö": "o",
"ù": "u",
"û": "u",
"ü": "u",
"ç": "c",
"'": "",
"": "",
}
for old, new in replacements.items():
stem = stem.replace(old, new)
stem = re.sub(r"-+", "-", stem).strip("-")
# normalisations spécifiques
stem = stem.replace("chapitre-1-fondements-epistemologiques-et-modelisation-archicratie-version-officielle-revise", "chapitre-1")
stem = stem.replace("chapitre-2", "chapitre-2")
stem = stem.replace("chapitre-3", "chapitre-3")
stem = stem.replace("chapitre-4", "chapitre-4")
stem = stem.replace("chapitre-5", "chapitre-5")
if "prologue" in stem:
return "prologue"
if "chapitre-1" in stem:
return "chapitre-1"
if "chapitre-2" in stem:
return "chapitre-2"
if "chapitre-3" in stem:
return "chapitre-3"
if "chapitre-4" in stem:
return "chapitre-4"
if "chapitre-5" in stem:
return "chapitre-5"
if "conclusion" in stem:
return "conclusion"
return stem
def extract_title_from_markdown(md_text: str) -> str | None:
for line in md_text.splitlines():
line = line.strip()
if not line:
continue
if line.startswith("# "):
return line[2:].strip()
return None
def remove_first_h1(md_text: str) -> str:
lines = md_text.splitlines()
out = []
removed = False
for line in lines:
if not removed and line.strip().startswith("# "):
removed = True
continue
out.append(line)
text = "\n".join(out).lstrip()
return text
def clean_markdown(md_text: str) -> str:
text = md_text.replace("\r\n", "\n").replace("\r", "\n")
# nettoyer espaces multiples
text = re.sub(r"\n{3,}", "\n\n", text)
# supprimer éventuels signets/artefacts de liens internes Pandoc
text = re.sub(r"\[\]\(#.*?\)", "", text)
# convertir astérismes parasites
text = re.sub(r"[ \t]+$", "", text, flags=re.MULTILINE)
return text.strip() + "\n"
def compute_level(slug: str) -> int:
if slug == "prologue":
return 1
if slug.startswith("chapitre-"):
return 1
if slug == "conclusion":
return 1
return 1
def convert_one_file(input_docx: Path, output_dir: Path, source_root: Path):
slug = slugify_name(input_docx)
output_mdx = output_dir / f"{slug}.mdx"
cmd = [
"pandoc",
str(input_docx),
"-f",
"docx",
"-t",
"gfm+smart",
]
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
md_text = result.stdout
detected_title = extract_title_from_markdown(md_text)
md_body = remove_first_h1(md_text)
md_body = clean_markdown(md_body)
title = TITLE_MAP.get(slug) or detected_title or input_docx.stem
order = ORDER_MAP.get(slug, 999)
level = compute_level(slug)
relative_source = input_docx
try:
relative_source = input_docx.relative_to(source_root)
except ValueError:
relative_source = input_docx.name
frontmatter = {
"title": title,
"edition": EDITION,
"status": STATUS,
"level": level,
"version": VERSION,
"concepts": [],
"links": [],
"order": order,
"summary": "",
"source": {
"kind": "docx",
"path": str(relative_source),
},
}
yaml_block = yaml.safe_dump(
frontmatter,
allow_unicode=True,
sort_keys=False,
default_flow_style=False,
).strip()
final_text = f"---\n{yaml_block}\n---\n{md_body if md_body.startswith(chr(10)) else chr(10) + md_body}"
output_mdx.write_text(final_text, encoding="utf-8")
print(f"{input_docx.name} -> {output_mdx.name}")
def main():
parser = argparse.ArgumentParser(description="Convertit un dossier DOCX en MDX avec frontmatter.")
parser.add_argument("input_dir", help="Dossier source contenant les DOCX")
parser.add_argument("output_dir", help="Dossier de sortie pour les MDX")
args = parser.parse_args()
input_dir = Path(args.input_dir).expanduser().resolve()
output_dir = Path(args.output_dir).expanduser().resolve()
if not shutil.which("pandoc"):
print("Erreur : pandoc n'est pas installé. Lance : brew install pandoc")
sys.exit(1)
if not input_dir.exists() or not input_dir.is_dir():
print(f"Erreur : dossier source introuvable : {input_dir}")
sys.exit(1)
output_dir.mkdir(parents=True, exist_ok=True)
docx_files = sorted(input_dir.glob("*.docx"))
if not docx_files:
print(f"Aucun DOCX trouvé dans : {input_dir}")
sys.exit(1)
for docx_file in docx_files:
convert_one_file(docx_file, output_dir, input_dir)
print()
print("Conversion DOCX -> MDX terminée.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,304 @@
#!/usr/bin/env python3
import argparse
import re
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
import zipfile
try:
import yaml
except ImportError:
print("Erreur : PyYAML n'est pas installé. Lance : pip3 install pyyaml")
sys.exit(1)
try:
from docx import Document
except ImportError:
print("Erreur : python-docx n'est pas installé. Lance : pip3 install python-docx")
sys.exit(1)
def split_frontmatter(text: str):
if not text.startswith("---\n"):
return {}, text
match = re.match(r"^---\n(.*?)\n---\n(.*)$", text, flags=re.DOTALL)
if not match:
return {}, text
yaml_block = match.group(1)
body = match.group(2)
try:
metadata = yaml.safe_load(yaml_block) or {}
except Exception as e:
print(f"Avertissement : frontmatter YAML illisible : {e}")
metadata = {}
return metadata, body
def strip_mdx_artifacts(text: str):
# imports / exports MDX
text = re.sub(r"^\s*(import|export)\s+.+?$", "", text, flags=re.MULTILINE)
# composants autofermants : <Component />
text = re.sub(r"<[A-Z][A-Za-z0-9._-]*\b[^>]*\/>", "", text)
# composants bloc : <Component ...>...</Component>
text = re.sub(
r"<([A-Z][A-Za-z0-9._-]*)\b[^>]*>.*?</\1>",
"",
text,
flags=re.DOTALL,
)
# accolades seules résiduelles sur ligne
text = re.sub(r"^\s*{\s*}\s*$", "", text, flags=re.MULTILINE)
# lignes vides multiples
text = re.sub(r"\n{3,}", "\n\n", text)
return text.strip() + "\n"
def inject_h1_from_title(metadata: dict, body: str):
title = metadata.get("title", "")
if not title:
return body
if re.match(r"^\s*#\s+", body):
return body
return f"# {title}\n\n{body.lstrip()}"
def find_style_by_candidates(doc, candidates):
# Cherche d'abord par nom visible
for style in doc.styles:
for candidate in candidates:
if style.name == candidate:
return style
# Puis par style_id Word interne
for style in doc.styles:
style_id = getattr(style, "style_id", "")
if style_id in {"BodyText", "Heading1", "Heading2", "Heading3", "Heading4"}:
for candidate in candidates:
if candidate in {"Body Text", "Corps de texte"} and style_id == "BodyText":
return style
if candidate in {"Heading 1", "Titre 1"} and style_id == "Heading1":
return style
if candidate in {"Heading 2", "Titre 2"} and style_id == "Heading2":
return style
if candidate in {"Heading 3", "Titre 3"} and style_id == "Heading3":
return style
if candidate in {"Heading 4", "Titre 4"} and style_id == "Heading4":
return style
return None
def strip_leading_paragraph_numbers(text: str):
"""
Supprime les numéros de paragraphe du type :
2. Texte...
11. Texte...
101. Texte...
sans toucher aux titres Markdown (#, ##, ###).
"""
fixed_lines = []
for line in text.splitlines():
stripped = line.lstrip()
# Ne jamais toucher aux titres Markdown
if stripped.startswith("#"):
fixed_lines.append(line)
continue
# Supprime un numéro de paragraphe en début de ligne
line = re.sub(r"^\s*\d+\.\s+", "", line)
fixed_lines.append(line)
return "\n".join(fixed_lines) + "\n"
def normalize_non_heading_paragraphs(docx_path: Path):
"""
Force tous les paragraphes non-titres en Body Text / Corps de texte.
On laisse intacts les Heading 1-4.
"""
doc = Document(str(docx_path))
body_style = find_style_by_candidates(doc, ["Body Text", "Corps de texte"])
if body_style is None:
print(f"Avertissement : style 'Body Text / Corps de texte' introuvable dans {docx_path.name}")
return
heading_names = {
"Heading 1", "Heading 2", "Heading 3", "Heading 4",
"Titre 1", "Titre 2", "Titre 3", "Titre 4",
}
heading_ids = {"Heading1", "Heading2", "Heading3", "Heading4"}
changed = 0
for para in doc.paragraphs:
text = para.text.strip()
if not text:
continue
current_style = para.style
current_name = current_style.name if current_style else ""
current_id = getattr(current_style, "style_id", "") if current_style else ""
if current_name in heading_names or current_id in heading_ids:
continue
# Tout le reste passe en Body Text
para.style = body_style
changed += 1
doc.save(str(docx_path))
print(f" ↳ normalisation styles : {changed} paragraphe(s) mis en 'Body Text / Corps de texte'")
def remove_word_bookmarks(docx_path: Path):
"""
Supprime les bookmarks Word (signets) du DOCX.
Ce sont eux qui apparaissent comme crochets gris dans LibreOffice/Word
quand l'affichage des signets est activé.
"""
with tempfile.TemporaryDirectory() as tmpdir:
tmpdir = Path(tmpdir)
# Dézipper le docx
with zipfile.ZipFile(docx_path, "r") as zin:
zin.extractall(tmpdir)
xml_targets = [
tmpdir / "word" / "document.xml",
tmpdir / "word" / "footnotes.xml",
tmpdir / "word" / "endnotes.xml",
tmpdir / "word" / "comments.xml",
]
removed = 0
for xml_file in xml_targets:
if not xml_file.exists():
continue
text = xml_file.read_text(encoding="utf-8")
# enlever <w:bookmarkStart .../> et <w:bookmarkEnd .../>
text, c1 = re.subn(r"<w:bookmarkStart\b[^>]*/>", "", text)
text, c2 = re.subn(r"<w:bookmarkEnd\b[^>]*/>", "", text)
removed += c1 + c2
xml_file.write_text(text, encoding="utf-8")
# Rezipper
tmp_output = docx_path.with_suffix(".cleaned.docx")
with zipfile.ZipFile(tmp_output, "w", zipfile.ZIP_DEFLATED) as zout:
for file in tmpdir.rglob("*"):
if file.is_file():
zout.write(file, file.relative_to(tmpdir))
tmp_output.replace(docx_path)
print(f" ↳ suppression signets : {removed} balise(s) supprimée(s)")
def convert_one_file(input_path: Path, output_path: Path, reference_doc: Path | None):
raw = input_path.read_text(encoding="utf-8")
metadata, body = split_frontmatter(raw)
body = strip_mdx_artifacts(body)
body = strip_leading_paragraph_numbers(body)
body = inject_h1_from_title(metadata, body)
with tempfile.NamedTemporaryFile("w", suffix=".md", delete=False, encoding="utf-8") as tmp:
tmp.write(body)
tmp_md = Path(tmp.name)
cmd = [
"pandoc",
str(tmp_md),
"-f",
"markdown",
"-o",
str(output_path),
]
if reference_doc:
cmd.extend(["--reference-doc", str(reference_doc)])
try:
subprocess.run(cmd, check=True)
finally:
try:
tmp_md.unlink()
except FileNotFoundError:
pass
normalize_non_heading_paragraphs(output_path)
remove_word_bookmarks(output_path)
def main():
parser = argparse.ArgumentParser(
description="Convertit des fichiers MDX en DOCX en conservant H1/H2/H3/H4 et en forçant le corps en Body Text."
)
parser.add_argument("input_dir", help="Dossier contenant les .mdx")
parser.add_argument(
"--output-dir",
default=str(Path.home() / "Desktop" / "archicrat-ia-docx"),
help="Dossier de sortie DOCX"
)
parser.add_argument(
"--reference-doc",
default=None,
help="DOCX modèle Word à utiliser comme reference-doc"
)
args = parser.parse_args()
input_dir = Path(args.input_dir)
output_dir = Path(args.output_dir)
reference_doc = Path(args.reference_doc) if args.reference_doc else None
if not shutil.which("pandoc"):
print("Erreur : pandoc n'est pas installé. Installe-le avec : brew install pandoc")
sys.exit(1)
if not input_dir.exists() or not input_dir.is_dir():
print(f"Erreur : dossier introuvable : {input_dir}")
sys.exit(1)
if reference_doc and not reference_doc.exists():
print(f"Erreur : reference-doc introuvable : {reference_doc}")
sys.exit(1)
output_dir.mkdir(parents=True, exist_ok=True)
mdx_files = sorted(input_dir.glob("*.mdx"))
if not mdx_files:
print(f"Aucun fichier .mdx trouvé dans : {input_dir}")
sys.exit(1)
print(f"Conversion de {len(mdx_files)} fichier(s)...")
print(f"Entrée : {input_dir}")
print(f"Sortie : {output_dir}")
if reference_doc:
print(f"Modèle : {reference_doc}")
print()
for mdx_file in mdx_files:
docx_name = mdx_file.with_suffix(".docx").name
out_file = output_dir / docx_name
print(f"{mdx_file.name} -> {docx_name}")
convert_one_file(mdx_file, out_file, reference_doc)
print()
print("✅ Conversion terminée.")
if __name__ == "__main__":
main()

View File

@@ -22,43 +22,58 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
const bt = String(b.data.title ?? b.data.term ?? slugOf(b));
return collator.compare(at, bt);
});
const tocId = `toc-global-${collection}-${String(basePath).replace(/[^\w-]+/g, "-")}`;
---
<nav class="toc-global" aria-label={label}>
<div class="toc-global__head">
<div class="toc-global__title">{label}</div>
</div>
<nav
class="toc-global"
aria-label={label}
data-toc-global
data-toc-key={`global:${collection}:${basePath}`}
>
<button
class="toc-global__head toc-global__toggle"
type="button"
aria-expanded="true"
aria-controls={tocId}
>
<span class="toc-global__title">{label}</span>
<span class="toc-global__chevron" aria-hidden="true">▾</span>
</button>
<ol class="toc-global__list">
{entries.map((e) => {
const slug = slugOf(e);
const active = slug === currentSlug;
<div class="toc-global__body-clip" id={tocId}>
<div class="toc-global__body">
<ol class="toc-global__list">
{entries.map((e) => {
const slug = slugOf(e);
const active = slug === currentSlug;
return (
<li class={`toc-item ${active ? "is-active" : ""}`}>
<a class="toc-link" href={hrefOf(e)} aria-current={active ? "page" : undefined}>
<span class="toc-link__row">
{active ? (
<span class="toc-active-indicator" aria-hidden="true">👉</span>
) : (
<span class="toc-active-spacer" aria-hidden="true"></span>
)}
return (
<li class={`toc-item ${active ? "is-active" : ""}`}>
<a class="toc-link" href={hrefOf(e)} aria-current={active ? "page" : undefined}>
<span class="toc-link__row">
<span class={`toc-active-mark ${active ? "is-on" : ""}`} aria-hidden="true">
<span class="toc-active-mark__dot"></span>
</span>
<span class="toc-link__title">{e.data.title}</span>
<span class="toc-link__title">{e.data.title}</span>
{active && (
<span class="toc-badge" aria-label="Chapitre en cours">
En cours
{active && (
<span class="toc-badge" aria-label="Chapitre en cours">
En cours
</span>
)}
</span>
)}
</span>
{active && <span class="toc-underline" aria-hidden="true"></span>}
</a>
</li>
);
})}
</ol>
{active && <span class="toc-underline" aria-hidden="true"></span>}
</a>
</li>
);
})}
</ol>
</div>
</div>
</nav>
<style>
@@ -69,7 +84,22 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
background: rgba(127,127,127,0.06);
}
.toc-global__toggle{
width: 100%;
appearance: none;
border: 0;
background: transparent;
color: inherit;
text-align: left;
padding: 0;
cursor: pointer;
}
.toc-global__head{
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px dashed rgba(127,127,127,0.25);
@@ -82,11 +112,36 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
opacity: .88;
}
.toc-global__chevron{
font-size: 12px;
opacity: .7;
transition: transform 180ms ease;
}
.toc-global__body-clip{
display: grid;
grid-template-rows: 1fr;
transition:
grid-template-rows 220ms ease,
opacity 160ms ease,
margin-top 220ms ease;
}
.toc-global__body{
min-height: 0;
overflow: hidden;
}
.toc-global__list{
list-style: none;
margin: 0;
padding: 0;
max-height: 44vh;
overflow: auto;
padding-right: 8px;
scrollbar-gutter: stable;
}
.toc-global__list li::marker{ content: ""; }
.toc-item{ margin: 6px 0; }
@@ -112,13 +167,33 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
align-items: center;
}
.toc-active-indicator{
font-size: 14px;
line-height: 1;
.toc-active-mark{
width: 14px;
height: 14px;
display: inline-grid;
place-items: center;
border-radius: 999px;
border: 1px solid transparent;
opacity: .55;
}
.toc-active-spacer{
width: 14px;
.toc-active-mark__dot{
width: 5px;
height: 5px;
border-radius: 999px;
background: currentColor;
opacity: .65;
}
.toc-active-mark.is-on{
border-color: rgba(127,127,127,0.34);
opacity: 1;
}
.toc-active-mark.is-on .toc-active-mark__dot{
width: 6px;
height: 6px;
opacity: 1;
}
.toc-link__title{
@@ -156,11 +231,66 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
border-radius: 999px;
}
.toc-global__list{
max-height: 44vh;
overflow: auto;
padding-right: 8px;
scrollbar-gutter: stable;
@media (max-width: 980px){
.toc-global{
padding: 10px 12px;
border-radius: 14px;
}
.toc-global__head{
margin-bottom: 0;
padding-bottom: 0;
border-bottom: 0;
min-height: 28px;
}
.toc-global__title{
font-size: 13px;
}
.toc-global__body-clip{
margin-top: 10px;
}
.toc-global.is-collapsed .toc-global__body-clip{
grid-template-rows: 0fr;
opacity: 0;
margin-top: 0;
}
.toc-global__body{
min-height: 0;
overflow: hidden;
transition: opacity 180ms ease;
}
.toc-global.is-collapsed .toc-global__body{
opacity: 0;
}
.toc-global.is-collapsed .toc-global__chevron{
transform: rotate(-90deg);
}
.toc-link{
padding: 7px 9px;
border-radius: 12px;
}
.toc-link__title{
font-size: 12.5px;
line-height: 1.22;
}
.toc-badge{
font-size: 10px;
padding: 2px 7px;
}
.toc-global__list{
max-height: min(42vh, 360px);
padding-right: 4px;
}
}
@media (prefers-color-scheme: dark){
@@ -168,12 +298,88 @@ const entries = [...await getCollection(collection)].sort((a, b) => {
.toc-link:hover{ background: rgba(255,255,255,0.06); }
.toc-item.is-active .toc-link{ background: rgba(255,255,255,0.06); }
.toc-badge{ background: rgba(255,255,255,0.06); }
.toc-active-mark.is-on{ border-color: rgba(255,255,255,0.22); }
}
</style>
<script is:inline>
(() => {
const active = document.querySelector(".toc-global .toc-item.is-active");
if (active) active.scrollIntoView({ block: "nearest" });
function init() {
document.querySelectorAll("[data-toc-global]").forEach((nav) => {
if (nav.dataset.tocReady === "1") return;
nav.dataset.tocReady = "1";
const toggle = nav.querySelector(".toc-global__toggle");
const bodyClip = nav.querySelector(".toc-global__body-clip");
const active = nav.querySelector(".toc-item.is-active");
const mq = window.matchMedia("(max-width: 980px)");
const key = `archicratie:${nav.dataset.tocKey || "toc-global"}`;
if (!toggle || !bodyClip) return;
const read = () => {
try {
const v = localStorage.getItem(key);
if (v === "open") return true;
if (v === "closed") return false;
} catch {}
return null;
};
const write = (open) => {
try { localStorage.setItem(key, open ? "open" : "closed"); } catch {}
};
const setOpen = (open, { persist = true } = {}) => {
const isMobile = mq.matches;
nav.classList.toggle("is-collapsed", isMobile && !open);
toggle.setAttribute("aria-expanded", open ? "true" : "false");
if (persist && isMobile) write(open);
};
const initState = () => {
if (!mq.matches) {
setOpen(true, { persist: false });
if (active) active.scrollIntoView({ block: "nearest" });
return;
}
const stored = read();
const open = stored == null ? false : stored;
setOpen(open, { persist: false });
if (open && active) active.scrollIntoView({ block: "nearest" });
};
toggle.addEventListener("click", () => {
const open = toggle.getAttribute("aria-expanded") !== "true";
setOpen(open);
if (open && active) active.scrollIntoView({ block: "nearest" });
if (open) {
window.dispatchEvent(new CustomEvent("archicratie:tocGlobalOpen"));
}
});
window.addEventListener("archicratie:tocLocalOpen", () => {
if (!mq.matches) return;
setOpen(false);
});
if (mq.addEventListener) {
mq.addEventListener("change", initState);
} else if (mq.addListener) {
mq.addListener(initState);
}
initState();
});
}
if (document.readyState === "loading") {
window.addEventListener("DOMContentLoaded", init, { once: true });
} else {
init();
}
})();
</script>

View File

@@ -49,85 +49,114 @@ const portalLinks = getGlossaryPortalLinks();
</div>
</div>
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">Portails</h2>
<ul class="glossary-aside__list">
{portalLinks.map((item) => (
<li><a href={item.href}>{item.label}</a></li>
))}
</ul>
</section>
<details class="glossary-aside__block glossary-aside__disclosure" open>
<summary class="glossary-aside__summary">
<span class="glossary-aside__heading">Portails</span>
<span class="glossary-aside__chevron" aria-hidden="true">▾</span>
</summary>
<div class="glossary-aside__panel">
<ul class="glossary-aside__list">
{portalLinks.map((item) => (
<li><a href={item.href}>{item.label}</a></li>
))}
</ul>
</div>
</details>
{showNoyau && (
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">Noyau archicratique</h2>
<ul class="glossary-aside__list">
{fondamentaux.map((entry) => {
const active = slugOfGlossaryEntry(entry) === currentSlug;
return (
<li>
<a
href={hrefOfGlossaryEntry(entry)}
aria-current={active ? "page" : undefined}
class={active ? "is-active" : undefined}
>
{entry.data.term}
</a>
</li>
);
})}
</ul>
</section>
<details class="glossary-aside__block glossary-aside__disclosure" open>
<summary class="glossary-aside__summary">
<span class="glossary-aside__heading">Noyau archicratique</span>
<span class="glossary-aside__chevron" aria-hidden="true">▾</span>
</summary>
<div class="glossary-aside__panel">
<ul class="glossary-aside__list">
{fondamentaux.map((entry) => {
const active = slugOfGlossaryEntry(entry) === currentSlug;
return (
<li>
<a
href={hrefOfGlossaryEntry(entry)}
aria-current={active ? "page" : undefined}
class={active ? "is-active" : undefined}
>
{entry.data.term}
</a>
</li>
);
})}
</ul>
</div>
</details>
)}
{showSameFamily && (
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">{sameFamilyTitle}</h2>
<ul class="glossary-aside__list">
{sameFamilyEntries.map((entry) => {
const active = slugOfGlossaryEntry(entry) === currentSlug;
return (
<li>
<a
href={hrefOfGlossaryEntry(entry)}
aria-current={active ? "page" : undefined}
class={active ? "is-active" : undefined}
>
{entry.data.term}
</a>
</li>
);
})}
</ul>
</section>
<details class="glossary-aside__block glossary-aside__disclosure" open>
<summary class="glossary-aside__summary">
<span class="glossary-aside__heading">{sameFamilyTitle}</span>
<span class="glossary-aside__chevron" aria-hidden="true">▾</span>
</summary>
<div class="glossary-aside__panel">
<ul class="glossary-aside__list">
{sameFamilyEntries.map((entry) => {
const active = slugOfGlossaryEntry(entry) === currentSlug;
return (
<li>
<a
href={hrefOfGlossaryEntry(entry)}
aria-current={active ? "page" : undefined}
class={active ? "is-active" : undefined}
>
{entry.data.term}
</a>
</li>
);
})}
</ul>
</div>
</details>
)}
{relationSections.length > 0 && (
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">Autour de cette fiche</h2>
<details class="glossary-aside__block glossary-aside__disclosure" open>
<summary class="glossary-aside__summary">
<span class="glossary-aside__heading">Autour de cette fiche</span>
<span class="glossary-aside__chevron" aria-hidden="true">▾</span>
</summary>
{relationSections.map((section) => (
<>
<h3 class="glossary-aside__subheading">{section.title}</h3>
<ul class="glossary-aside__list">
{section.items.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
))}
</ul>
</>
))}
</section>
<div class="glossary-aside__panel">
{relationSections.map((section) => (
<>
<h3 class="glossary-aside__subheading">{section.title}</h3>
<ul class="glossary-aside__list">
{section.items.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
))}
</ul>
</>
))}
</div>
</details>
)}
{contextualTheory.length > 0 && (
<section class="glossary-aside__block">
<h2 class="glossary-aside__heading">Paysage théorique</h2>
<ul class="glossary-aside__list">
{contextualTheory.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
))}
</ul>
</section>
<details class="glossary-aside__block glossary-aside__disclosure" open>
<summary class="glossary-aside__summary">
<span class="glossary-aside__heading">Paysage théorique</span>
<span class="glossary-aside__chevron" aria-hidden="true">▾</span>
</summary>
<div class="glossary-aside__panel">
<ul class="glossary-aside__list">
{contextualTheory.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
))}
</ul>
</div>
</details>
)}
</nav>
@@ -136,6 +165,7 @@ const portalLinks = getGlossaryPortalLinks();
display: flex;
flex-direction: column;
gap: 14px;
min-width: 0;
}
.glossary-aside__block{
@@ -143,6 +173,7 @@ const portalLinks = getGlossaryPortalLinks();
border-radius: 16px;
padding: 14px;
background: rgba(127,127,127,0.05);
min-width: 0;
}
.glossary-aside__block--intro{
@@ -160,10 +191,10 @@ const portalLinks = getGlossaryPortalLinks();
}
.glossary-aside__title{
font-size: 16px;
font-weight: 800;
letter-spacing: .2px;
line-height: 1.3;
font-size: 18px;
font-weight: 850;
letter-spacing: .1px;
line-height: 1.22;
}
.glossary-aside__pills{
@@ -183,6 +214,7 @@ const portalLinks = getGlossaryPortalLinks();
font-size: 13px;
line-height: 1.35;
opacity: .92;
min-width: 0;
}
.glossary-aside__pill--family{
@@ -190,12 +222,54 @@ const portalLinks = getGlossaryPortalLinks();
font-weight: 800;
}
.glossary-aside__disclosure{
padding: 0;
overflow: hidden;
}
.glossary-aside__summary{
list-style: none;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 14px;
cursor: pointer;
user-select: none;
}
.glossary-aside__summary::-webkit-details-marker{
display: none;
}
.glossary-aside__summary:hover{
background: rgba(127,127,127,0.035);
}
.glossary-aside__heading{
margin: 0 0 11px;
margin: 0;
font-size: 16px;
font-weight: 850;
line-height: 1.28;
opacity: .97;
}
.glossary-aside__chevron{
flex: 0 0 auto;
font-size: 14px;
font-weight: 800;
line-height: 1.35;
opacity: .94;
line-height: 1;
opacity: .72;
transform: rotate(0deg);
transition: transform 160ms ease, opacity 160ms ease;
}
.glossary-aside__disclosure[open] .glossary-aside__chevron{
transform: rotate(180deg);
opacity: .96;
}
.glossary-aside__panel{
padding: 0 14px 14px;
}
.glossary-aside__subheading{
@@ -222,16 +296,210 @@ const portalLinks = getGlossaryPortalLinks();
text-decoration: none;
font-size: 14px;
line-height: 1.4;
word-break: break-word;
}
.glossary-aside__list a.is-active{
font-weight: 800;
}
@media (max-width: 860px){
.glossary-aside{
gap: 10px;
}
.glossary-aside__block{
border-radius: 14px;
}
.glossary-aside__block--intro{
padding: 12px;
}
.glossary-aside__back{
margin-bottom: 8px;
font-size: 13px;
line-height: 1.28;
}
.glossary-aside__title{
font-size: 19px;
line-height: 1.18;
}
.glossary-aside__pills{
gap: 6px;
margin-top: 8px;
}
.glossary-aside__pill{
padding: 4px 9px;
font-size: 12px;
line-height: 1.26;
}
.glossary-aside__summary{
padding: 12px;
}
.glossary-aside__heading{
font-size: 17px;
line-height: 1.2;
}
.glossary-aside__panel{
padding: 0 12px 12px;
}
.glossary-aside__subheading{
margin: 10px 0 6px;
font-size: 11.5px;
line-height: 1.26;
}
.glossary-aside__list li{
margin: 5px 0;
}
.glossary-aside__list a{
font-size: 14px;
line-height: 1.34;
}
.glossary-aside__disclosure:not([open]) .glossary-aside__panel{
display: none;
}
}
@media (max-width: 860px){
.glossary-aside__disclosure{
background: rgba(127,127,127,0.045);
}
.glossary-aside__disclosure[open] .glossary-aside__summary{
border-bottom: 1px solid rgba(127,127,127,0.12);
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-aside{
gap: 8px;
}
.glossary-aside__block{
border-radius: 12px;
}
.glossary-aside__block--intro{
padding: 10px 11px;
}
.glossary-aside__back{
margin-bottom: 6px;
font-size: 12px;
line-height: 1.2;
}
.glossary-aside__title{
font-size: 16px;
line-height: 1.14;
}
.glossary-aside__pills{
gap: 5px;
margin-top: 7px;
}
.glossary-aside__pill{
padding: 3px 8px;
font-size: 11px;
line-height: 1.2;
}
.glossary-aside__summary{
padding: 10px 11px;
}
.glossary-aside__heading{
font-size: 15px;
line-height: 1.16;
}
.glossary-aside__panel{
padding: 0 11px 10px;
}
.glossary-aside__subheading{
margin: 8px 0 5px;
font-size: 11px;
line-height: 1.18;
}
.glossary-aside__list li{
margin: 4px 0;
}
.glossary-aside__list a{
font-size: 13px;
line-height: 1.28;
}
}
@media (min-width: 861px){
.glossary-aside__summary{
cursor: default;
}
.glossary-aside__chevron{
display: none;
}
}
@media (prefers-color-scheme: dark){
.glossary-aside__block,
.glossary-aside__pill{
background: rgba(255,255,255,0.04);
}
.glossary-aside__summary:hover{
background: rgba(255,255,255,0.03);
}
}
</style>
</style>
<script is:inline>
(() => {
const syncMobileDisclosure = () => {
const mobile = window.matchMedia("(max-width: 860px)").matches;
const smallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
).matches;
const compact = mobile || smallLandscape;
document
.querySelectorAll(".glossary-aside__disclosure")
.forEach((el, index) => {
if (!(el instanceof HTMLDetailsElement)) return;
if (compact) {
if (!el.dataset.mobileInit) {
el.open = index === 0;
el.dataset.mobileInit = "true";
}
} else {
el.open = true;
}
});
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", syncMobileDisclosure, { once: true });
} else {
syncMobileDisclosure();
}
window.addEventListener("resize", syncMobileDisclosure);
window.addEventListener("pageshow", syncMobileDisclosure);
})();
</script>

View File

@@ -32,16 +32,16 @@ const {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.glossary-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
gap: 7px;
padding: 13px 14px;
border: 1px solid var(--glossary-border);
border-radius: 18px;
border-radius: 16px;
background: var(--glossary-bg-soft);
text-decoration: none;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
@@ -60,17 +60,44 @@ const {
.glossary-card strong{
color: var(--glossary-accent);
font-size: 1.04rem;
line-height: 1.28;
font-size: 1.02rem;
line-height: 1.24;
}
.glossary-card span{
color: inherit;
font-size: 1rem;
line-height: 1.5;
font-size: .98rem;
line-height: 1.46;
opacity: .94;
}
@media (max-width: 760px){
.glossary-cards{
grid-template-columns: 1fr;
gap: 10px;
margin-top: 10px;
}
.glossary-card{
gap: 6px;
padding: 12px 12px;
border-radius: 14px;
}
.glossary-card strong{
font-size: .98rem;
}
.glossary-card span{
font-size: .94rem;
line-height: 1.42;
}
.glossary-card--wide{
grid-column: auto;
}
}
@media (prefers-color-scheme: dark){
.glossary-card{
background: rgba(255,255,255,0.04);

View File

@@ -75,9 +75,9 @@ const hasScholarlyMeta =
position: sticky;
top: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px));
z-index: 11;
margin: 0 0 24px;
margin: 0 0 22px;
border: 1px solid rgba(127,127,127,0.18);
border-radius: 28px;
border-radius: 24px;
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%);
@@ -97,7 +97,7 @@ const hasScholarlyMeta =
calc(var(--entry-hero-pad-top, 18px) - 2px);
transition: padding 180ms ease;
}
.glossary-entry-head h1{
margin: 0;
font-size: var(--entry-hero-h1-size, clamp(2.2rem, 4vw, 3.15rem));
@@ -129,12 +129,17 @@ const hasScholarlyMeta =
max-width 180ms ease,
font-size 180ms ease,
line-height 180ms ease;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
}
.glossary-entry-signals{
display: flex;
flex-wrap: wrap;
gap: 8px;
gap: 7px;
margin: 0;
transition: gap 180ms ease;
}
@@ -142,13 +147,13 @@ const hasScholarlyMeta =
.glossary-pill{
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 10px;
gap: 5px;
padding: 5px 9px;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 999px;
background: rgba(127,127,127,0.05);
font-size: 13px;
line-height: 1.35;
font-size: 12.5px;
line-height: 1.28;
transition:
padding 180ms ease,
font-size 180ms ease,
@@ -179,42 +184,67 @@ const hasScholarlyMeta =
.glossary-entry-meta p{
margin: 0;
font-size: 14px;
line-height: 1.5;
font-size: 13.5px;
line-height: 1.45;
}
.glossary-entry-meta p + p{
margin-top: 6px;
}
@media (max-width: 720px){
@media (max-width: 860px){
.glossary-entry-head{
position: static;
border-radius: 18px;
margin-bottom: 16px;
}
.glossary-entry-head__title{
padding: 12px 12px 10px;
}
.glossary-entry-summary{
gap: 9px;
padding: 10px 12px 12px;
}
.glossary-entry-dek{
max-width: none;
-webkit-line-clamp: 3;
}
.glossary-entry-signals{
gap: 6px;
}
.glossary-pill{
font-size: 12px;
padding: 4px 8px;
}
}
@media (max-width: 860px){
@media (max-width: 520px){
.glossary-entry-head{
position: static;
border-radius: 22px;
margin-bottom: 20px;
border-radius: 16px;
margin-bottom: 14px;
}
.glossary-entry-head__title{
padding: 14px 14px 12px;
padding: 10px 10px 9px;
}
.glossary-entry-summary{
gap: 12px;
padding: 14px;
gap: 8px;
padding: 9px 10px 10px;
}
.glossary-entry-dek{
max-width: none;
-webkit-line-clamp: 2;
}
.glossary-pill{
font-size: 11.5px;
padding: 3px 7px;
}
}

View File

@@ -6,6 +6,9 @@
const hero = document.querySelector("[data-ge-hero]");
const follow = document.getElementById("reading-follow");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
if (!body || !root || !hero || !follow) return;
@@ -18,11 +21,26 @@
body.classList.add(BODY_CLASS);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const neutralizeGlobalFollowIfCompact = () => {
if (!isCompactViewport()) {
follow.style.display = "";
return;
}
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
root.style.setProperty("--followbar-h", "0px");
};
const computeFollowOn = () =>
!mqMobile.matches &&
!isCompactViewport() &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
@@ -39,7 +57,7 @@
};
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
const h = isCompactViewport() ? 0 : heroHeight();
if (h === lastHeight) return;
lastHeight = h;
@@ -58,6 +76,7 @@
};
const syncAll = () => {
neutralizeGlobalFollowIfCompact();
stripLocalSticky();
syncFollowState();
applyLocalStickyHeight();
@@ -98,6 +117,12 @@
mqMobile.addListener(schedule);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", schedule);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(schedule);
}
schedule();
};
@@ -114,37 +139,47 @@
z-index: 10;
}
: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-head){
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
box-shadow: 0 8px 20px rgba(0,0,0,0.10);
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-head h1){
letter-spacing: -.03em;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-summary){
gap: 10px;
padding-top: 12px;
padding-bottom: 10px;
gap: 8px;
padding-top: 10px;
padding-bottom: 8px;
border-top-color: rgba(127,127,127,0.10);
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-dek){
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
-webkit-line-clamp: 1;
overflow: hidden;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-signals){
gap: 5px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-pill){
padding: 4px 8px;
font-size: 12px;
gap: 4px;
padding: 3px 7px;
font-size: 11px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-meta){
padding: 0;
border-color: transparent;
max-height: 0;
opacity: 0;
overflow: hidden;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on #reading-follow){
@@ -177,9 +212,78 @@
}
@media (max-width: 860px){
:global(body.is-glossary-entry-page #reading-follow),
:global(body.is-glossary-entry-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
pointer-events: none !important;
visibility: hidden !important;
}
:global(body.is-glossary-entry-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-head){
margin-bottom: 20px;
border-radius: 22px;
margin-bottom: 18px;
border-radius: 20px;
box-shadow: none;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-summary){
gap: 6px;
padding-top: 8px;
padding-bottom: 8px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-dek){
display: none;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-signals){
gap: 5px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-pill){
padding: 3px 6px;
font-size: 10.5px;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-entry-page #reading-follow),
:global(body.is-glossary-entry-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
pointer-events: none !important;
visibility: hidden !important;
}
:global(body.is-glossary-entry-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-head){
margin-bottom: 14px;
border-radius: 16px;
box-shadow: none;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-summary){
gap: 5px;
padding-top: 6px;
padding-bottom: 6px;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-entry-dek){
display: none;
}
:global(body.is-glossary-entry-page.glossary-entry-follow-on .glossary-pill){
padding: 2px 6px;
font-size: 10px;
}
}
</style>

View File

@@ -37,24 +37,36 @@ const {
</div>
</div>
<section class="glossary-home-aside__block">
<h2 class="glossary-home-aside__heading">Parcours du glossaire</h2>
<ul class="glossary-home-aside__list">
{portalLinks.map((item) => (
<li><a href={item.href}>{item.label}</a></li>
))}
</ul>
</section>
<details class="glossary-home-aside__block glossary-home-aside__disclosure" open>
<summary class="glossary-home-aside__summary">
<span class="glossary-home-aside__heading">Parcours du glossaire</span>
<span class="glossary-home-aside__chevron" aria-hidden="true">▾</span>
</summary>
{fondamentaux.length > 0 && (
<section class="glossary-home-aside__block">
<h2 class="glossary-home-aside__heading">Noyau archicratique</h2>
<div class="glossary-home-aside__panel">
<ul class="glossary-home-aside__list">
{fondamentaux.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
{portalLinks.map((item) => (
<li><a href={item.href}>{item.label}</a></li>
))}
</ul>
</section>
</div>
</details>
{fondamentaux.length > 0 && (
<details class="glossary-home-aside__block glossary-home-aside__disclosure" open>
<summary class="glossary-home-aside__summary">
<span class="glossary-home-aside__heading">Noyau archicratique</span>
<span class="glossary-home-aside__chevron" aria-hidden="true">▾</span>
</summary>
<div class="glossary-home-aside__panel">
<ul class="glossary-home-aside__list">
{fondamentaux.map((entry) => (
<li><a href={hrefOfGlossaryEntry(entry)}>{entry.data.term}</a></li>
))}
</ul>
</div>
</details>
)}
</nav>
@@ -63,6 +75,7 @@ const {
display: flex;
flex-direction: column;
gap: 14px;
min-width: 0;
}
.glossary-home-aside__block{
@@ -70,6 +83,7 @@ const {
border-radius: 16px;
padding: 14px;
background: rgba(127,127,127,0.05);
min-width: 0;
}
.glossary-home-aside__block--intro{
@@ -78,10 +92,10 @@ const {
}
.glossary-home-aside__title{
font-size: 16px;
font-weight: 800;
letter-spacing: .2px;
line-height: 1.3;
font-size: 18px;
font-weight: 850;
letter-spacing: .1px;
line-height: 1.22;
}
.glossary-home-aside__meta{
@@ -108,14 +122,57 @@ const {
font-size: 13px;
line-height: 1.35;
opacity: .92;
min-width: 0;
}
.glossary-home-aside__disclosure{
padding: 0;
overflow: hidden;
}
.glossary-home-aside__summary{
list-style: none;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 14px;
cursor: pointer;
user-select: none;
}
.glossary-home-aside__summary::-webkit-details-marker{
display: none;
}
.glossary-home-aside__summary:hover{
background: rgba(127,127,127,0.035);
}
.glossary-home-aside__heading{
margin: 0 0 11px;
margin: 0;
font-size: 16px;
font-weight: 850;
line-height: 1.28;
opacity: .97;
}
.glossary-home-aside__chevron{
flex: 0 0 auto;
font-size: 14px;
font-weight: 800;
line-height: 1.35;
opacity: .94;
line-height: 1;
opacity: .72;
transform: rotate(0deg);
transition: transform 160ms ease, opacity 160ms ease;
}
.glossary-home-aside__disclosure[open] .glossary-home-aside__chevron{
transform: rotate(180deg);
opacity: .96;
}
.glossary-home-aside__panel{
padding: 0 14px 14px;
}
.glossary-home-aside__list{
@@ -131,7 +188,148 @@ const {
.glossary-home-aside__list a{
text-decoration: none;
font-size: 14px;
line-height: 1.4;
line-height: 1.42;
word-break: break-word;
}
@media (max-width: 860px){
.glossary-home-aside{
gap: 10px;
}
.glossary-home-aside__block{
border-radius: 14px;
}
.glossary-home-aside__block--intro{
padding: 12px;
}
.glossary-home-aside__title{
font-size: 19px;
line-height: 1.18;
}
.glossary-home-aside__meta{
margin-top: 6px;
font-size: 12px;
line-height: 1.32;
}
.glossary-home-aside__pills{
gap: 6px;
margin-top: 9px;
}
.glossary-home-aside__pill{
padding: 4px 9px;
font-size: 12px;
line-height: 1.28;
}
.glossary-home-aside__summary{
padding: 12px;
}
.glossary-home-aside__heading{
font-size: 17px;
line-height: 1.2;
}
.glossary-home-aside__panel{
padding: 0 12px 12px;
}
.glossary-home-aside__list li{
margin: 5px 0;
}
.glossary-home-aside__list a{
font-size: 14px;
line-height: 1.34;
}
.glossary-home-aside__disclosure:not([open]) .glossary-home-aside__panel{
display: none;
}
}
@media (max-width: 860px){
.glossary-home-aside__disclosure{
background: rgba(127,127,127,0.045);
}
.glossary-home-aside__disclosure[open] .glossary-home-aside__summary{
border-bottom: 1px solid rgba(127,127,127,0.12);
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-home-aside{
gap: 8px;
}
.glossary-home-aside__block{
border-radius: 12px;
}
.glossary-home-aside__block--intro{
padding: 10px 11px;
}
.glossary-home-aside__title{
font-size: 16px;
line-height: 1.14;
}
.glossary-home-aside__meta{
font-size: 11px;
line-height: 1.26;
margin-top: 5px;
}
.glossary-home-aside__pills{
gap: 5px;
margin-top: 8px;
}
.glossary-home-aside__pill{
padding: 3px 8px;
font-size: 11px;
line-height: 1.2;
}
.glossary-home-aside__summary{
padding: 10px 11px;
}
.glossary-home-aside__heading{
font-size: 15px;
line-height: 1.16;
}
.glossary-home-aside__panel{
padding: 0 11px 10px;
}
.glossary-home-aside__list li{
margin: 4px 0;
}
.glossary-home-aside__list a{
font-size: 13px;
line-height: 1.28;
}
}
@media (min-width: 861px){
.glossary-home-aside__summary{
cursor: default;
}
.glossary-home-aside__chevron{
display: none;
}
}
@media (prefers-color-scheme: dark){
@@ -139,5 +337,46 @@ const {
.glossary-home-aside__pill{
background: rgba(255,255,255,0.04);
}
.glossary-home-aside__summary:hover{
background: rgba(255,255,255,0.03);
}
}
</style>
</style>
<script is:inline>
(() => {
const syncMobileDisclosure = () => {
const mobile = window.matchMedia("(max-width: 860px)").matches;
const smallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
).matches;
const compact = mobile || smallLandscape;
document
.querySelectorAll(".glossary-home-aside__disclosure")
.forEach((el, index) => {
if (!(el instanceof HTMLDetailsElement)) return;
if (compact) {
if (!el.dataset.mobileInit) {
el.open = index === 0;
el.dataset.mobileInit = "true";
}
} else {
el.open = true;
}
});
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", syncMobileDisclosure, { once: true });
} else {
syncMobileDisclosure();
}
window.addEventListener("resize", syncMobileDisclosure);
window.addEventListener("pageshow", syncMobileDisclosure);
})();
</script>

View File

@@ -15,7 +15,28 @@ const {
<header class="glossary-hero" id="glossary-hero">
<p class="glossary-kicker">{kicker}</p>
<h1>{title}</h1>
<p class="glossary-intro">{intro}</p>
<div class="glossary-hero__collapsible">
<p
class="glossary-intro"
id="glossary-hero-intro"
aria-hidden="false"
>
{intro}
</p>
<button
class="glossary-hero__toggle"
id="glossary-hero-toggle"
type="button"
aria-controls="glossary-hero-intro"
aria-expanded="false"
hidden
>
lire la suite
</button>
</div>
<h2
class="glossary-hero-follow"
id="glossary-hero-follow"
@@ -36,6 +57,8 @@ const {
linear-gradient(180deg, rgba(0,0,0,0.60), rgba(0,0,0,0.90)),
radial-gradient(900px 240px at 20% 0%, rgba(0,217,255,0.08), transparent 60%);
transition:
padding 220ms cubic-bezier(.22,.8,.22,1),
border-radius 220ms cubic-bezier(.22,.8,.22,1),
background 300ms cubic-bezier(.22,.8,.22,1),
border-color 300ms cubic-bezier(.22,.8,.22,1),
box-shadow 300ms cubic-bezier(.22,.8,.22,1);
@@ -43,6 +66,8 @@ const {
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 12px;
min-width: 0;
overflow: clip;
}
.glossary-kicker{
@@ -59,6 +84,16 @@ const {
line-height: 1.02;
letter-spacing: -.04em;
font-weight: 850;
transition:
font-size 220ms cubic-bezier(.22,.8,.22,1),
line-height 220ms cubic-bezier(.22,.8,.22,1);
min-width: 0;
}
.glossary-hero__collapsible{
display: grid;
row-gap: 6px;
min-width: 0;
}
.glossary-intro{
@@ -67,13 +102,58 @@ const {
font-size: 1.05rem;
line-height: 1.55;
opacity: .94;
min-width: 0;
transition:
font-size 220ms cubic-bezier(.22,.8,.22,1),
line-height 220ms cubic-bezier(.22,.8,.22,1),
max-height 220ms cubic-bezier(.22,.8,.22,1),
opacity 180ms ease;
}
.glossary-hero__toggle{
display: inline-flex;
align-items: center;
justify-content: center;
width: fit-content;
min-height: 30px;
padding: 3px 0;
border: 0;
border-radius: 0;
background: transparent;
color: inherit;
font-size: 12px;
line-height: 1.2;
letter-spacing: .01em;
opacity: .72;
cursor: pointer;
text-decoration: underline;
text-decoration-thickness: 1px;
text-underline-offset: 2px;
transition:
opacity 120ms ease,
transform 120ms ease;
}
.glossary-hero__toggle:hover{
opacity: .92;
transform: translateY(-1px);
}
.glossary-hero__toggle:focus-visible{
outline: 2px solid rgba(0,217,255,0.24);
outline-offset: 4px;
border-radius: 4px;
}
.glossary-hero__toggle[hidden]{
display: none !important;
}
.glossary-hero-follow{
margin: 2px 0 0;
min-height: var(--glossary-follow-height);
display: flex;
align-items: flex-end;
display: block;
max-width: min(100%, 22ch);
opacity: 0;
transform: translateY(10px) scale(.985);
filter: blur(6px);
@@ -86,6 +166,7 @@ const {
overflow: hidden;
text-overflow: ellipsis;
will-change: opacity, transform, filter;
min-width: 0;
}
.glossary-hero-follow.is-visible{
@@ -94,10 +175,190 @@ const {
filter: blur(0);
}
:global(body.glossary-home-follow-on) .glossary-hero{
padding: 12px 14px 14px;
border-bottom-left-radius: 18px;
border-bottom-right-radius: 18px;
}
:global(body.glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.7rem, 3.2vw, 2.2rem);
line-height: 1.02;
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-intro{
font-size: .94rem;
line-height: 1.34;
max-height: 2.7em;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero__toggle{
display: inline-flex;
}
@media (max-width: 760px){
.glossary-hero{
top: calc(var(--glossary-sticky-top) - 2px);
padding: 12px 14px 16px;
border-radius: 22px;
row-gap: 10px;
}
.glossary-hero h1{
font-size: clamp(1.9rem, 8vw, 2.45rem);
line-height: 1.02;
letter-spacing: -.03em;
}
.glossary-hero__collapsible{
row-gap: 7px;
}
.glossary-intro{
max-width: 100%;
width: 100%;
font-size: .98rem;
line-height: 1.44;
}
:global(body.glossary-home-follow-on) .glossary-hero{
padding: 10px 13px 12px;
border-radius: 18px;
}
:global(body.glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.45rem, 6vw, 1.8rem);
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-intro{
max-width: 100%;
width: 100%;
font-size: .86rem;
line-height: 1.24;
max-height: 2.48em;
-webkit-line-clamp: 2;
opacity: .9;
}
.glossary-hero__toggle{
min-height: 28px;
font-size: 11.5px;
}
.glossary-hero-follow{
max-width: min(100%, 24ch);
}
}
@media (max-width: 520px){
.glossary-hero{
padding: 11px 12px 14px;
border-radius: 20px;
}
.glossary-intro{
max-width: 100%;
width: 100%;
font-size: .94rem;
line-height: 1.4;
}
:global(body.glossary-home-follow-on) .glossary-hero{
padding: 9px 11px 11px;
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-intro{
max-width: 100%;
width: 100%;
font-size: .84rem;
line-height: 1.22;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-hero{
padding: 10px 12px 12px;
border-radius: 16px;
row-gap: 8px;
}
.glossary-kicker{
font-size: 10px;
letter-spacing: .1em;
}
.glossary-hero h1{
font-size: clamp(1.35rem, 4vw, 1.8rem);
line-height: 1;
}
.glossary-intro{
font-size: .84rem;
line-height: 1.24;
}
:global(body.glossary-home-follow-on) .glossary-hero{
padding: 9px 11px 10px;
border-radius: 16px;
}
:global(body.glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.1rem, 3vw, 1.35rem);
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-intro{
font-size: .8rem;
line-height: 1.18;
max-height: 2.36em;
-webkit-line-clamp: 2;
opacity: .88;
}
.glossary-hero__toggle{
min-height: 24px;
font-size: 11px;
}
.glossary-hero-follow{
max-width: min(100%, 26ch);
}
}
@media (max-width: 860px){
.glossary-hero{
position: static !important;
top: auto !important;
z-index: auto !important;
margin-bottom: 18px !important;
}
.glossary-hero-follow{
display: none !important;
min-height: 0 !important;
opacity: 0 !important;
transform: none !important;
filter: none !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-hero{
position: static !important;
top: auto !important;
z-index: auto !important;
margin-bottom: 14px !important;
}
.glossary-hero-follow{
display: none !important;
min-height: 0 !important;
opacity: 0 !important;
transform: none !important;
filter: none !important;
}
}
</style>

View File

@@ -43,22 +43,22 @@ const showCta = Boolean(ctaHref && ctaLabel);
<style>
.glossary-section{
margin-top: 42px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 190px);
margin-top: 34px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 150px);
}
.glossary-section__head{
display: flex;
justify-content: space-between;
align-items: start;
gap: 16px;
gap: 14px;
flex-wrap: wrap;
margin-bottom: 14px;
margin-bottom: 12px;
}
.glossary-section h2{
margin: 0;
font-size: clamp(2rem, 3vw, 2.55rem);
font-size: clamp(1.8rem, 3vw, 2.55rem);
line-height: 1.06;
letter-spacing: -.03em;
font-weight: 800;
@@ -67,23 +67,23 @@ const showCta = Boolean(ctaHref && ctaLabel);
.glossary-intro{
margin: 0;
max-width: 72ch;
font-size: 1.05rem;
line-height: 1.55;
font-size: 1rem;
line-height: 1.52;
opacity: .94;
}
.glossary-section__head .glossary-intro{
margin-top: 10px;
margin-top: 8px;
}
.glossary-cta{
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 40px;
min-height: 38px;
border: 1px solid var(--glossary-border-strong);
border-radius: 999px;
padding: 7px 14px;
padding: 6px 13px;
color: var(--glossary-accent);
text-decoration: none;
white-space: nowrap;
@@ -97,13 +97,37 @@ const showCta = Boolean(ctaHref && ctaLabel);
}
@media (max-width: 760px){
.glossary-section{
margin-top: 24px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 110px);
}
.glossary-section__head{
flex-direction: column;
align-items: stretch;
gap: 10px;
margin-bottom: 10px;
}
.glossary-section h2{
font-size: clamp(1.45rem, 6vw, 1.95rem);
line-height: 1.05;
}
.glossary-intro{
font-size: .95rem;
line-height: 1.42;
}
.glossary-section__head .glossary-intro{
margin-top: 6px;
}
.glossary-cta{
width: fit-content;
min-height: 35px;
padding: 5px 12px;
font-size: .95rem;
}
}
</style>

View File

@@ -65,37 +65,39 @@ const {
.glossary-portal-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-portal-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-portal-aside__title{
font-size: 14px;
font-size: 16px;
font-weight: 800;
letter-spacing: .2px;
line-height: 1.25;
line-height: 1.3;
}
.glossary-portal-aside__meta{
margin-top: 8px;
font-size: 12px;
line-height: 1.35;
opacity: .78;
font-size: 13px;
line-height: 1.4;
opacity: .8;
}
.glossary-portal-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-portal-aside__list{
@@ -105,13 +107,108 @@ const {
}
.glossary-portal-aside__list li{
margin: 6px 0;
margin: 7px 0;
}
.glossary-portal-aside__list a{
text-decoration: none;
font-size: 13px;
line-height: 1.3;
font-size: 14px;
line-height: 1.4;
}
@media (max-width: 980px){
.glossary-portal-aside{
gap: 12px;
}
.glossary-portal-aside__block{
padding: 12px;
border-radius: 14px;
}
}
@media (max-width: 760px){
.glossary-portal-aside{
gap: 10px;
}
.glossary-portal-aside__block{
padding: 11px 12px;
border-radius: 14px;
}
.glossary-portal-aside__back{
margin-bottom: 8px;
font-size: 13px;
}
.glossary-portal-aside__title{
font-size: 15px;
line-height: 1.22;
}
.glossary-portal-aside__meta{
margin-top: 6px;
font-size: 12px;
line-height: 1.32;
}
.glossary-portal-aside__heading{
margin-bottom: 8px;
font-size: 13px;
line-height: 1.22;
}
.glossary-portal-aside__list li{
margin: 5px 0;
}
.glossary-portal-aside__list a{
font-size: 12.5px;
line-height: 1.3;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-portal-aside{
gap: 8px;
}
.glossary-portal-aside__block{
padding: 9px 10px;
border-radius: 12px;
}
.glossary-portal-aside__back{
margin-bottom: 6px;
font-size: 12px;
}
.glossary-portal-aside__title{
font-size: 14px;
line-height: 1.18;
}
.glossary-portal-aside__meta{
margin-top: 4px;
font-size: 11px;
line-height: 1.24;
}
.glossary-portal-aside__heading{
margin-bottom: 6px;
font-size: 12px;
line-height: 1.18;
}
.glossary-portal-aside__list li{
margin: 4px 0;
}
.glossary-portal-aside__list a{
font-size: 11.5px;
line-height: 1.22;
}
}
@media (prefers-color-scheme: dark){

View File

@@ -24,64 +24,44 @@ const {
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);
padding: 7px 14px;
border: 1px solid rgba(127,127,127,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);
background: rgba(127,127,127,0.05);
text-decoration: none;
font-size: 12px;
font-weight: 800;
letter-spacing: .01em;
white-space: nowrap;
line-height: 1.2;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease,
box-shadow 120ms ease;
border-color 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);
background: rgba(127,127,127,0.08);
border-color: rgba(0,217,255,0.18);
text-decoration: none;
}
.glossary-portal-cta:focus-visible{
outline: 2px solid rgba(0,217,255,0.28);
outline-offset: 4px;
outline-offset: 3px;
}
@media (max-width: 720px){
@media (max-width: 760px){
.glossary-portal-cta{
width: 100%;
min-height: 36px;
padding: 6px 12px;
font-size: 12px;
}
}
@media (prefers-color-scheme: dark){
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.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);
min-height: 32px;
padding: 5px 10px;
font-size: 11px;
}
}
</style>

View File

@@ -36,17 +36,17 @@ const {
.glossary-portals{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 14px;
margin-top: 14px;
gap: 12px;
margin-top: 12px;
}
.glossary-portal-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px 18px;
gap: 7px;
padding: 14px 15px;
border: 1px solid var(--glossary-border);
border-radius: 18px;
border-radius: 16px;
background: var(--glossary-bg-soft);
text-decoration: none;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
@@ -61,24 +61,51 @@ const {
.glossary-portal-card strong{
color: var(--glossary-accent);
font-size: 1.08rem;
line-height: 1.28;
font-size: 1.04rem;
line-height: 1.24;
}
.glossary-portal-card span{
color: inherit;
font-size: 1rem;
line-height: 1.5;
font-size: .98rem;
line-height: 1.46;
opacity: .94;
}
.glossary-portal-card small{
color: var(--glossary-accent);
font-size: .94rem;
line-height: 1.35;
font-size: .9rem;
line-height: 1.28;
opacity: .9;
}
@media (max-width: 760px){
.glossary-portals{
grid-template-columns: 1fr;
gap: 10px;
margin-top: 10px;
}
.glossary-portal-card{
padding: 12px 12px;
border-radius: 14px;
gap: 6px;
}
.glossary-portal-card strong{
font-size: .98rem;
}
.glossary-portal-card span{
font-size: .94rem;
line-height: 1.42;
}
.glossary-portal-card small{
font-size: .85rem;
}
}
@media (prefers-color-scheme: dark){
.glossary-portal-card{
background: rgba(255,255,255,0.04);

View File

@@ -16,8 +16,8 @@ const {
title,
intro,
moreParagraphs = [],
introMaxWidth = "72ch",
followIntroMaxWidth = "68ch",
introMaxWidth = "70ch",
followIntroMaxWidth = "62ch",
moreMaxHeight = "18rem",
} = Astro.props;
---
@@ -25,12 +25,13 @@ const {
<div
class="glossary-portal-hero glossary-page-hero"
data-glossary-portal-hero
style={`--portal-hero-intro-max-w:${introMaxWidth}; --portal-hero-follow-intro-max-w:${followIntroMaxWidth}; --portal-hero-more-max-h:${moreMaxHeight};`}
style={`--portal-hero-intro-max-w:${introMaxWidth}; --portal-hero-follow-intro-max-w:${followIntroMaxWidth}; --portal-hero-secondary-max-h:${moreMaxHeight};`}
>
<p class="glossary-portal-hero__kicker">{kicker}</p>
<h1>{title}</h1>
<p class="glossary-portal-hero__intro">
<p class="glossary-portal-hero__intro glossary-portal-hero__intro--lead">
{intro}
</p>
@@ -43,7 +44,9 @@ const {
aria-hidden="false"
>
{moreParagraphs.map((paragraph) => (
<p class="glossary-portal-hero__intro">{paragraph}</p>
<p class="glossary-portal-hero__intro glossary-portal-hero__intro--more">
{paragraph}
</p>
))}
</div>
@@ -65,93 +68,121 @@ const {
<style>
.glossary-portal-hero{
position: sticky;
top: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px));
z-index: 11;
margin: 0 0 24px;
padding: 18px 18px 20px;
top: var(--glossary-sticky-top);
z-index: 12;
margin-bottom: var(--portal-hero-margin-bottom, 28px);
padding:
var(--portal-hero-pad-top, 20px)
var(--portal-hero-pad-x, 18px)
var(--portal-hero-pad-bottom, 22px);
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%);
radial-gradient(980px 260px at 18% 0%, rgba(0,217,255,0.08), transparent 60%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: grid;
row-gap: 14px;
row-gap: var(--portal-hero-gap, 16px);
min-width: 0;
overflow: hidden;
transition:
margin-bottom 180ms ease,
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease;
background 280ms cubic-bezier(.22,.8,.22,1),
border-color 220ms cubic-bezier(.22,.8,.22,1),
box-shadow 220ms cubic-bezier(.22,.8,.22,1),
border-radius 220ms ease,
padding 220ms ease,
row-gap 220ms ease,
margin-bottom 220ms ease;
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.02),
0 10px 26px rgba(0,0,0,0.08);
}
.glossary-portal-hero__kicker{
margin: 0;
font-size: 12px;
letter-spacing: .08em;
font-size: var(--portal-kicker-size, 12px);
line-height: var(--portal-kicker-lh, 1.2);
letter-spacing: var(--portal-kicker-spacing, .14em);
text-transform: uppercase;
opacity: .72;
font-weight: 650;
opacity: .74;
}
.glossary-portal-hero h1{
margin: 0;
font-size: clamp(2.2rem, 4vw, 3.15rem);
line-height: 1.02;
letter-spacing: -.04em;
font-size: var(--portal-hero-h1-size, clamp(3rem, 4.8vw, 4.15rem));
line-height: var(--portal-hero-h1-lh, .98);
letter-spacing: var(--portal-hero-h1-spacing, -.045em);
font-weight: 850;
transition: font-size 180ms ease;
text-wrap: balance;
transition:
font-size 180ms ease,
line-height 180ms ease,
letter-spacing 180ms ease;
}
.glossary-portal-hero__intro{
margin: 0;
max-width: var(--portal-hero-intro-max-w);
font-size: 1.04rem;
line-height: 1.55;
opacity: .94;
max-width: var(--portal-hero-intro-max-w, 70ch);
font-size: var(--portal-hero-intro-size, 1.06rem);
line-height: var(--portal-hero-intro-lh, 1.6);
text-wrap: pretty;
transition:
font-size 180ms ease,
line-height 180ms ease,
max-width 180ms ease;
max-width 180ms ease,
opacity 180ms ease;
}
.glossary-portal-hero__intro--lead{ opacity: .95; }
.glossary-portal-hero__intro--more{ opacity: .89; }
.glossary-portal-hero__collapsible{
display: grid;
row-gap: 6px;
row-gap: 8px;
min-width: 0;
}
.glossary-portal-hero__more{
display: grid;
row-gap: 14px;
max-height: var(--portal-hero-more-max-h);
gap: 12px;
max-height: var(--portal-hero-secondary-max-h, 20em);
overflow: hidden;
opacity: 1;
opacity: var(--portal-hero-secondary-opacity, .92);
min-width: 0;
transition:
max-height 220ms ease,
opacity 180ms ease;
}
.glossary-portal-hero__toggle{
display: none;
align-self: flex-start;
display: inline-flex;
align-items: center;
justify-content: center;
width: fit-content;
margin: 0;
padding: 0;
min-height: 34px;
padding: 5px 0;
border: 0;
border-radius: 0;
background: transparent;
color: inherit;
font: inherit;
font-size: 11px;
font-size: 12.5px;
line-height: 1.2;
letter-spacing: .01em;
opacity: .56;
opacity: .72;
cursor: pointer;
text-decoration: underline;
text-underline-offset: .12em;
text-decoration-thickness: 1px;
text-underline-offset: 2px;
transition:
opacity 120ms ease,
transform 120ms ease;
}
.glossary-portal-hero__toggle:hover{
opacity: .84;
opacity: .92;
transform: translateY(-1px);
}
.glossary-portal-hero__toggle:focus-visible{
@@ -164,27 +195,66 @@ const {
display: none !important;
}
@media (max-width: 860px){
@media (max-width: 980px){
.glossary-portal-hero{
position: static;
border-radius: 22px;
margin-bottom: 20px;
padding: 14px 14px 16px;
row-gap: 12px;
border-radius: 24px;
}
.glossary-portal-hero__intro{
max-width: none;
.glossary-portal-hero h1{
text-wrap: pretty;
}
.glossary-portal-hero__more{
max-height: none;
opacity: 1;
overflow: visible;
gap: 10px;
}
}
@media (max-width: 860px){
.glossary-portal-hero{
position: static !important;
top: auto !important;
z-index: auto !important;
margin-bottom: 18px !important;
width: 100% !important;
max-width: 100% !important;
min-width: 0 !important;
}
.glossary-portal-hero__toggle{
display: none !important;
.glossary-portal-hero h1,
.glossary-portal-hero__intro,
.glossary-portal-hero__more,
.glossary-portal-hero__collapsible{
min-width: 0 !important;
max-width: 100% !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-portal-hero{
position: static !important;
top: auto !important;
z-index: auto !important;
margin-bottom: 14px !important;
width: 100% !important;
max-width: 100% !important;
min-width: 0 !important;
border-radius: 16px !important;
}
.glossary-portal-hero h1,
.glossary-portal-hero__intro,
.glossary-portal-hero__more,
.glossary-portal-hero__collapsible{
min-width: 0 !important;
max-width: 100% !important;
}
}
@media (prefers-color-scheme: dark){
.glossary-portal-hero{
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.02),
0 14px 34px rgba(0,0,0,0.16);
}
}
</style>

View File

@@ -38,59 +38,90 @@ const {
<style>
.glossary-portal-panel{
display: grid;
gap: 12px;
gap: 10px;
}
.glossary-portal-panel--surface{
padding: 18px 18px 16px;
padding:
var(--portal-panel-pad-y, 16px)
var(--portal-panel-pad-x, 16px);
border: 1px solid var(--glossary-border, rgba(127,127,127,0.18));
border-radius: 18px;
border-radius: var(--portal-panel-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;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
gap: 10px;
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);
font-size: var(--portal-local-h3-size, clamp(1.35rem, 2vw, 1.7rem));
line-height: var(--portal-local-h3-lh, 1.15);
letter-spacing: -.02em;
}
.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);
min-height: 26px;
padding: 0 9px;
border: 1px solid rgba(127,127,127,0.20);
border-radius: 999px;
font-size: 12px;
background: rgba(127,127,127,0.04);
font-size: 11.5px;
line-height: 1.2;
opacity: .78;
opacity: .8;
white-space: nowrap;
}
.glossary-portal-panel__intro{
max-width: 78ch;
margin: 0;
font-size: 14px;
line-height: 1.5;
opacity: .9;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
@media (max-width: 760px){
.glossary-portal-panel{
gap: 8px;
}
.glossary-portal-panel__head{
gap: 8px;
}
.glossary-portal-panel__count{
min-height: 23px;
padding: 0 8px;
font-size: 10.5px;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-portal-panel{
gap: 6px;
}
.glossary-portal-panel__head{
gap: 6px;
}
.glossary-portal-panel__count{
min-height: 21px;
padding: 0 7px;
font-size: 10px;
}
}
@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);
background: rgba(255,255,255,0.04);
}
}
</style>

View File

@@ -31,37 +31,113 @@ const {
<style>
.glossary-portal-section{
margin-top: 34px;
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 28px);
margin-top: 30px;
}
.glossary-portal-section h2{
scroll-margin-top: calc(var(--sticky-offset-px, 96px) + 28px);
margin: 0;
font-size: clamp(1.8rem, 3vw, 2.35rem);
line-height: 1.05;
letter-spacing: -.03em;
font-weight: 800;
}
.glossary-portal-section__head{
display: flex;
align-items: baseline;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 10px;
position: static;
}
.glossary-portal-section__count{
font-size: 13px;
opacity: .72;
display: inline-flex;
align-items: center;
min-height: 28px;
padding: 0 10px;
border: 1px solid rgba(127,127,127,0.20);
border-radius: 999px;
background: rgba(127,127,127,0.04);
font-size: 12px;
line-height: 1.2;
opacity: .8;
white-space: nowrap;
}
.glossary-portal-section__intro{
max-width: 78ch;
margin: 0;
opacity: .92;
max-width: 76ch;
font-size: var(--portal-body-size, 1rem);
line-height: var(--portal-body-lh, 1.55);
opacity: .94;
}
.glossary-portal-section--final{
margin-top: 42px;
margin-top: 34px;
}
@media (max-width: 980px){
.glossary-portal-section{
margin-top: 24px;
}
.glossary-portal-section h2{
font-size: clamp(1.6rem, 4.4vw, 2rem);
line-height: 1.04;
}
}
@media (max-width: 760px){
.glossary-portal-section{
margin-top: 20px;
}
.glossary-portal-section__head{
gap: 8px;
margin-bottom: 8px;
}
.glossary-portal-section h2{
font-size: clamp(1.34rem, 6.5vw, 1.72rem);
line-height: 1.04;
letter-spacing: -.022em;
}
.glossary-portal-section__count{
min-height: 24px;
padding: 0 8px;
font-size: 11px;
}
.glossary-portal-section--final{
margin-top: 24px;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-portal-section{
margin-top: 16px;
}
.glossary-portal-section__head{
gap: 6px;
margin-bottom: 6px;
}
.glossary-portal-section h2{
font-size: clamp(1.12rem, 4.2vw, 1.34rem);
line-height: 1.02;
}
.glossary-portal-section__count{
min-height: 22px;
padding: 0 7px;
font-size: 10px;
}
.glossary-portal-section--final{
margin-top: 18px;
}
}
</style>

View File

@@ -34,16 +34,24 @@ const {
const BODY_CLASS = "is-glossary-portal-page";
const FOLLOW_ON_CLASS = "glossary-portal-follow-on";
const EXPANDED_CLASS = "glossary-portal-hero-expanded";
const CONDENSED_CLASS = "glossary-portal-hero-condensed";
const mqMobile = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`);
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
let expandedAtY = null;
let lastScrollY = window.scrollY || 0;
let raf = 0;
let lastFollowOn = null;
let lastCondensed = null;
let lastHeroHeight = -1;
body.classList.add(BODY_CLASS);
const heroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const stripLocalSticky = () => {
document.querySelectorAll(sectionHeadSelector).forEach((el) => {
@@ -52,14 +60,53 @@ const {
});
};
const readStickyTop = () => {
const raw = getComputedStyle(document.documentElement)
.getPropertyValue("--glossary-sticky-top")
.trim();
const n = Number.parseFloat(raw);
return Number.isFinite(n) ? n : 64;
};
const computeFollowOn = () =>
!mqMobile.matches &&
!isCompactViewport() &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const computeCondensed = () => {
if (isCompactViewport()) return false;
const heroRect = hero.getBoundingClientRect();
const stickyTop = readStickyTop();
return heroRect.top <= stickyTop + 2;
};
const measureHeroHeight = () =>
Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));
const PIN_EPS = 3;
const isHeroPinned = () => {
if (isCompactViewport()) return false;
const rect = hero.getBoundingClientRect();
const stickyTop = readStickyTop();
const cs = getComputedStyle(hero);
if (cs.position !== "sticky") return false;
const pinnedOnRail = Math.abs(rect.top - stickyTop) <= PIN_EPS;
const stillVisible = rect.bottom > stickyTop + 24;
return pinnedOnRail && stillVisible;
};
const applyLocalStickyHeight = () => {
const h = mqMobile.matches ? 0 : heroHeight();
const h = isHeroPinned() ? measureHeroHeight() : 0;
if (h === lastHeroHeight) return;
lastHeroHeight = h;
if (typeof window.__archiSetLocalStickyHeight === "function") {
window.__archiSetLocalStickyHeight(h);
@@ -70,10 +117,26 @@ const {
const syncFollowState = () => {
const on = computeFollowOn();
body.classList.toggle(FOLLOW_ON_CLASS, on);
if (on !== lastFollowOn) {
lastFollowOn = on;
body.classList.toggle(FOLLOW_ON_CLASS, on);
}
return on;
};
const syncCondensedState = () => {
const condensed = computeCondensed();
if (condensed !== lastCondensed) {
lastCondensed = condensed;
body.classList.toggle(CONDENSED_CLASS, condensed);
}
return condensed;
};
const collapseHero = () => {
if (!body.classList.contains(EXPANDED_CLASS)) return;
@@ -116,12 +179,11 @@ const {
schedule();
};
const syncHeroState = () => {
const followOn = computeFollowOn();
const syncHeroState = (condensed) => {
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = followOn && !expanded;
const collapsed = condensed && !expanded;
if (!followOn || mqMobile.matches) {
if (isCompactViewport() || !condensed) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
@@ -148,12 +210,7 @@ const {
};
const maybeAutoCollapseOnScroll = () => {
if (mqMobile.matches) {
lastScrollY = window.scrollY || 0;
return;
}
if (!computeFollowOn()) {
if (isCompactViewport()) {
lastScrollY = window.scrollY || 0;
return;
}
@@ -181,16 +238,59 @@ const {
const syncAll = () => {
stripLocalSticky();
syncFollowState();
syncHeroState();
applyLocalStickyHeight();
if (isCompactViewport()) {
body.classList.remove(FOLLOW_ON_CLASS);
body.classList.remove(CONDENSED_CLASS);
body.classList.remove(EXPANDED_CLASS);
lastFollowOn = false;
lastCondensed = false;
expandedAtY = null;
if (heroMore) {
heroMore.setAttribute("aria-hidden", "false");
}
if (heroToggle) {
heroToggle.hidden = true;
heroToggle.setAttribute("aria-expanded", "false");
}
requestAnimationFrame(() => {
applyLocalStickyHeight();
try {
window.__archiUpdateFollow?.();
} catch {}
});
return;
}
const condensed = syncCondensedState();
syncHeroState(condensed);
requestAnimationFrame(() => {
applyLocalStickyHeight();
syncFollowState();
try {
window.__archiUpdateFollow?.();
} catch {}
});
requestAnimationFrame(() => {
applyLocalStickyHeight();
try {
window.__archiUpdateFollow?.();
} catch {}
});
};
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
requestAnimationFrame(syncAll);
syncAll();
});
};
@@ -229,6 +329,12 @@ const {
mqMobile.addListener(schedule);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", schedule);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(schedule);
}
schedule();
};
@@ -245,40 +351,63 @@ const {
z-index: 10;
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero){
margin-bottom: 0;
padding: 12px 16px 14px;
row-gap: 10px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
/* Le hero se condense dès quil devient sticky */
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed .glossary-portal-hero){
padding:
var(--portal-hero-pad-top-condensed, 14px)
var(--portal-hero-pad-x-condensed, 16px)
var(--portal-hero-pad-bottom-condensed, 16px);
row-gap: var(--portal-hero-gap-condensed, 10px);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.02),
0 8px 20px rgba(0,0,0,0.12);
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero h1){
font-size: clamp(1.9rem, 3.2vw, 2.55rem);
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed .glossary-portal-hero h1){
font-size: var(--portal-hero-h1-size-condensed, clamp(2.05rem, 3.15vw, 2.7rem));
line-height: var(--portal-hero-h1-lh-condensed, 1);
letter-spacing: var(--portal-hero-h1-spacing-condensed, -.04em);
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero__intro){
max-width: var(--portal-hero-follow-intro-max-w, 68ch);
font-size: .98rem;
line-height: 1.48;
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed .glossary-portal-hero__intro){
max-width: var(--portal-hero-follow-intro-max-w, 62ch);
font-size: var(--portal-hero-intro-size-condensed, .98rem);
line-height: var(--portal-hero-intro-lh-condensed, 1.46);
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on:not(.glossary-portal-hero-expanded) .glossary-portal-hero__more){
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed .glossary-portal-hero__kicker){
opacity: .68;
}
/* Le more se replie dès létat condensé */
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__more){
max-height: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on:not(.glossary-portal-hero-expanded) .glossary-portal-hero__toggle){
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__toggle){
display: inline-flex;
}
/* Laccolage hero + follow narrive que quand le follow est actif */
:global(body.is-glossary-portal-page.glossary-portal-hero-condensed.glossary-portal-follow-on .glossary-portal-hero){
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on #reading-follow .reading-follow__inner){
margin-top: -1px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
:global(body.is-glossary-portal-page.glossary-portal-follow-on #reading-follow .rf-h2){
letter-spacing: -.02em;
}
:global(body.is-glossary-portal-page .glossary-portal-section__head.is-sticky),
:global(body.is-glossary-portal-page .glossary-portal-section__head[data-sticky-active="true"]){
position: static !important;
@@ -291,4 +420,68 @@ const {
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero){
margin-bottom: var(--portal-hero-margin-bottom, 18px);
border-radius: 20px !important;
box-shadow: none !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero__more){
max-height: none !important;
opacity: 1 !important;
overflow: visible !important;
pointer-events: auto !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero__toggle){
display: none !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero){
margin-bottom: var(--portal-hero-margin-bottom, 12px);
border-radius: 16px !important;
box-shadow: none !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero__more){
max-height: none !important;
opacity: 1 !important;
overflow: visible !important;
pointer-events: auto !important;
}
:global(body.is-glossary-portal-page .glossary-portal-hero__toggle){
display: none !important;
}
}
</style>

View File

@@ -36,44 +36,45 @@ const relationsHeadingId = "relations-conceptuelles";
<style>
.glossary-relations{
margin-top: 26px;
padding-top: 18px;
margin-top: 22px;
padding-top: 14px;
border-top: 1px solid rgba(127,127,127,0.18);
}
.glossary-relations h2{
margin-bottom: 14px;
margin: 0 0 12px;
font-size: clamp(1.35rem, 3vw, 1.8rem);
line-height: 1.08;
}
.glossary-relations-grid{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 10px;
}
.glossary-relations-card{
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
padding: 14px 16px;
border: 1px solid rgba(127,127,127,0.20);
border-radius: 14px;
padding: 12px 13px;
background: rgba(127,127,127,0.05);
}
.glossary-relations-card h3{
margin-top: 0;
margin-bottom: 10px;
font-size: 15px;
line-height: 1.35;
margin: 0 0 8px;
font-size: 14px;
line-height: 1.3;
}
.glossary-relations-card ul{
margin: 0;
padding-left: 18px;
padding-left: 16px;
}
.glossary-relations-card li{
margin-bottom: 8px;
font-size: 14px;
line-height: 1.45;
margin-bottom: 7px;
font-size: 13.5px;
line-height: 1.42;
}
.glossary-relations-card li:last-child{
@@ -81,7 +82,39 @@ const relationsHeadingId = "relations-conceptuelles";
}
.glossary-relations-card span{
opacity: .9;
opacity: .88;
}
@media (max-width: 760px){
.glossary-relations{
margin-top: 18px;
padding-top: 12px;
}
.glossary-relations h2{
margin-bottom: 10px;
font-size: 1.3rem;
}
.glossary-relations-grid{
grid-template-columns: 1fr;
gap: 8px;
}
.glossary-relations-card{
padding: 11px 11px;
border-radius: 13px;
}
.glossary-relations-card h3{
font-size: 13px;
margin-bottom: 7px;
}
.glossary-relations-card li{
font-size: 13px;
line-height: 1.38;
}
}
@media (prefers-color-scheme: dark){

View File

@@ -68,7 +68,6 @@ const { initialLevel = 1 } = Astro.props;
} catch {}
}
// init : storage > initialLevel
let start = clampLevel(initialLevel);
try {
const stored = localStorage.getItem(KEY);
@@ -77,13 +76,11 @@ const { initialLevel = 1 } = Astro.props;
applyLevel(start, { persist: false });
// clicks
wrap.addEventListener("click", (ev) => {
const btn = ev.target?.closest?.("button[data-level]");
if (!btn) return;
ev.preventDefault();
// ✅ crucial : on capture la position AVANT le reflow lié au changement de niveau
captureBeforeLevelSwitch();
applyLevel(btn.dataset.level);
});
@@ -95,6 +92,8 @@ const { initialLevel = 1 } = Astro.props;
display: inline-flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
max-width: 100%;
}
.level-btn{
@@ -106,6 +105,7 @@ const { initialLevel = 1 } = Astro.props;
cursor: pointer;
user-select: none;
transition: filter .12s ease, transform .12s ease, background .12s ease, border-color .12s ease;
white-space: nowrap;
}
.level-btn:hover{
@@ -125,4 +125,21 @@ const { initialLevel = 1 } = Astro.props;
.level-btn:active{
transform: translateY(1px);
}
</style>
@media (max-width: 980px){
.level-toggle{
gap: 6px;
}
.level-btn{
padding: 5px 9px;
font-size: 12px;
}
}
@media (max-width: 760px){
.level-toggle{
display: none;
}
}
</style>

View File

@@ -3,49 +3,122 @@ const { headings } = Astro.props;
// H2/H3 seulement
const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
---
{items.length > 0 && (
<nav class="toc-local" aria-label="Dans ce chapitre">
<div class="toc-local__title">Dans ce chapitre</div>
<nav class="toc-local" aria-label="Dans ce chapitre" data-toc-local>
<button
class="toc-local__head toc-local__toggle"
type="button"
aria-expanded="true"
aria-controls={tocId}
>
<span class="toc-local__title">Dans ce chapitre</span>
<span class="toc-local__chevron" aria-hidden="true">▾</span>
</button>
<ol class="toc-local__list">
{items.map((h) => (
<li
class={`toc-local__item d${h.depth}`}
data-toc-item
data-depth={h.depth}
data-id={h.slug}
>
<a href={`#${h.slug}`} data-toc-link data-slug={h.slug}>
{h.text}
</a>
</li>
))}
</ol>
<div class="toc-local__body-clip" id={tocId}>
<div class="toc-local__body">
<ol class="toc-local__list">
{items.map((h) => (
<li
class={`toc-local__item d${h.depth}`}
data-toc-item
data-depth={h.depth}
data-id={h.slug}
>
<a href={`#${h.slug}`} data-toc-link data-slug={h.slug}>
<span class="toc-local__mark" aria-hidden="true"></span>
<span class="toc-local__text">{h.text}</span>
</a>
</li>
))}
</ol>
</div>
</div>
</nav>
)}
<script is:inline>
(() => {
function init() {
const toc = document.querySelector(".toc-local");
if (!toc) return;
const toc = document.querySelector(".toc-local[data-toc-local]");
if (!toc || toc.dataset.tocReady === "1") return;
toc.dataset.tocReady = "1";
const toggle = toc.querySelector(".toc-local__toggle");
const bodyClip = toc.querySelector(".toc-local__body-clip");
const mq = window.matchMedia("(max-width: 980px)");
const KEY = `archicratie:toc-local:${window.location.pathname}`;
if (!toggle || !bodyClip) return;
const readState = () => {
try {
const v = localStorage.getItem(KEY);
if (v === "open") return true;
if (v === "closed") return false;
} catch {}
return null;
};
const writeState = (open) => {
try { localStorage.setItem(KEY, open ? "open" : "closed"); } catch {}
};
const setOpen = (open, { persist = true, emit = true } = {}) => {
const isMobile = mq.matches;
toc.classList.toggle("is-collapsed", isMobile && !open);
toggle.setAttribute("aria-expanded", open ? "true" : "false");
if (persist && isMobile) writeState(open);
if (emit && open && isMobile) {
window.dispatchEvent(new CustomEvent("archicratie:tocLocalOpen"));
}
};
const initAccordion = () => {
if (!mq.matches) {
setOpen(true, { persist: false, emit: false });
return;
}
const stored = readState();
setOpen(stored == null ? true : stored, { persist: false, emit: false });
};
toggle.addEventListener("click", () => {
const next = toggle.getAttribute("aria-expanded") !== "true";
setOpen(next);
});
if (mq.addEventListener) {
mq.addEventListener("change", initAccordion);
} else if (mq.addListener) {
mq.addListener(initAccordion);
}
const itemEls = Array.from(toc.querySelectorAll("[data-toc-item]"));
if (!itemEls.length) return;
if (!itemEls.length) {
initAccordion();
return;
}
const ordered = itemEls
.map((li) => {
const a = li.querySelector("a[data-toc-link]");
const id = li.getAttribute("data-id") || a?.dataset.slug || "";
const depth = Number(li.getAttribute("data-depth") || "0");
const el = id ? document.getElementById(id) : null; // span.details-anchor OU h3[id]
const el = id ? document.getElementById(id) : null;
return (a && id && el) ? { id, depth, li, a, el } : null;
})
.filter(Boolean);
if (!ordered.length) return;
if (!ordered.length) {
initAccordion();
return;
}
const clear = () => {
for (const t of ordered) {
@@ -55,14 +128,29 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
};
const openDetailsIfNeeded = (el) => {
const d = el?.closest?.("details");
if (d && !d.open) d.open = true;
try {
if (!el) return;
let d = el.closest?.("details") || null;
if (!d && el.classList?.contains("details-anchor")) {
const n = el.nextElementSibling;
if (n && n.tagName === "DETAILS") d = n;
}
if (!d) {
const s = el.closest?.("summary");
if (s && s.parentElement && s.parentElement.tagName === "DETAILS") d = s.parentElement;
}
if (d && d.tagName === "DETAILS" && !d.open) d.open = true;
} catch {}
};
let current = "";
const setCurrent = (id) => {
if (!id || id === current) return;
const setCurrent = (id, { autoOpen = true } = {}) => {
if (!id) return;
const t = ordered.find((x) => x.id === id);
if (!t) return;
@@ -74,17 +162,21 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
t.a.setAttribute("aria-current", "true");
t.li.classList.add("is-current");
// ✅ IMPORTANT: plus de scrollIntoView ici
// sinon ça scroll l'aside pendant le scroll du reading => TOC global “disparaît”.
if (mq.matches && autoOpen && toc.classList.contains("is-collapsed")) {
setOpen(true);
}
window.dispatchEvent(
new CustomEvent("archicratie:tocLocalActive", { detail: { id } })
);
};
const computeActive = () => {
const visible = ordered.filter((t) => {
const d = t.el.closest?.("details");
if (d && !d.open) {
// Si l'élément est dans <summary>, il reste visible même details fermé
const inSummary = !!t.el.closest?.("summary");
if (!inSummary) return false;
if (!inSummary && !t.el.classList?.contains("details-anchor")) return false;
}
return true;
});
@@ -102,7 +194,7 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
}
if (!best) best = visible[0];
setCurrent(best.id);
if (best && best.id !== current) setCurrent(best.id, { autoOpen: true });
};
let ticking = false;
@@ -117,11 +209,14 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
const syncFromHash = () => {
const id = (location.hash || "").slice(1);
if (!id) { computeActive(); return; }
if (!id) {
computeActive();
return;
}
const el = document.getElementById(id);
if (el) openDetailsIfNeeded(el);
setCurrent(id);
setCurrent(id, { autoOpen: true });
};
toc.addEventListener("click", (ev) => {
@@ -133,13 +228,14 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
const el = document.getElementById(id);
if (el) openDetailsIfNeeded(el);
setCurrent(id);
setCurrent(id, { autoOpen: true });
});
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll);
window.addEventListener("hashchange", syncFromHash);
initAccordion();
syncFromHash();
onScroll();
}
@@ -153,30 +249,183 @@ const items = (headings || []).filter((h) => h.depth >= 2 && h.depth <= 3);
</script>
<style>
.toc-local{margin-top:12px;border:1px solid rgba(127,127,127,.25);border-radius:16px;padding:12px}
.toc-local__title{font-size:13px;opacity:.85;margin-bottom:8px}
.toc-local__list{list-style:none;margin:0;padding:0}
.toc-local__item::marker{content:""}
.toc-local__item{margin:6px 0}
.toc-local__item.d3{margin-left:12px;opacity:.9}
.toc-local__item.is-current > a{
font-weight: 750;
text-decoration: underline;
.toc-local{
margin-top: 12px;
border: 1px solid rgba(127,127,127,.25);
border-radius: 16px;
padding: 12px;
background: rgba(127,127,127,0.03);
}
.toc-local a{
display:inline-block;
max-width:100%;
text-decoration:none;
.toc-local__toggle{
width: 100%;
appearance: none;
border: 0;
background: transparent;
color: inherit;
text-align: left;
padding: 0;
cursor: pointer;
}
.toc-local a:hover{ text-decoration: underline; }
.toc-local__head{
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-bottom: 8px;
}
.toc-local__title{
font-size: 13px;
opacity: .85;
}
.toc-local__chevron{
font-size: 12px;
opacity: .72;
transition: transform 180ms ease;
}
.toc-local__body-clip{
display: grid;
grid-template-rows: 1fr;
transition:
grid-template-rows 220ms ease,
opacity 160ms ease,
margin-top 220ms ease;
}
.toc-local__body{
min-height: 0;
overflow: hidden;
}
.toc-local__list{
list-style: none;
margin: 0;
padding: 0;
max-height: 44vh;
overflow: auto;
padding-right: 8px;
scrollbar-gutter: stable;
}
</style>
.toc-local__item::marker{ content:""; }
.toc-local__item{ margin: 6px 0; }
.toc-local__item.d3{
margin-left: 14px;
opacity: .94;
}
.toc-local a{
display: grid;
grid-template-columns: auto 1fr;
gap: 8px;
align-items: start;
max-width: 100%;
text-decoration: none;
}
.toc-local a:hover{
text-decoration: none;
}
.toc-local__mark{
width: 10px;
height: 10px;
margin-top: .36em;
border-radius: 999px;
border: 1px solid rgba(127,127,127,.34);
background: transparent;
opacity: .68;
}
.toc-local__text{
line-height: 1.28;
}
.toc-local__item.is-current > a{
font-weight: 760;
}
.toc-local__item.is-current > a .toc-local__mark{
background: currentColor;
border-color: currentColor;
box-shadow: 0 0 0 3px rgba(127,127,127,.10);
opacity: 1;
}
@media (max-width: 980px){
.toc-local{
padding: 10px 12px;
border-radius: 14px;
}
.toc-local__head{
margin-bottom: 0;
min-height: 28px;
}
.toc-local__body-clip{
margin-top: 10px;
}
.toc-local.is-collapsed .toc-local__body-clip{
grid-template-rows: 0fr;
opacity: 0;
margin-top: 0;
}
.toc-local__body{
min-height: 0;
overflow: hidden;
transition: opacity 180ms ease;
}
.toc-local.is-collapsed .toc-local__body{
opacity: 0;
}
.toc-local.is-collapsed .toc-local__chevron{
transform: rotate(-90deg);
}
.toc-local__title{
font-size: 13px;
}
.toc-local__list{
max-height: min(42vh, 360px);
padding-right: 4px;
}
.toc-local__item{
margin: 5px 0;
}
.toc-local__item.d2 > a .toc-local__text{
font-size: 12.9px;
line-height: 1.24;
font-weight: 680;
}
.toc-local__item.d3{
margin-left: 12px;
}
.toc-local__item.d3 > a .toc-local__text{
font-size: 12.1px;
line-height: 1.22;
opacity: .95;
}
.toc-local__item.d3 > a .toc-local__mark{
width: 8px;
height: 8px;
margin-top: .42em;
opacity: .55;
}
}
</style>

View File

@@ -32,7 +32,7 @@ Cette grammaire ne vaut toutefois quà condition daccepter dêtre elle-
## **3.1 — Régimes des philosophies fondatrices de lordre —** *puissance instituante*
2. À lorée de la philosophie politique moderne simpose une question matricielle : quest-ce qui fonde lautorité, et à quelles conditions cette fondation peut-elle rendre le vivre-ensemble politiquement viable ? Les pensées étudiées ici — Hobbes, Locke et Rousseau — répondent toutes, chacune à leur manière, à cette exigence de structuration du commun. Mais elles le font à partir dune arcalité fondatrice : peur primordiale, droit naturel, volonté générale. Dans chaque cas, un principe supérieur vient justifier lordre institué en le précédant, en lorientant et en le contraignant.
À lorée de la philosophie politique moderne simpose une question matricielle : quest-ce qui fonde lautorité, et à quelles conditions cette fondation peut-elle rendre le vivre-ensemble politiquement viable ? Les pensées étudiées ici — Hobbes, Locke et Rousseau — répondent toutes, chacune à leur manière, à cette exigence de structuration du commun. Mais elles le font à partir dune arcalité fondatrice : peur primordiale, droit naturel, volonté générale. Dans chaque cas, un principe supérieur vient justifier lordre institué en le précédant, en lorientant et en le contraignant.
Or lexigence archicratique ne se satisfait pas de cette extériorité du principe. Elle interroge moins ce qui fonde le pouvoir que ce qui permet de le tenir sans labsolutiser, de le moduler sans labolir, et de rendre la co-viabilité collective effectivement praticable. De ce point de vue, les philosophies fondatrices sont à la fois indispensables et insuffisantes : indispensables parce quelles posent les cadres majeurs de la pensée politique moderne ; insuffisantes parce quelles confondent encore la structure de la régulation avec la seule légitimation du pouvoir.

View File

@@ -12,7 +12,7 @@ source:
kind: docx
path: "sources/docx/archicrat-ia/Chapitre_5—Problematiques_des_tensions_des_co-viabilites_et_des_regulations_archicratiques-version_officielle.docx"
---
2. Lépoque contemporaine sest emparée du terme soutenabilité avec une insistance telle quelle pourrait laisser croire à lémergence dune conscience enfin lucide de linterdépendance entre systèmes naturels, économies, institutions, subjectivités, techniques et formes de vie. À première vue, le mot paraît répondre à une nécessité historique. Il semble désigner la prise en compte des limites, des vulnérabilités, des interdépendances et des irréversibilités qui traversent le monde contemporain. Pourtant, cette évidence apparente exige dêtre immédiatement troublée. Car la soutenabilité ne se borne pas à nommer une alerte ; elle en organise aussi le cadrage, en reformulant les contradictions du monde dans les termes dune mise en compatibilité administrable.
Lépoque contemporaine sest emparée du terme soutenabilité avec une insistance telle quelle pourrait laisser croire à lémergence dune conscience enfin lucide de linterdépendance entre systèmes naturels, économies, institutions, subjectivités, techniques et formes de vie. À première vue, le mot paraît répondre à une nécessité historique. Il semble désigner la prise en compte des limites, des vulnérabilités, des interdépendances et des irréversibilités qui traversent le monde contemporain. Pourtant, cette évidence apparente exige dêtre immédiatement troublée. Car la soutenabilité ne se borne pas à nommer une alerte ; elle en organise aussi le cadrage, en reformulant les contradictions du monde dans les termes dune mise en compatibilité administrable.
Sous son apparente neutralité, le lexique de la soutenabilité reconduit ainsi une opération plus profonde : il naturalise des conflits qui devraient être rendus politiquement disputables. Il transforme des antagonismes structurels en variables de régulation. Il traduit des incompatibilités de co-viabilité en déséquilibres paramétrables. Sous le langage de la préservation, il reconduit une entreprise de neutralisation. Ce qui, dans un autre vocabulaire, apparaîtrait comme extraction, dépossession, sacrifice différentiel, hiérarchisation des vies ou capture des capacités dagir, se trouve requalifié sous des catégories plus lisses : résilience, adaptation, transition, compensation, gouvernance, développement soutenable. Le vocabulaire change ; la conflictualité se dérobe.

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,10 @@ const {
</EditionLayout>
<style is:global>
/* =========================================================
FICHES GLOSSAIRE — état normal
========================================================= */
body[data-edition-key="glossaire"][data-sticky-mode="glossary-entry"]{
--entry-hero-pad-top: 18px;
--entry-hero-pad-x: 18px;
@@ -58,38 +62,82 @@ const {
--entry-hero-meta-opacity: 0;
}
/* =========================================================
PORTAILS GLOSSAIRE — socle premium desktop
========================================================= */
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]{
--portal-hero-pad-top: 18px;
/* hero : état plein */
--portal-hero-margin-bottom: 28px;
--portal-hero-pad-top: 20px;
--portal-hero-pad-x: 18px;
--portal-hero-pad-bottom: 20px;
--portal-hero-gap: 14px;
--portal-hero-pad-bottom: 22px;
--portal-hero-gap: 16px;
--portal-hero-h1-size: clamp(2.2rem, 4vw, 3.15rem);
--portal-kicker-size: 12px;
--portal-kicker-lh: 1.2;
--portal-kicker-spacing: .14em;
--portal-hero-intro-size: 1.04rem;
--portal-hero-intro-lh: 1.55;
--portal-hero-intro-maxw: 76ch;
--portal-hero-h1-size: clamp(3rem, 4.8vw, 4.15rem);
--portal-hero-h1-lh: .98;
--portal-hero-h1-spacing: -.045em;
--portal-hero-intro-size: 1.06rem;
--portal-hero-intro-lh: 1.6;
--portal-hero-intro-maxw: 70ch;
--portal-hero-follow-intro-max-w: 62ch;
--portal-hero-secondary-max-h: 20em;
--portal-hero-secondary-opacity: .94;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-follow-on{
--portal-hero-pad-top: 12px;
--portal-hero-pad-x: 16px;
--portal-hero-pad-bottom: 14px;
--portal-hero-gap: 8px;
--portal-hero-h1-size: clamp(1.95rem, 3.3vw, 2.6rem);
--portal-hero-intro-size: .98rem;
--portal-hero-intro-lh: 1.46;
--portal-hero-intro-maxw: 68ch;
--portal-hero-secondary-max-h: 4.6em;
--portal-hero-secondary-opacity: .82;
--portal-hero-secondary-opacity: .92;
/* hero : état condensé */
--portal-hero-pad-top-condensed: 14px;
--portal-hero-pad-x-condensed: 16px;
--portal-hero-pad-bottom-condensed: 16px;
--portal-hero-gap-condensed: 10px;
--portal-hero-h1-size-condensed: clamp(2.05rem, 3.15vw, 2.7rem);
--portal-hero-h1-lh-condensed: 1;
--portal-hero-h1-spacing-condensed: -.04em;
--portal-hero-intro-size-condensed: .98rem;
--portal-hero-intro-lh-condensed: 1.46;
/* rythme vertical */
--portal-page-pad-top: 8px;
--portal-page-pad-bottom: 24px;
--portal-block-gap: 20px;
--portal-grid-gap: 14px;
/* cartes / panels */
--portal-card-pad-y: 14px;
--portal-card-pad-x: 16px;
--portal-card-radius: 16px;
--portal-panel-pad-y: 16px;
--portal-panel-pad-x: 16px;
--portal-panel-radius: 18px;
--portal-focus-pad-y: 18px;
--portal-focus-pad-x: 20px;
--portal-focus-radius: 18px;
/* typo locale */
--portal-body-size: 1rem;
--portal-body-lh: 1.55;
--portal-card-title-size: 15px;
--portal-card-text-size: 14px;
--portal-card-text-lh: 1.45;
--portal-card-meta-size: 12px;
--portal-local-h3-size: clamp(1.35rem, 2vw, 1.7rem);
--portal-local-h3-lh: 1.15;
}
/* transition commune */
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"] .scene-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"] .glossary-portal-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"] .glossary-page-hero{
@@ -97,18 +145,298 @@ const {
border-radius 180ms ease,
padding 180ms ease,
row-gap 180ms ease,
margin-bottom 180ms ease;
margin-bottom 180ms ease,
box-shadow 180ms ease;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-follow-on .scene-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-follow-on .glossary-portal-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-follow-on .glossary-page-hero{
/* raccord premium hero + follow */
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-portal-follow-on .scene-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-portal-follow-on .glossary-portal-hero,
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-portal-follow-on .glossary-page-hero{
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-follow-on #reading-follow .reading-follow__inner{
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"].glossary-portal-follow-on #reading-follow .reading-follow__inner{
border-top-left-radius: 0;
border-top-right-radius: 0;
margin-top: -1px;
}
/* =========================================================
TABLETTE / INTERMÉDIAIRE
========================================================= */
@media (max-width: 980px){
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]{
--portal-hero-margin-bottom: 22px;
--portal-hero-pad-top: 18px;
--portal-hero-pad-x: 16px;
--portal-hero-pad-bottom: 18px;
--portal-hero-gap: 14px;
--portal-hero-h1-size: clamp(2.45rem, 4.4vw, 3.25rem);
--portal-hero-h1-lh: .99;
--portal-hero-h1-spacing: -.04em;
--portal-hero-intro-size: 1rem;
--portal-hero-intro-lh: 1.5;
--portal-hero-intro-maxw: 68ch;
--portal-hero-pad-top-condensed: 13px;
--portal-hero-pad-x-condensed: 14px;
--portal-hero-pad-bottom-condensed: 14px;
--portal-hero-gap-condensed: 9px;
--portal-hero-h1-size-condensed: clamp(1.88rem, 3vw, 2.35rem);
--portal-hero-h1-lh-condensed: 1;
--portal-hero-intro-size-condensed: .95rem;
--portal-hero-intro-lh-condensed: 1.42;
--portal-page-pad-top: 6px;
--portal-page-pad-bottom: 20px;
--portal-block-gap: 17px;
--portal-grid-gap: 11px;
--portal-card-pad-y: 13px;
--portal-card-pad-x: 14px;
--portal-card-radius: 15px;
--portal-panel-pad-y: 14px;
--portal-panel-pad-x: 14px;
--portal-panel-radius: 16px;
--portal-focus-pad-y: 16px;
--portal-focus-pad-x: 16px;
--portal-focus-radius: 16px;
--portal-body-size: .96rem;
--portal-body-lh: 1.46;
--portal-card-title-size: 14px;
--portal-card-text-size: 13px;
--portal-card-text-lh: 1.4;
--portal-card-meta-size: 11.5px;
--portal-local-h3-size: clamp(1.18rem, 2.2vw, 1.42rem);
--portal-local-h3-lh: 1.14;
}
}
/* =========================================================
MOBILE
========================================================= */
@media (max-width: 860px){
body[data-edition-key="glossaire"][data-sticky-mode="glossary-entry"]{
--entry-hero-pad-top: 12px;
--entry-hero-pad-x: 12px;
--entry-hero-pad-bottom: 12px;
--entry-hero-gap: 9px;
--entry-hero-h1-size: clamp(1.55rem, 7vw, 2rem);
--entry-hero-dek-size: .95rem;
--entry-hero-dek-lh: 1.42;
--entry-hero-dek-maxw: 100%;
--entry-hero-meta-max-h: 0px;
--entry-hero-meta-opacity: 0;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-entry"].glossary-entry-follow-on{
--entry-hero-pad-top: 8px;
--entry-hero-pad-x: 10px;
--entry-hero-pad-bottom: 8px;
--entry-hero-gap: 6px;
--entry-hero-h1-size: clamp(1.15rem, 5.2vw, 1.35rem);
--entry-hero-dek-size: .82rem;
--entry-hero-dek-lh: 1.25;
--entry-hero-dek-maxw: 100%;
--entry-hero-meta-max-h: 0px;
--entry-hero-meta-opacity: 0;
}
}
@media (max-width: 760px){
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]{
--portal-hero-margin-bottom: 18px;
--portal-hero-pad-top: 12px;
--portal-hero-pad-x: 12px;
--portal-hero-pad-bottom: 12px;
--portal-hero-gap: 8px;
--portal-kicker-size: 11px;
--portal-kicker-lh: 1.18;
--portal-kicker-spacing: .12em;
--portal-hero-h1-size: clamp(1.72rem, 7vw, 2.08rem);
--portal-hero-h1-lh: 1.01;
--portal-hero-h1-spacing: -.03em;
--portal-hero-intro-size: .95rem;
--portal-hero-intro-lh: 1.4;
--portal-hero-intro-maxw: 100%;
--portal-hero-follow-intro-max-w: 100%;
--portal-hero-secondary-max-h: none;
--portal-hero-secondary-opacity: 1;
/* valeurs condensées mobiles dédiées */
--portal-hero-pad-top-condensed: 10px;
--portal-hero-pad-x-condensed: 12px;
--portal-hero-pad-bottom-condensed: 10px;
--portal-hero-gap-condensed: 7px;
--portal-hero-h1-size-condensed: clamp(1.42rem, 5.8vw, 1.8rem);
--portal-hero-h1-lh-condensed: 1.02;
--portal-hero-h1-spacing-condensed: -.028em;
--portal-hero-intro-size-condensed: .88rem;
--portal-hero-intro-lh-condensed: 1.3;
--portal-page-pad-top: 4px;
--portal-page-pad-bottom: 16px;
--portal-block-gap: 14px;
--portal-grid-gap: 9px;
--portal-card-pad-y: 12px;
--portal-card-pad-x: 12px;
--portal-card-radius: 14px;
--portal-panel-pad-y: 12px;
--portal-panel-pad-x: 12px;
--portal-panel-radius: 14px;
--portal-focus-pad-y: 13px;
--portal-focus-pad-x: 13px;
--portal-focus-radius: 14px;
--portal-body-size: .9rem;
--portal-body-lh: 1.34;
--portal-card-title-size: 13.5px;
--portal-card-text-size: 12.5px;
--portal-card-text-lh: 1.34;
--portal-card-meta-size: 11px;
--portal-local-h3-size: clamp(1.02rem, 4.8vw, 1.2rem);
--portal-local-h3-lh: 1.12;
}
}
@media (max-width: 520px){
body[data-edition-key="glossaire"][data-sticky-mode="glossary-entry"]{
--entry-hero-pad-top: 10px;
--entry-hero-pad-x: 10px;
--entry-hero-pad-bottom: 10px;
--entry-hero-gap: 8px;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-entry"].glossary-entry-follow-on{
--entry-hero-pad-top: 7px;
--entry-hero-pad-x: 8px;
--entry-hero-pad-bottom: 7px;
--entry-hero-gap: 5px;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]{
--portal-hero-margin-bottom: 16px;
--portal-hero-pad-top: 10px;
--portal-hero-pad-x: 10px;
--portal-hero-pad-bottom: 10px;
--portal-hero-gap: 7px;
--portal-hero-pad-top-condensed: 8px;
--portal-hero-pad-x-condensed: 8px;
--portal-hero-pad-bottom-condensed: 8px;
--portal-hero-gap-condensed: 5px;
}
body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on #reading-follow .reading-follow__inner{
border-top-left-radius: 0;
border-top-right-radius: 0;
margin-top: -1px;
}
}
/* =========================================================
PAYSAGE COMPACT
========================================================= */
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
body[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]{
--portal-hero-margin-bottom: 12px;
--portal-hero-pad-top: 10px;
--portal-hero-pad-x: 10px;
--portal-hero-pad-bottom: 10px;
--portal-hero-gap: 6px;
--portal-kicker-size: 10px;
--portal-kicker-lh: 1.14;
--portal-kicker-spacing: .1em;
--portal-hero-h1-size: clamp(1.24rem, 4vw, 1.52rem);
--portal-hero-h1-lh: 1.02;
--portal-hero-h1-spacing: -.022em;
--portal-hero-intro-size: .82rem;
--portal-hero-intro-lh: 1.24;
--portal-hero-intro-maxw: 100%;
--portal-hero-follow-intro-max-w: 100%;
--portal-hero-secondary-max-h: none;
--portal-hero-secondary-opacity: 1;
--portal-hero-pad-top-condensed: 8px;
--portal-hero-pad-x-condensed: 10px;
--portal-hero-pad-bottom-condensed: 8px;
--portal-hero-gap-condensed: 5px;
--portal-hero-h1-size-condensed: clamp(1.08rem, 3.4vw, 1.28rem);
--portal-hero-h1-lh-condensed: 1.02;
--portal-hero-h1-spacing-condensed: -.018em;
--portal-hero-intro-size-condensed: .76rem;
--portal-hero-intro-lh-condensed: 1.18;
--portal-page-pad-top: 2px;
--portal-page-pad-bottom: 12px;
--portal-block-gap: 10px;
--portal-grid-gap: 8px;
--portal-card-pad-y: 10px;
--portal-card-pad-x: 10px;
--portal-card-radius: 12px;
--portal-panel-pad-y: 10px;
--portal-panel-pad-x: 10px;
--portal-panel-radius: 12px;
--portal-focus-pad-y: 10px;
--portal-focus-pad-x: 10px;
--portal-focus-radius: 12px;
--portal-body-size: .82rem;
--portal-body-lh: 1.24;
--portal-card-title-size: 12.5px;
--portal-card-text-size: 11.5px;
--portal-card-text-lh: 1.24;
--portal-card-meta-size: 10.5px;
--portal-local-h3-size: clamp(.96rem, 3.2vw, 1.08rem);
--portal-local-h3-lh: 1.1;
}
}
</style>

View File

@@ -219,6 +219,80 @@ const prolongerLinks = [
heroMoreId="archi-hero-more"
heroToggleId="archi-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
@@ -278,4 +352,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.archi-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.archi-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -91,7 +91,7 @@ const pageItems = [
{ href: "#six-concepts", label: "Les six concepts cardinaux" },
{ href: "#distinctions-decisives", label: "Distinctions décisives" },
{ href: "#ordre-lecture", label: "Ordre conseillé de lecture" },
{ href: "#prolonger-lecture", label: "Prolonger la lecture" },
{ href: "#prolonger-la-lecture", label: "Prolonger la lecture" },
];
const usefulLinks = [
@@ -333,22 +333,36 @@ const prolongerLinks = [
<style>
.cf-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.cf-page,
.cf-map,
.cf-map__stage,
.cf-map__roots,
.cf-cards,
.cf-comparisons,
.cf-steps,
.cf-card,
.cf-step{
min-width: 0;
}
.cf-map{
display: grid;
justify-items: center;
gap: 10px;
margin-top: 14px;
padding: 16px 18px 18px;
border: 1px solid rgba(127,127,127,0.22);
border-radius: 18px;
background: rgba(127,127,127,0.05);
gap: var(--portal-block-gap, 18px);
margin-top: 12px;
padding:
var(--portal-focus-pad-y, 18px)
var(--portal-focus-pad-x, 20px);
border: 1px solid rgba(127,127,127,0.20);
border-radius: var(--portal-focus-radius, 18px);
background: rgba(127,127,127,0.04);
}
.cf-map__stage{
width: min(580px, 100%);
width: min(610px, 100%);
display: grid;
justify-items: center;
gap: 10px;
@@ -357,41 +371,47 @@ const prolongerLinks = [
.cf-map__title{
width: 100%;
text-align: center;
font-size: 1.02rem;
line-height: 1.25;
font-weight: 800;
letter-spacing: -.01em;
font-size: clamp(1rem, 1.35vw, 1.12rem);
line-height: 1.2;
font-weight: 790;
letter-spacing: -.012em;
opacity: .96;
text-wrap: balance;
}
.cf-map__roots{
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
gap: var(--portal-grid-gap, 12px);
}
.cf-node{
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 48px;
min-height: 50px;
padding: 10px 14px;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 999px;
background: rgba(127,127,127,0.05);
color: var(--glossary-accent, #00d9ff);
text-decoration: none;
text-align: center;
font-size: 13px;
font-weight: 800;
letter-spacing: .05em;
line-height: 1.2;
transition: transform 120ms ease, background 120ms ease;
line-height: 1.18;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease;
}
.cf-node:hover{
transform: translateY(-1px);
background: rgba(127,127,127,0.08);
border-color: rgba(0,217,255,0.18);
text-decoration: none;
}
@@ -401,29 +421,34 @@ const prolongerLinks = [
}
.cf-map__arrow{
font-size: 18px;
font-size: 1.45rem;
line-height: 1;
opacity: .65;
opacity: .68;
}
.cf-cards,
.cf-comparisons{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
margin-top: 14px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: var(--portal-grid-gap, 12px);
margin-top: 12px;
}
.cf-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding:
var(--portal-card-pad-y, 14px)
var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-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;
}
.cf-card:hover{
@@ -434,20 +459,21 @@ const prolongerLinks = [
}
.cf-card strong{
font-size: 15px;
line-height: 1.3;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.26;
color: var(--glossary-accent, #00d9ff);
}
.cf-card span{
font-size: 14px;
line-height: 1.45;
opacity: .92;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .93;
}
.cf-card small{
font-size: 12px;
line-height: 1.4;
opacity: .72;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.35;
opacity: .74;
}
.cf-card--text{
@@ -461,7 +487,7 @@ const prolongerLinks = [
.cf-steps{
display: grid;
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.cf-step{
@@ -469,9 +495,11 @@ const prolongerLinks = [
grid-template-columns: 64px minmax(0, 1fr);
gap: 14px;
align-items: start;
padding: 14px 16px;
padding:
var(--portal-panel-pad-y, 16px)
var(--portal-panel-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-panel-radius, 18px);
background: rgba(127,127,127,0.05);
}
@@ -480,6 +508,7 @@ const prolongerLinks = [
align-items: center;
justify-content: center;
min-height: 44px;
min-width: 44px;
border: 1px solid rgba(127,127,127,0.28);
border-radius: 999px;
font-size: 13px;
@@ -489,29 +518,224 @@ const prolongerLinks = [
.cf-step__body h3{
margin: 0;
font-size: 15px;
line-height: 1.3;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.28;
}
.cf-step__body p{
margin: 8px 0 0;
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
@media (max-width: 720px){
@media (max-width: 980px){
.cf-map{
margin-top: 10px;
}
.cf-map__stage{
width: 100%;
gap: 9px;
}
.cf-map__title{
font-size: 1rem;
line-height: 1.18;
}
.cf-node{
min-height: 46px;
font-size: 12.5px;
line-height: 1.16;
}
.cf-cards,
.cf-comparisons{
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
}
@media (max-width: 760px){
.cf-page{
padding-top: 2px;
}
.cf-map{
gap: 12px;
margin-top: 10px;
padding: 13px 13px 14px;
border-radius: 14px;
}
.cf-map__stage{
gap: 7px;
}
.cf-map__title{
font-size: .9rem;
line-height: 1.16;
}
.cf-map__roots{
grid-template-columns: 1fr;
gap: 8px;
}
.cf-node{
min-height: 40px;
padding: 8px 10px;
font-size: .83rem;
line-height: 1.12;
letter-spacing: .04em;
}
.cf-map__arrow{
font-size: 1rem;
opacity: .62;
}
.cf-cards,
.cf-comparisons{
grid-template-columns: 1fr;
gap: 9px;
margin-top: 10px;
}
.cf-card{
gap: 6px;
padding: 12px 12px;
border-radius: 14px;
}
.cf-card strong{
font-size: 13.5px;
line-height: 1.22;
}
.cf-card span{
font-size: 12.5px;
line-height: 1.34;
}
.cf-steps{
gap: 9px;
margin-top: 10px;
}
.cf-step{
grid-template-columns: 1fr;
gap: 10px;
padding: 12px 12px;
border-radius: 14px;
}
.cf-step__num{
width: fit-content;
min-width: 64px;
min-width: 58px;
min-height: 36px;
font-size: 12px;
}
.cf-step__body h3{
font-size: 13.5px;
line-height: 1.22;
}
.cf-step__body p{
margin-top: 6px;
font-size: 12.5px;
line-height: 1.34;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.cf-page{
padding-top: 0;
}
.cf-map{
gap: 8px;
margin-top: 8px;
padding: 10px 10px 12px;
border-radius: 12px;
}
.cf-map__stage{
gap: 5px;
}
.cf-map__title{
font-size: .8rem;
line-height: 1.12;
}
.cf-map__roots{
grid-template-columns: 1fr;
gap: 6px;
}
.cf-node{
min-height: 32px;
padding: 6px 8px;
font-size: .74rem;
line-height: 1.08;
}
.cf-map__arrow{
font-size: .92rem;
}
.cf-cards,
.cf-comparisons{
grid-template-columns: 1fr;
gap: 8px;
margin-top: 8px;
}
.cf-card{
gap: 5px;
padding: 9px 10px;
border-radius: 12px;
}
.cf-card strong{
font-size: 12.5px;
line-height: 1.18;
}
.cf-card span{
font-size: 11.5px;
line-height: 1.24;
}
.cf-steps{
gap: 8px;
margin-top: 8px;
}
.cf-step{
grid-template-columns: 1fr;
gap: 8px;
padding: 9px 10px;
border-radius: 12px;
}
.cf-step__num{
min-width: 52px;
min-height: 30px;
font-size: 11px;
}
.cf-step__body h3{
font-size: 12.5px;
line-height: 1.18;
}
.cf-step__body p{
margin-top: 5px;
font-size: 11.5px;
line-height: 1.22;
}
}

View File

@@ -336,11 +336,84 @@ const prolongerLinks = [
heroMoreId="dyna-hero-more"
heroToggleId="dyna-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.dyna-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.dyna-focus-grid{
@@ -351,9 +424,9 @@ const prolongerLinks = [
}
.dyna-focus-card{
padding: 18px 20px;
padding: var(--portal-focus-pad-y, 18px) var(--portal-focus-pad-x, 20px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 18px;
border-radius: var(--portal-focus-radius, 18px);
background: rgba(127,127,127,0.05);
}
@@ -368,8 +441,8 @@ const prolongerLinks = [
.dyna-focus-card h3{
margin: 0 0 10px;
font-size: clamp(1.35rem, 2vw, 1.7rem);
line-height: 1.15;
font-size: var(--portal-local-h3-size, clamp(1.35rem, 2vw, 1.7rem));
line-height: var(--portal-local-h3-lh, 1.15);
}
.dyna-focus-card h3 a{
@@ -410,18 +483,18 @@ const prolongerLinks = [
.dyna-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.dyna-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
text-decoration: none;
transition:
@@ -438,18 +511,18 @@ const prolongerLinks = [
}
.dyna-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.dyna-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
.dyna-card small{
font-size: 12px;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.4;
opacity: .72;
}
@@ -478,4 +551,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.dyna-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.dyna-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -252,6 +252,9 @@ const prolongerLinks = [
const LETTERS_DOCKED_CLASS = "gic-letters-docked";
const ACTIVE_CLASS = "is-active";
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
const EXTRA_GAP = 12;
const MAX_CORRECTION_PASSES = 8;
@@ -262,8 +265,30 @@ const prolongerLinks = [
body.classList.add(BODY_CLASS);
const forceHideGlobalFollowOnCompactViewport = () => {
if (!isCompactViewport()) {
follow.style.display = "";
return;
}
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
setAnchorOffset(0);
};
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const computeFollowOn = () =>
!mqMobile.matches &&
!isCompactViewport() &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
@@ -475,6 +500,7 @@ const prolongerLinks = [
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
forceHideGlobalFollowOnCompactViewport();
syncFollowLettersTop();
syncLettersDockState();
syncActiveLetter();
@@ -507,10 +533,10 @@ const prolongerLinks = [
document.fonts.ready.then(schedule).catch(() => {});
}
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", schedule);
} else if (mqMobile.addListener) {
mqMobile.addListener(schedule);
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", schedule);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(schedule);
}
if (reducedMotion.addEventListener) {
@@ -520,6 +546,7 @@ const prolongerLinks = [
}
setAnchorOffset(0);
forceHideGlobalFollowOnCompactViewport();
schedule();
if (window.location.hash.startsWith("#letter-")) {
@@ -543,68 +570,69 @@ const prolongerLinks = [
<style>
.gic-page{
--gic-follow-letters-offset: 0px;
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.gic-aside-stack{
display: flex;
flex-direction: column;
gap: 14px;
gap: 12px;
}
.gic-aside__block{
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
padding: 12px;
border-radius: 15px;
padding: 11px 12px;
background: rgba(127,127,127,0.05);
}
.gic-aside__heading{
margin: 0 0 10px;
font-size: 13px;
margin: 0 0 8px;
font-size: 13.5px;
line-height: 1.25;
font-weight: 800;
opacity: .9;
opacity: .92;
}
.gic-aside__pills{
display: flex;
flex-wrap: wrap;
gap: 6px;
gap: 5px;
}
.gic-aside__pill{
display: inline-flex;
align-items: center;
padding: 4px 9px;
padding: 3px 8px;
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;
font-size: 11.5px;
line-height: 1.25;
opacity: .9;
}
.gic-aside__note{
margin: 10px 0 0;
font-size: 12px;
line-height: 1.45;
opacity: .78;
margin: 8px 0 0;
font-size: 11.5px;
line-height: 1.4;
opacity: .8;
}
.gic-letters{
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 14px;
gap: 7px;
margin-top: 12px;
}
.gic-letters a,
.gic-follow-letters a{
min-width: 34px;
min-width: 32px;
text-align: center;
border: 1px solid rgba(127,127,127,0.24);
border-radius: 10px;
padding: 5px 8px;
border-radius: 9px;
padding: 4px 7px;
text-decoration: none;
transition:
transform 120ms ease,
@@ -644,15 +672,15 @@ const prolongerLinks = [
z-index: 59;
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 8px 12px 10px;
gap: 7px;
padding: 7px 10px 9px;
border: 1px solid rgba(127,127,127,.20);
border-top: 0;
border-radius: 0 0 14px 14px;
border-radius: 0 0 12px 12px;
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);
box-shadow: 0 8px 18px rgba(0,0,0,.06);
opacity: 0;
transform: translateY(-6px);
pointer-events: none;
@@ -673,7 +701,7 @@ const prolongerLinks = [
.gic-groups{
display: flex;
flex-direction: column;
gap: 28px;
gap: 22px;
}
.gic-group{
@@ -683,18 +711,18 @@ const prolongerLinks = [
}
.gic-section{
margin-top: 34px;
margin-top: 28px;
}
.gic-section__head{
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 10px;
margin-bottom: 8px;
scroll-margin-top: calc(
var(--sticky-offset-px, 96px) + 28px + var(--gic-follow-letters-offset, 0px)
var(--sticky-offset-px, 96px) + 24px + var(--gic-follow-letters-offset, 0px)
);
}
@@ -713,60 +741,61 @@ const prolongerLinks = [
.gic-list{
display: grid;
gap: 12px;
gap: 10px;
}
.gic-item{
border: 1px solid rgba(127,127,127,0.20);
border-radius: 16px;
padding: 14px 16px;
border-radius: 15px;
padding: 13px 14px;
background: rgba(127,127,127,0.04);
}
.gic-term{
display: inline-block;
font-weight: 800;
font-size: 1.04rem;
line-height: 1.3;
font-size: 1rem;
line-height: 1.28;
text-decoration: none;
margin-bottom: 6px;
margin-bottom: 5px;
}
.gic-def{
margin: 0 0 8px;
line-height: 1.5;
margin: 0 0 7px;
font-size: 13.5px;
line-height: 1.46;
opacity: .94;
}
.gic-meta{
display: flex;
flex-wrap: wrap;
gap: 8px;
gap: 6px;
margin: 0;
font-size: 12px;
font-size: 11.5px;
opacity: .78;
}
.gic-meta span{
border: 1px solid rgba(127,127,127,0.20);
border-radius: 999px;
padding: 2px 8px;
padding: 2px 7px;
}
.gic-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
margin-top: 14px;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--portal-grid-gap, 12px);
margin-top: 12px;
}
.gic-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
text-decoration: none;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
@@ -780,13 +809,13 @@ const prolongerLinks = [
}
.gic-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.gic-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
@@ -794,6 +823,160 @@ const prolongerLinks = [
.gic-follow-letters{
display: none !important;
}
.gic-aside-stack{
gap: 10px;
}
.gic-aside__block{
border-radius: 14px;
padding: 10px 11px;
}
.gic-aside__heading{
margin-bottom: 7px;
font-size: 13px;
}
.gic-aside__pill{
padding: 3px 7px;
font-size: 11px;
}
.gic-aside__note{
font-size: 11px;
line-height: 1.34;
}
.gic-letters{
gap: 6px;
margin-top: 10px;
}
.gic-letters a{
min-width: 30px;
padding: 4px 6px;
border-radius: 8px;
font-size: 12px;
}
.gic-groups{
gap: 18px;
}
.gic-section{
margin-top: 22px;
}
.gic-item{
border-radius: 14px;
padding: 12px 12px;
}
.gic-term{
font-size: .96rem;
}
.gic-def{
font-size: 13px;
line-height: 1.4;
}
.gic-meta{
gap: 5px;
font-size: 11px;
}
.gic-meta span{
padding: 2px 6px;
}
.gic-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.gic-follow-letters{
display: none !important;
}
.gic-aside-stack{
gap: 8px;
}
.gic-aside__block{
border-radius: 13px;
padding: 9px 10px;
}
.gic-aside__heading{
margin-bottom: 6px;
font-size: 12.5px;
}
.gic-aside__pill{
padding: 2px 7px;
font-size: 10.5px;
}
.gic-aside__note{
font-size: 10.5px;
line-height: 1.3;
}
.gic-letters{
gap: 5px;
margin-top: 9px;
}
.gic-letters a{
min-width: 28px;
padding: 3px 6px;
border-radius: 8px;
font-size: 11.5px;
}
.gic-groups{
gap: 16px;
}
.gic-section{
margin-top: 18px;
}
.gic-section__head{
margin-bottom: 6px;
}
.gic-item{
border-radius: 13px;
padding: 10px 11px;
}
.gic-term{
font-size: .93rem;
margin-bottom: 4px;
}
.gic-def{
margin-bottom: 6px;
font-size: 12.5px;
line-height: 1.34;
}
.gic-meta{
gap: 4px;
font-size: 10.5px;
}
.gic-meta span{
padding: 1px 6px;
}
.gic-cards{
grid-template-columns: 1fr;
}
}
@media (prefers-color-scheme: dark){
@@ -824,4 +1007,38 @@ const prolongerLinks = [
rgba(255,255,255,0.06);
}
}
:global(body.is-index-complet-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-index-complet-page #reading-follow),
:global(body.is-index-complet-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-index-complet-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-index-complet-page #reading-follow),
:global(body.is-index-complet-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-index-complet-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -286,151 +286,198 @@ const approfondirPortalItems = [
</section>
<script is:inline>
(() => {
const header = document.querySelector("header");
const hero = document.getElementById("glossary-hero");
const follow = document.getElementById("glossary-hero-follow");
const headings = Array.from(document.querySelectorAll("[data-follow-section]"));
(() => {
const header = document.querySelector("header");
const hero = document.getElementById("glossary-hero");
const follow = document.getElementById("glossary-hero-follow");
const intro = document.getElementById("glossary-hero-intro");
const toggle = document.getElementById("glossary-hero-toggle");
const headings = Array.from(document.querySelectorAll("[data-follow-section]"));
if (!header || !hero || !follow || headings.length === 0) return;
if (!header || !hero || !follow || !intro || !toggle || headings.length === 0) return;
let raf = 0;
let activeHeading = null;
let clearTimer = 0;
let raf = 0;
let activeHeading = null;
let clearTimer = 0;
function syncStickyTop() {
const headerHeight = header.getBoundingClientRect().height || 0;
document.documentElement.style.setProperty(
"--glossary-sticky-top",
`${Math.round(headerHeight + 8)}px`
);
}
function syncStickyTop() {
const headerHeight = header.getBoundingClientRect().height || 0;
document.documentElement.style.setProperty(
"--glossary-sticky-top",
`${Math.round(headerHeight + 8)}px`
);
}
function applyHeadingMetrics(fromEl, toEl) {
const cs = window.getComputedStyle(fromEl);
function applyHeadingMetrics(fromEl, toEl) {
const cs = window.getComputedStyle(fromEl);
const sourceFontSize = Number.parseFloat(cs.fontSize) || 40;
const sourceLineHeight =
Number.parseFloat(cs.lineHeight) ||
Math.round(sourceFontSize * 1.06 * 100) / 100;
const sourceFontSize = Number.parseFloat(cs.fontSize) || 40;
const sourceLineHeight =
Number.parseFloat(cs.lineHeight) ||
Math.round(sourceFontSize * 1.06 * 100) / 100;
const scaledFontSize = Math.max(28, sourceFontSize * 0.9);
const scaledLineHeight = Math.max(scaledFontSize * 1.04, sourceLineHeight * 0.92);
const scaledFontSize = Math.max(28, sourceFontSize * 0.9);
const scaledLineHeight = Math.max(scaledFontSize * 1.04, sourceLineHeight * 0.92);
toEl.style.fontSize = `${scaledFontSize}px`;
toEl.style.lineHeight = `${scaledLineHeight}px`;
toEl.style.fontWeight = cs.fontWeight;
toEl.style.letterSpacing = cs.letterSpacing;
toEl.style.fontFamily = cs.fontFamily;
toEl.style.fontSize = `${scaledFontSize}px`;
toEl.style.lineHeight = `${scaledLineHeight}px`;
toEl.style.fontWeight = cs.fontWeight;
toEl.style.letterSpacing = cs.letterSpacing;
toEl.style.fontFamily = cs.fontFamily;
document.documentElement.style.setProperty(
"--glossary-follow-height",
`${Math.ceil(scaledLineHeight)}px`
);
}
document.documentElement.style.setProperty(
"--glossary-follow-height",
`${Math.ceil(scaledLineHeight)}px`
);
}
function getCurrentHeading() {
const heroRect = hero.getBoundingClientRect();
let candidate = null;
function getCurrentHeading() {
const heroRect = hero.getBoundingClientRect();
const heroBottom = heroRect.bottom;
let candidate = null;
for (const heading of headings) {
const rect = heading.getBoundingClientRect();
const trigger = heroRect.bottom - Math.min(rect.height * 0.42, 18);
for (const heading of headings) {
const rect = heading.getBoundingClientRect();
const trigger =
heroBottom - Math.min(Math.max(rect.height * 0.55, 18), 34);
if (rect.top <= trigger) {
candidate = heading;
} else {
break;
}
}
return candidate;
}
function hideFollow() {
if (!follow.classList.contains("is-visible")) return;
follow.classList.remove("is-visible");
follow.setAttribute("aria-hidden", "true");
window.clearTimeout(clearTimer);
clearTimer = window.setTimeout(() => {
if (!follow.classList.contains("is-visible")) {
follow.textContent = "";
}
}, 260);
}
function showFollow(heading) {
const nextText = (heading.dataset.followSection || heading.textContent || "").trim();
if (!nextText) {
hideFollow();
return;
}
if (activeHeading !== heading) {
activeHeading = heading;
follow.textContent = nextText;
applyHeadingMetrics(heading, follow);
}
window.clearTimeout(clearTimer);
if (!follow.classList.contains("is-visible")) {
requestAnimationFrame(() => {
follow.classList.add("is-visible");
follow.setAttribute("aria-hidden", "false");
});
if (rect.top <= trigger) {
candidate = heading;
} else {
break;
}
}
return candidate;
}
function hideFollow() {
if (!follow.classList.contains("is-visible")) return;
follow.classList.remove("is-visible");
follow.setAttribute("aria-hidden", "true");
window.clearTimeout(clearTimer);
clearTimer = window.setTimeout(() => {
if (!follow.classList.contains("is-visible")) {
follow.textContent = "";
}
}, 260);
}
function showFollow(heading) {
const nextText = (heading.dataset.followSection || heading.textContent || "").trim();
if (!nextText) {
hideFollow();
return;
}
if (activeHeading !== heading) {
activeHeading = heading;
follow.textContent = nextText;
applyHeadingMetrics(heading, follow);
}
window.clearTimeout(clearTimer);
if (!follow.classList.contains("is-visible")) {
requestAnimationFrame(() => {
follow.classList.add("is-visible");
follow.setAttribute("aria-hidden", "false");
}
}
function updateFollow() {
syncStickyTop();
const active = getCurrentHeading();
if (!active) {
activeHeading = null;
hideFollow();
return;
}
const heroRect = hero.getBoundingClientRect();
const activeRect = active.getBoundingClientRect();
const showThreshold = heroRect.bottom - Math.min(activeRect.height * 0.34, 14);
const shouldShow = activeRect.top <= showThreshold;
if (!shouldShow) {
activeHeading = null;
hideFollow();
return;
}
showFollow(active);
}
function schedule() {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
updateFollow();
});
} else {
follow.setAttribute("aria-hidden", "false");
}
}
function collapseIntro() {
if (!document.body.classList.contains("glossary-home-follow-on")) return;
if (document.body.classList.contains("glossary-home-hero-expanded")) return;
intro.setAttribute("aria-hidden", "true");
toggle.hidden = false;
toggle.setAttribute("aria-expanded", "false");
}
function expandIntro() {
document.body.classList.add("glossary-home-hero-expanded");
intro.setAttribute("aria-hidden", "false");
toggle.hidden = true;
toggle.setAttribute("aria-expanded", "true");
}
function resetIntro() {
document.body.classList.remove("glossary-home-hero-expanded");
intro.setAttribute("aria-hidden", "false");
toggle.hidden = true;
toggle.setAttribute("aria-expanded", "false");
}
function updateFollow() {
syncStickyTop();
const heroRect = hero.getBoundingClientRect();
const active = getCurrentHeading();
const stickyTop =
parseFloat(
getComputedStyle(document.documentElement)
.getPropertyValue("--glossary-sticky-top")
) || 64;
const hasStartedScrolling = (window.scrollY || window.pageYOffset || 0) > 8;
const heroDocked = Math.abs(heroRect.top - stickyTop) <= 6;
const heroOut = hasStartedScrolling && heroDocked;
document.body.classList.toggle("glossary-home-follow-on", heroOut);
if (!active) {
activeHeading = null;
hideFollow();
resetIntro();
return;
}
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
const activeRect = active.getBoundingClientRect();
const showThreshold =
heroRect.bottom - Math.min(Math.max(activeRect.height * 0.58, 18), 34);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
const shouldShow = heroOut && activeRect.top <= showThreshold;
if (!shouldShow) {
activeHeading = null;
hideFollow();
resetIntro();
return;
}
schedule();
})();
</script>
collapseIntro();
showFollow(active);
}
<style>
function schedule() {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
updateFollow();
});
}
toggle.addEventListener("click", expandIntro);
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
schedule();
})();
</script>
<style>
:root{
--glossary-accent: #00d9ff;
--glossary-bg-soft: rgba(127,127,127,0.05);
@@ -441,22 +488,32 @@ const approfondirPortalItems = [
--glossary-follow-height: 2.5rem;
}
.glossary-home-shell__main,
.glossary-home-shell__aside{
grid-column: auto;
.glossary-home{
min-width: 0;
overflow-x: clip;
}
.glossary-home-shell__aside-inner{
position: static;
.glossary-home > *{
min-width: 0;
}
.glossary-map-block,
.glossary-section,
.glossary-map,
.glossary-map__stage,
.glossary-map__roots,
.glossary-map__node{
min-width: 0;
}
.glossary-map-block__head h2,
.glossary-section h2{
margin: 0;
font-size: clamp(2rem, 3vw, 2.55rem);
font-size: clamp(1.8rem, 3vw, 2.55rem);
line-height: 1.06;
letter-spacing: -.03em;
font-weight: 800;
text-wrap: balance;
}
.glossary-map-block{
@@ -472,6 +529,7 @@ const approfondirPortalItems = [
font-size: 1rem;
line-height: 1.55;
opacity: .94;
text-wrap: pretty;
}
.glossary-map{
@@ -496,6 +554,7 @@ const approfondirPortalItems = [
font-weight: 800;
letter-spacing: -.01em;
opacity: .96;
text-wrap: balance;
}
.glossary-map__roots{
@@ -520,7 +579,11 @@ const approfondirPortalItems = [
font-size: .99rem;
font-weight: 800;
letter-spacing: .04em;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
line-height: 1.2;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease;
}
.glossary-map__node:hover{
@@ -562,12 +625,33 @@ const approfondirPortalItems = [
}
@media (max-width: 980px){
.glossary-home-shell{
grid-template-columns: 1fr;
.glossary-map-block{
padding: 16px 16px 18px;
border-radius: 20px;
}
.glossary-home-shell__aside-inner{
position: static;
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.8rem, 5vw, 2.3rem);
line-height: 1.04;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .96rem;
line-height: 1.44;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
grid-template-columns: 1fr;
gap: 10px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 13px 14px;
border-radius: 15px;
}
}
@@ -577,18 +661,133 @@ const approfondirPortalItems = [
padding: 12px 14px 16px;
}
.glossary-map__roots{
grid-template-columns: 1fr;
.glossary-map-block{
padding: 16px 16px 18px;
border-radius: 20px;
}
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.5rem, 7vw, 1.95rem);
line-height: 1.04;
letter-spacing: -.022em;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .9rem;
line-height: 1.34;
}
.glossary-section__head{
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.glossary-cta{
width: fit-content;
}
.glossary-map{
gap: 7px;
margin-top: 12px;
}
.glossary-map__stage{
gap: 7px;
width: 100%;
}
.glossary-map__title{
font-size: .9rem;
line-height: 1.2;
}
.glossary-map__roots{
grid-template-columns: 1fr;
gap: 6px;
}
.glossary-map__node{
min-height: 38px;
padding: 8px 10px;
font-size: .84rem;
line-height: 1.15;
}
.glossary-map__arrow{
font-size: 1rem;
opacity: .62;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-map-block{
padding: 10px 10px 12px;
border-radius: 14px;
}
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.2rem, 3.8vw, 1.55rem);
line-height: 1.02;
text-wrap: pretty;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .82rem;
line-height: 1.24;
}
.glossary-section{
margin-top: 24px;
}
.glossary-section__head{
gap: 10px;
margin-bottom: 10px;
}
.glossary-map{
gap: 5px;
margin-top: 10px;
}
.glossary-map__stage{
gap: 5px;
}
.glossary-map__title{
font-size: .8rem;
line-height: 1.12;
}
.glossary-map__node{
min-height: 32px;
padding: 6px 8px;
font-size: .74rem;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 10px 11px;
border-radius: 12px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .9rem;
line-height: 1.2;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span,
.glossary-home .glossary-portal-card small{
font-size: .8rem;
line-height: 1.22;
}
}
@media (prefers-color-scheme: dark){
@@ -605,6 +804,112 @@ const approfondirPortalItems = [
.glossary-cta:hover{
background: rgba(255,255,255,0.07);
}
}
/* =========================================================
LOT 17.A.5 — Recalage follow + densité mobile finale
========================================================= */
.glossary-home{
min-width: 0;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
min-width: 0;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
min-width: 0;
}
@media (max-width: 760px){
.glossary-section{
margin-top: 30px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 108px);
}
.glossary-section__head{
gap: 10px;
margin-bottom: 10px;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
gap: 9px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 12px 13px;
border-radius: 14px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .98rem;
line-height: 1.2;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span{
font-size: .92rem;
line-height: 1.36;
}
.glossary-home .glossary-portal-card small{
font-size: .82rem;
line-height: 1.2;
}
.glossary-cta{
min-height: 36px;
padding: 6px 12px;
font-size: .92rem;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.glossary-section{
margin-top: 20px;
scroll-margin-top: calc(var(--glossary-sticky-top) + 84px);
}
.glossary-section__head{
gap: 8px;
margin-bottom: 8px;
}
.glossary-home .glossary-cards,
.glossary-home .glossary-portals{
gap: 8px;
}
.glossary-home .glossary-card,
.glossary-home .glossary-portal-card{
padding: 9px 10px;
border-radius: 12px;
}
.glossary-home .glossary-card strong,
.glossary-home .glossary-portal-card strong{
font-size: .86rem;
line-height: 1.14;
}
.glossary-home .glossary-card span,
.glossary-home .glossary-portal-card span,
.glossary-home .glossary-portal-card small{
font-size: .76rem;
line-height: 1.16;
}
.glossary-cta{
min-height: 30px;
padding: 4px 10px;
font-size: .8rem;
}
}
</style>
</GlossaryLayout>

View File

@@ -663,18 +663,91 @@ const usefulLinks = [
heroMoreId="pa-hero-more"
heroToggleId="pa-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.pa-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.pa-focus-card{
margin-top: 14px;
padding: 18px 20px;
.pa-focus-card{
margin-top: 12px;
padding: var(--portal-focus-pad-y, 18px) var(--portal-focus-pad-x, 20px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 18px;
border-radius: var(--portal-focus-radius, 18px);
background: rgba(127,127,127,0.05);
}
@@ -689,8 +762,8 @@ const usefulLinks = [
.pa-focus-card h3{
margin: 0 0 10px;
font-size: clamp(1.35rem, 2vw, 1.7rem);
line-height: 1.15;
font-size: var(--portal-local-h3-size, clamp(1.35rem, 2vw, 1.7rem));
line-height: var(--portal-local-h3-lh, 1.15);
}
.pa-focus-card h3 a{
@@ -722,14 +795,14 @@ const usefulLinks = [
}
.pa-block{
margin-top: 18px;
margin-top: 16px;
}
.pa-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
margin-top: 14px;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--portal-grid-gap, 12px);
margin-top: 12px;
}
.pa-card,
@@ -737,9 +810,9 @@ const usefulLinks = [
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
}
@@ -757,19 +830,19 @@ const usefulLinks = [
.pa-card strong,
.pa-note-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.pa-card span,
.pa-note-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
.pa-card small{
font-size: 12px;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.4;
opacity: .72;
}
@@ -782,14 +855,14 @@ const usefulLinks = [
.pa-theory-hub{
display: grid;
gap: 12px;
margin-top: 14px;
padding: 18px 20px;
gap: 10px;
margin-top: 12px;
padding: 16px 18px;
border: 1px solid rgba(127,127,127,0.20);
border-radius: 22px;
border-radius: 20px;
background:
linear-gradient(180deg, rgba(0,0,0,0.16), rgba(0,0,0,0.04)),
radial-gradient(700px 180px at 12% 0%, rgba(0,217,255,0.06), transparent 62%),
linear-gradient(180deg, rgba(0,0,0,0.14), rgba(0,0,0,0.035)),
radial-gradient(700px 180px at 12% 0%, rgba(0,217,255,0.055), transparent 62%),
rgba(127,127,127,0.04);
}
@@ -797,13 +870,13 @@ const usefulLinks = [
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
gap: 10px;
flex-wrap: wrap;
}
.pa-theory-hub__head{
display: grid;
gap: 6px;
gap: 4px;
}
.pa-theory-hub__eyebrow{
@@ -816,19 +889,19 @@ const usefulLinks = [
.pa-theory-hub h3{
margin: 0;
font-size: clamp(1.1rem, 1.6vw, 1.3rem);
line-height: 1.2;
font-size: clamp(1.02rem, 1.45vw, 1.22rem);
line-height: 1.18;
}
.pa-theory-hub__count{
display: inline-flex;
align-items: center;
min-height: 28px;
padding: 0 11px;
min-height: 26px;
padding: 0 10px;
border: 1px solid rgba(127,127,127,0.22);
border-radius: 999px;
background: rgba(127,127,127,0.04);
font-size: 12px;
font-size: 11.5px;
line-height: 1.2;
opacity: .82;
white-space: nowrap;
@@ -836,9 +909,9 @@ const usefulLinks = [
.pa-theory-hub__intro{
margin: 0;
max-width: 78ch;
font-size: 14px;
line-height: 1.55;
max-width: 76ch;
font-size: 13.5px;
line-height: 1.5;
opacity: .94;
}
@@ -846,25 +919,25 @@ const usefulLinks = [
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
gap: 10px;
flex-wrap: wrap;
}
.pa-theory-hub__chips{
display: flex;
flex-wrap: wrap;
gap: 8px;
gap: 6px;
}
.pa-chip{
display: inline-flex;
align-items: center;
min-height: 30px;
padding: 0 11px;
min-height: 28px;
padding: 0 10px;
border: 1px solid rgba(127,127,127,0.22);
border-radius: 999px;
background: rgba(127,127,127,0.05);
font-size: 12px;
font-size: 11.5px;
line-height: 1.2;
opacity: .9;
white-space: nowrap;
@@ -908,8 +981,33 @@ const usefulLinks = [
@media (max-width: 720px){
.pa-theory-hub{
padding: 16px;
border-radius: 18px;
gap: 8px;
padding: 14px;
border-radius: 16px;
}
.pa-theory-hub__top{
gap: 8px;
}
.pa-theory-hub h3{
font-size: 1rem;
}
.pa-theory-hub__intro{
font-size: 13px;
line-height: 1.44;
}
.pa-theory-hub__chips{
gap: 5px;
}
.pa-chip{
min-height: 26px;
padding: 0 9px;
font-size: 11px;
white-space: normal;
}
}
@@ -939,4 +1037,72 @@ const usefulLinks = [
background: rgba(0,217,255,0.08);
}
}
@media (max-width: 760px){
.pa-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.pa-cards{
grid-template-columns: 1fr;
}
.pa-theory-hub{
gap: 7px;
padding: 12px;
border-radius: 14px;
}
.pa-theory-hub h3{
font-size: .96rem;
line-height: 1.14;
}
.pa-theory-hub__intro{
font-size: 12.5px;
line-height: 1.38;
}
.pa-chip{
min-height: 24px;
padding: 0 8px;
font-size: 10.5px;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -212,11 +212,84 @@ const prolongerLinks = [
heroMoreId="theo-hero-more"
heroToggleId="theo-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.theo-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.theo-overview{
@@ -248,18 +321,18 @@ const prolongerLinks = [
.theo-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.theo-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
text-decoration: none;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
@@ -273,18 +346,18 @@ const prolongerLinks = [
}
.theo-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.theo-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
.theo-card small{
font-size: 12px;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.4;
opacity: .72;
}
@@ -305,4 +378,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.theo-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.theo-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -314,18 +314,91 @@ const prolongerLinks = [
heroMoreId="scene-hero-more"
heroToggleId="scene-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.scene-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.scene-focus-card{
margin-top: 14px;
padding: 18px 20px;
padding: var(--portal-focus-pad-y, 18px) var(--portal-focus-pad-x, 20px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 18px;
border-radius: var(--portal-focus-radius, 18px);
background: rgba(127,127,127,0.05);
}
@@ -340,8 +413,8 @@ const prolongerLinks = [
.scene-focus-card h3{
margin: 0 0 10px;
font-size: clamp(1.35rem, 2vw, 1.7rem);
line-height: 1.15;
font-size: var(--portal-local-h3-size, clamp(1.35rem, 2vw, 1.7rem));
line-height: var(--portal-local-h3-lh, 1.15);
}
.scene-focus-card h3 a{
@@ -378,18 +451,18 @@ const prolongerLinks = [
.scene-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.scene-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
text-decoration: none;
transition:
@@ -406,18 +479,18 @@ const prolongerLinks = [
}
.scene-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.scene-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
.scene-card small{
font-size: 12px;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.4;
opacity: .72;
}
@@ -438,4 +511,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.scene-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.scene-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -341,18 +341,91 @@ const prolongerLinks = [
heroMoreId="tir-hero-more"
heroToggleId="tir-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.tir-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.tir-note-card{
margin-top: 14px;
padding: 16px 18px;
padding: var(--portal-focus-pad-y, 18px) var(--portal-focus-pad-x, 20px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-focus-radius, 18px);
background: rgba(127,127,127,0.05);
}
@@ -426,18 +499,18 @@ const prolongerLinks = [
.tir-link-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.tir-link-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
text-decoration: none;
transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
@@ -451,18 +524,18 @@ const prolongerLinks = [
}
.tir-link-card strong{
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.tir-link-card span{
font-size: 14px;
line-height: 1.45;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.45);
opacity: .92;
}
.tir-link-card small{
font-size: 12px;
font-size: var(--portal-card-meta-size, 12px);
line-height: 1.4;
opacity: .72;
}
@@ -479,4 +552,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.tir-link-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.tir-link-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -328,27 +328,100 @@ const prolongerLinks = [
heroMoreId="verbs-hero-more"
heroToggleId="verbs-hero-toggle"
/>
<script is:inline>
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const follow = document.getElementById("reading-follow");
if (!body || !root || !follow) return;
body.classList.add("is-glossary-portal-page");
const mqMobile = window.matchMedia("(max-width: 860px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const disableFollow = () => {
if (!isCompactViewport()) return;
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
follow.style.display = "none";
follow.innerHTML = "";
root.style.setProperty("--followbar-h", "0px");
root.style.setProperty(
"--sticky-offset-px",
"calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))"
);
};
const enableFollow = () => {
if (isCompactViewport()) return;
follow.style.display = "";
};
const sync = () => {
if (isCompactViewport()) {
disableFollow();
} else {
enableFollow();
}
};
if (mqMobile.addEventListener) {
mqMobile.addEventListener("change", sync);
} else if (mqMobile.addListener) {
mqMobile.addListener(sync);
}
if (mqSmallLandscape.addEventListener) {
mqSmallLandscape.addEventListener("change", sync);
} else if (mqSmallLandscape.addListener) {
mqSmallLandscape.addListener(sync);
}
window.addEventListener("resize", sync);
window.addEventListener("pageshow", sync);
sync();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
.verbs-page{
padding: 8px 0 24px;
padding: var(--portal-page-pad-top, 8px) 0 var(--portal-page-pad-bottom, 24px);
}
.verbs-cards{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
margin-top: 14px;
margin-top: 12px;
}
.verbs-card{
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
padding: var(--portal-card-pad-y, 14px) var(--portal-card-pad-x, 16px);
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
border-radius: var(--portal-card-radius, 16px);
background: rgba(127,127,127,0.05);
transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
@@ -374,15 +447,15 @@ const prolongerLinks = [
.verbs-card h3{
margin: 0;
font-size: 15px;
font-size: var(--portal-card-title-size, 15px);
line-height: 1.3;
}
.verbs-card__definition,
.verbs-card__example{
margin: 0;
font-size: 14px;
line-height: 1.5;
font-size: var(--portal-card-text-size, 14px);
line-height: var(--portal-card-text-lh, 1.5);
opacity: .92;
}
@@ -395,4 +468,50 @@ const prolongerLinks = [
background: rgba(255,255,255,0.07);
}
}
@media (max-width: 760px){
.verbs-cards{
grid-template-columns: 1fr;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
.verbs-cards{
grid-template-columns: 1fr;
}
}
:global(body.is-glossary-portal-page #reading-follow){
z-index: 10;
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page){
--followbar-h: 0px !important;
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>