Compare commits

...

10 Commits

Author SHA1 Message Date
622963e8e9 Polish glossary portal compact sticky follow behavior
All checks were successful
SMOKE / smoke (push) Successful in 3s
CI / build-and-anchors (push) Successful in 38s
CI / build-and-anchors (pull_request) Successful in 37s
2026-05-07 22:56:53 +02:00
a2e5fd5bae Merge pull request 'Polish glossary complete index compact sticky behavior' (#359) from polish/index-complet-portal-sticky-mobile into main
All checks were successful
CI / build-and-anchors (push) Successful in 41s
Proposer Apply (Queue) / apply-proposer (push) Successful in 41s
SMOKE / smoke (push) Successful in 11s
Deploy staging+live (annotations) / deploy (push) Successful in 10m9s
Reviewed-on: #359
2026-05-07 17:20:51 +00:00
c9ed43c9e0 Polish glossary complete index compact sticky behavior
All checks were successful
SMOKE / smoke (push) Successful in 9s
CI / build-and-anchors (push) Successful in 49s
CI / build-and-anchors (pull_request) Successful in 42s
2026-05-07 19:18:25 +02:00
3439e2aaf9 Merge pull request 'Polish glossary home sticky hero on mobile and tablet' (#358) from polish/glossary-home-hero-sticky-mobile into main
All checks were successful
Proposer Apply (Queue) / apply-proposer (push) Successful in 21s
CI / build-and-anchors (push) Successful in 36s
SMOKE / smoke (push) Successful in 5s
Deploy staging+live (annotations) / deploy (push) Successful in 10m53s
Reviewed-on: #358
2026-05-07 12:56:01 +00:00
75fd6de293 Polish glossary home sticky hero on mobile and tablet
All checks were successful
SMOKE / smoke (push) Successful in 11s
CI / build-and-anchors (push) Successful in 42s
CI / build-and-anchors (pull_request) Successful in 40s
2026-05-07 14:52:12 +02:00
7551c91f37 Merge pull request 'Polish glossary home responsive aside and map density' (#357) from polish/glossary-home-mobile-and-map-density into main
All checks were successful
Proposer Apply (Queue) / apply-proposer (push) Successful in 26s
CI / build-and-anchors (push) Successful in 48s
SMOKE / smoke (push) Successful in 5s
Deploy staging+live (annotations) / deploy (push) Successful in 10m59s
Reviewed-on: #357
2026-05-07 12:04:59 +00:00
40ab10b8e8 Polish glossary home responsive aside and map density
All checks were successful
SMOKE / smoke (push) Successful in 15s
CI / build-and-anchors (push) Successful in 43s
CI / build-and-anchors (pull_request) Successful in 48s
2026-05-07 13:59:05 +02:00
4bab188df7 Merge pull request 'Fix glossary home hero follow truncation' (#356) from fix/glossary-home-hero-follow-no-truncation into main
All checks were successful
CI / build-and-anchors (push) Successful in 44s
Proposer Apply (Queue) / apply-proposer (push) Successful in 26s
SMOKE / smoke (push) Successful in 11s
Deploy staging+live (annotations) / deploy (push) Successful in 9m16s
Reviewed-on: #356
2026-05-06 11:50:48 +00:00
aaed642cec Fix glossary home hero follow truncation
All checks were successful
SMOKE / smoke (push) Successful in 4s
CI / build-and-anchors (push) Successful in 38s
CI / build-and-anchors (pull_request) Successful in 40s
2026-05-06 13:48:23 +02:00
b4f2de438e Merge pull request 'Stabilize commencer editorial reveal spacing' (#355) from fix/commencer-reveal-css-stabilization into main
All checks were successful
Proposer Apply (Queue) / apply-proposer (push) Successful in 24s
CI / build-and-anchors (push) Successful in 42s
SMOKE / smoke (push) Successful in 8s
Deploy staging+live (annotations) / deploy (push) Successful in 9m26s
Reviewed-on: #355
2026-05-06 08:26:22 +00:00
15 changed files with 2030 additions and 957 deletions

View File

@@ -192,120 +192,47 @@ const {
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){
@media (max-width: 980px){
.glossary-home-aside{
gap: 8px;
margin-bottom: 12px;
}
.glossary-home-aside__block{
border-radius: 12px;
border-radius: 13px;
}
.glossary-home-aside__block--intro{
padding: 10px 11px;
padding: 10px 12px;
}
.glossary-home-aside__title{
font-size: 16px;
line-height: 1.14;
font-size: 15px;
line-height: 1.15;
}
.glossary-home-aside__meta{
font-size: 11px;
line-height: 1.26;
margin-top: 5px;
display: none;
}
.glossary-home-aside__pills{
gap: 5px;
margin-top: 8px;
margin-top: 7px;
}
.glossary-home-aside__pill{
padding: 3px 8px;
font-size: 11px;
line-height: 1.2;
line-height: 1.18;
}
.glossary-home-aside__summary{
padding: 10px 11px;
padding: 9px 11px;
}
.glossary-home-aside__heading{
font-size: 15px;
line-height: 1.16;
font-size: 14px;
line-height: 1.15;
}
.glossary-home-aside__panel{
@@ -320,9 +247,80 @@ const {
font-size: 13px;
line-height: 1.28;
}
.glossary-home-aside__disclosure:not([open]) .glossary-home-aside__panel{
display: none;
}
}
@media (min-width: 861px){
@media (max-width: 980px){
.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: 7px;
margin-bottom: 10px;
}
.glossary-home-aside__block{
border-radius: 12px;
}
.glossary-home-aside__block--intro{
padding: 9px 10px;
}
.glossary-home-aside__title{
font-size: 14px;
line-height: 1.12;
}
.glossary-home-aside__meta{
display: none;
}
.glossary-home-aside__pills{
gap: 4px;
margin-top: 6px;
}
.glossary-home-aside__pill{
padding: 2px 7px;
font-size: 10.5px;
line-height: 1.16;
}
.glossary-home-aside__summary{
padding: 8px 10px;
}
.glossary-home-aside__heading{
font-size: 13px;
line-height: 1.12;
}
.glossary-home-aside__panel{
padding: 0 10px 9px;
}
.glossary-home-aside__list li{
margin: 3px 0;
}
.glossary-home-aside__list a{
font-size: 12px;
line-height: 1.22;
}
}
@media (min-width: 981px){
.glossary-home-aside__summary{
cursor: default;
}
@@ -346,28 +344,32 @@ const {
<script is:inline>
(() => {
let wasCompact = null;
const syncMobileDisclosure = () => {
const mobile = window.matchMedia("(max-width: 860px)").matches;
const stackedLayout = window.matchMedia("(max-width: 980px)").matches;
const smallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
).matches;
const compact = mobile || smallLandscape;
const compact = stackedLayout || smallLandscape;
const enteringCompact = compact && wasCompact !== true;
document
.querySelectorAll(".glossary-home-aside__disclosure")
.forEach((el, index) => {
.forEach((el) => {
if (!(el instanceof HTMLDetailsElement)) return;
if (compact) {
if (!el.dataset.mobileInit) {
el.open = index === 0;
el.dataset.mobileInit = "true";
if (enteringCompact) {
el.open = false;
}
} else {
el.open = true;
}
});
wasCompact = compact;
};
if (document.readyState === "loading") {

View File

@@ -457,4 +457,292 @@ const {
line-height: 1.08 !important;
}
}
/* =========================================================
Glossaire home — états du hero sticky
========================================================= */
/*
Principe :
- le follow peut respirer sans ellipsis brutal ;
- lintro reste strictement clampée en mode collapsed ;
- lintro ne redevient complète quen mode expanded ;
- mobile/tablette <= 860px reste neutralisé plus haut.
*/
.glossary-hero-follow{
height: auto;
max-height: none;
max-width: min(100%, 34ch);
overflow: visible;
white-space: normal;
text-overflow: clip;
line-height: 1.08;
}
:global(body.glossary-home-follow-on) .glossary-hero{
min-height: auto;
height: auto;
}
:global(body.glossary-home-follow-on) .glossary-hero h1{
white-space: normal;
overflow: visible;
text-overflow: clip;
}
/*
État collapsed :
lintro DOIT rester compactée. Cette règle doit gagner contre
les anciennes règles anti-troncature du follow.
*/
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero p#glossary-hero-intro{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
max-height: calc(2 * 1.34em);
overflow: hidden;
white-space: normal;
text-overflow: clip;
}
:global(body.glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero__toggle{
display: inline-flex;
margin-top: 2px;
align-self: start;
}
/*
État expanded :
lutilisateur a explicitement demandé à lire la suite,
donc lintro redevient complète.
*/
:global(body.glossary-home-hero-expanded) .glossary-hero p#glossary-hero-intro{
display: block;
-webkit-line-clamp: unset;
line-clamp: unset;
-webkit-box-orient: unset;
max-height: none;
overflow: visible;
white-space: normal;
text-overflow: clip;
}
:global(body.glossary-home-hero-expanded) .glossary-hero__toggle{
display: none !important;
}
@media (min-width: 861px) and (max-width: 1240px){
.glossary-hero-follow{
max-width: min(100%, 36ch);
font-size: clamp(1.55rem, 3.1vw, 2.05rem);
line-height: 1.08;
}
}
/* =========================================================
Glossaire home — sticky compact mobile/tablette avec H2 local
========================================================= */
@media (max-width: 980px){
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero{
position: sticky !important;
top: calc(var(--sticky-header-h, 0px) + 8px) !important;
z-index: 8 !important;
transform: none !important;
overflow: hidden !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero{
padding: 8px 10px 9px !important;
row-gap: 4px !important;
border-radius: 16px !important;
margin-bottom: 10px !important;
box-shadow: 0 12px 30px rgba(0,0,0,.22) !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-kicker{
font-size: 9px !important;
line-height: 1.05 !important;
letter-spacing: .11em !important;
opacity: .72 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.35rem, 5.1vw, 1.72rem) !important;
line-height: 1.02 !important;
letter-spacing: -.03em !important;
white-space: normal !important;
overflow: visible !important;
text-overflow: clip !important;
max-width: 100% !important;
margin: 0 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero p#glossary-hero-intro{
display: -webkit-box !important;
-webkit-box-orient: vertical !important;
-webkit-line-clamp: 2 !important;
line-clamp: 2 !important;
max-height: calc(2 * 1.12em) !important;
overflow: hidden !important;
white-space: normal !important;
text-overflow: clip !important;
font-size: .72rem !important;
line-height: 1.12 !important;
opacity: .78 !important;
margin: 0 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero__toggle{
display: none !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero-follow{
display: none !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero-follow.is-visible{
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-height: 0 !important;
margin-top: 4px !important;
padding-top: 6px !important;
border-top: 1px solid rgba(127,127,127,.18) !important;
opacity: .98 !important;
transform: none !important;
filter: none !important;
white-space: normal !important;
overflow: hidden !important;
text-overflow: clip !important;
color: inherit !important;
}
}
@media (min-width: 761px) and (max-width: 980px){
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero{
padding: 10px 14px 11px !important;
row-gap: 5px !important;
border-radius: 18px !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.65rem, 3.4vw, 2.1rem) !important;
line-height: 1.02 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero p#glossary-hero-intro{
font-size: .82rem !important;
line-height: 1.18 !important;
max-height: calc(2 * 1.18em) !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero-follow.is-visible{
margin-top: 5px !important;
padding-top: 7px !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero{
top: calc(var(--sticky-header-h, 0px) + 6px) !important;
padding: 6px 9px 7px !important;
row-gap: 3px !important;
border-radius: 13px !important;
margin-bottom: 8px !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-kicker{
font-size: 8px !important;
line-height: 1 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero h1{
font-size: clamp(1.08rem, 3.2vw, 1.34rem) !important;
line-height: 1 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on:not(.glossary-home-hero-expanded)) .glossary-hero p#glossary-hero-intro{
-webkit-line-clamp: 1 !important;
line-clamp: 1 !important;
max-height: 1.08em !important;
font-size: .64rem !important;
line-height: 1.08 !important;
opacity: .72 !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero-follow.is-visible{
margin-top: 3px !important;
padding-top: 4px !important;
font-size: .86rem !important;
line-height: 1.04 !important;
}
}
/* =========================================================
Glossaire home — polish premium fluidité sticky
========================================================= */
@media (max-width: 980px){
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero{
transition:
padding 180ms ease,
border-radius 180ms ease,
box-shadow 180ms ease,
background 180ms ease,
margin-bottom 180ms ease;
will-change: padding, border-radius, box-shadow;
backface-visibility: hidden;
transform: translateZ(0) !important;
background: rgba(0,0,0,.92) !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero h1,
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-kicker,
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero p#glossary-hero-intro{
transition:
font-size 180ms ease,
line-height 180ms ease,
opacity 180ms ease,
max-height 180ms ease;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"]) .glossary-hero-follow{
display: block !important;
max-height: 0 !important;
margin-top: 0 !important;
padding-top: 0 !important;
border-top: 0 !important;
opacity: 0 !important;
visibility: hidden !important;
overflow: hidden !important;
transform: translateY(-4px) !important;
transition:
max-height 180ms ease,
opacity 180ms ease,
transform 180ms ease,
padding-top 180ms ease,
margin-top 180ms ease;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero-follow.is-visible{
max-height: 3.2em !important;
opacity: .98 !important;
visibility: visible !important;
transform: translateY(0) !important;
border-top: 1px solid rgba(127,127,127,.18) !important;
}
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero{
background: rgba(0,0,0,.96) !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body[data-edition-key="glossaire"][data-sticky-mode="glossary-home"].glossary-home-follow-on) .glossary-hero-follow.is-visible{
max-height: 2.4em !important;
}
}
</style>

View File

@@ -5,6 +5,7 @@ interface Props {
sectionHeadSelector?: string;
mobileBreakpoint?: number;
autoCollapseDelta?: number;
compactSticky?: boolean;
}
const {
@@ -13,12 +14,13 @@ const {
sectionHeadSelector = ".glossary-portal-section__head",
mobileBreakpoint = 860,
autoCollapseDelta = 160,
compactSticky = false,
} = Astro.props;
---
<script
is:inline
define:vars={{ heroMoreId, heroToggleId, sectionHeadSelector, mobileBreakpoint, autoCollapseDelta }}
define:vars={{ heroMoreId, heroToggleId, sectionHeadSelector, mobileBreakpoint, autoCollapseDelta, compactSticky }}
>
(() => {
const boot = () => {
@@ -32,6 +34,7 @@ const {
if (!body || !root || !hero || !follow) return;
const BODY_CLASS = "is-glossary-portal-page";
const COMPACT_STICKY_CLASS = "glossary-portal-compact-sticky";
const FOLLOW_ON_CLASS = "glossary-portal-follow-on";
const EXPANDED_CLASS = "glossary-portal-hero-expanded";
const CONDENSED_CLASS = "glossary-portal-hero-condensed";
@@ -47,12 +50,24 @@ const {
let lastFollowOn = null;
let lastCondensed = null;
let lastHeroHeight = -1;
let heroPinStartY = null;
let lastCompactFollowTitle = null;
let lastCompactFollowOn = null;
body.classList.add(BODY_CLASS);
body.classList.toggle(COMPACT_STICKY_CLASS, Boolean(compactSticky));
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const keepPortalPremiumOnCompact = () =>
Boolean(compactSticky) || body.classList.contains("is-index-complet-page");
const compactShouldDisablePortal = () =>
isCompactViewport() && !keepPortalPremiumOnCompact();
const compactStickyEnabled = () => Boolean(compactSticky);
const stripLocalSticky = () => {
document.querySelectorAll(sectionHeadSelector).forEach((el) => {
el.classList.remove("is-sticky");
@@ -68,19 +83,49 @@ const {
return Number.isFinite(n) ? n : 64;
};
const captureHeroPinStart = (force = false) => {
if (!force && heroPinStartY != null) return heroPinStartY;
const stickyTop = readStickyTop();
const rect = hero.getBoundingClientRect();
const y = window.scrollY || window.pageYOffset || 0;
/*
Seuil documentaire réel : moment où le haut naturel du hero
rejoint le rail sticky. Ce seuil empêche la condensation au haut
de page lorsque le hero n'est pas encore embarqué dans le scroll.
*/
heroPinStartY = Math.max(0, Math.round(y + rect.top - stickyTop));
return heroPinStartY;
};
const hasReachedHeroPinStart = () => {
const y = window.scrollY || window.pageYOffset || 0;
const start = captureHeroPinStart(false);
const rect = hero.getBoundingClientRect();
const stickyTop = readStickyTop();
/*
Condensation immédiate au moment réel d'accrochage :
- soit le scroll a atteint le seuil documentaire ;
- soit le hero est déjà visuellement posé sur son rail sticky.
Aucun délai artificiel ne doit retarder la troncature.
*/
return y >= start - 1 || Math.abs(rect.top - stickyTop) <= 2;
};
const computeFollowOn = () =>
!isCompactViewport() &&
body.classList.contains(CONDENSED_CLASS) &&
(!isCompactViewport() || compactStickyEnabled()) &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const computeCondensed = () => {
if (isCompactViewport()) return false;
if (isCompactViewport() && !compactStickyEnabled()) return false;
const heroRect = hero.getBoundingClientRect();
const stickyTop = readStickyTop();
return heroRect.top <= stickyTop + 2;
return hasReachedHeroPinStart();
};
const measureHeroHeight = () =>
@@ -89,7 +134,7 @@ const {
const PIN_EPS = 3;
const isHeroPinned = () => {
if (isCompactViewport()) return false;
if (isCompactViewport() && !compactStickyEnabled()) return false;
const rect = hero.getBoundingClientRect();
const stickyTop = readStickyTop();
@@ -97,14 +142,73 @@ const {
if (cs.position !== "sticky") return false;
const pinnedOnRail = Math.abs(rect.top - stickyTop) <= PIN_EPS;
const stillVisible = rect.bottom > stickyTop + 24;
return hasReachedHeroPinStart() && stillVisible;
};
return pinnedOnRail && stillVisible;
const applyCompactHeroRail = () => {
/*
Les portails compactSticky doivent coller sous ledition-bar.
Certaines couches CSS historiques peuvent encore forcer top:0.
On pose donc le rail en inline !important, uniquement pour les
portails génériques compacts, jamais pour lindex complet.
*/
if (
!isCompactViewport() ||
!compactStickyEnabled() ||
body.classList.contains("is-index-complet-page")
) {
hero.style.removeProperty("top");
return;
}
const stickyTop = readStickyTop();
hero.style.setProperty("top", `${Math.round(stickyTop)}px`, "important");
};
const applyCompactFollowRail = () => {
/*
Le reading-follow compact doit être collé sous le hero.
Certaines règles historiques de #reading-follow imposent top:-1px
avec une priorité supérieure au style simple. On pose donc le rail
en inline !important, uniquement pour les portails compacts génériques.
*/
if (
!isCompactViewport() ||
!compactStickyEnabled() ||
body.classList.contains("is-index-complet-page")
) {
follow.style.removeProperty("top");
follow.style.removeProperty("left");
follow.style.removeProperty("width");
return;
}
const stickyTop = readStickyTop();
const heroH = body.classList.contains(CONDENSED_CLASS)
? measureHeroHeight()
: 0;
const top = Math.max(0, Math.round(stickyTop + heroH - 1));
follow.style.setProperty("position", "fixed", "important");
follow.style.setProperty("top", `${top}px`, "important");
follow.style.setProperty("left", "var(--reading-left)", "important");
follow.style.setProperty("width", "var(--reading-width)", "important");
follow.style.setProperty("z-index", "71", "important");
};
const applyLocalStickyHeight = () => {
const h = isHeroPinned() ? measureHeroHeight() : 0;
/*
Stabilisation premium :
une fois le hero condensé, on réserve sa hauteur réelle.
Cela évite les oscillations dun frame où isHeroPinned()
peut repasser brièvement à false pendant le scroll.
*/
const shouldReserveHero =
body.classList.contains(CONDENSED_CLASS) || isHeroPinned();
const h = shouldReserveHero ? measureHeroHeight() : 0;
if (h === lastHeroHeight) return;
lastHeroHeight = h;
@@ -183,7 +287,7 @@ const {
const expanded = body.classList.contains(EXPANDED_CLASS);
const collapsed = condensed && !expanded;
if (isCompactViewport() || !condensed) {
if ((isCompactViewport() && !compactStickyEnabled()) || !condensed) {
body.classList.remove(EXPANDED_CLASS);
expandedAtY = null;
@@ -208,9 +312,229 @@ const {
heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
}
};
/* GENERIC_COMPACT_FOLLOW_CLEAN_START
Portails génériques compactSticky :
- ligne 1 : section macro active ;
- ligne 2 : sous-tête interne active ;
- un titre ne devient actif qu'une fois complètement dépassé
par la bande réelle du reading-follow__inner.
*/
const isGenericCompactPortal = () =>
isCompactViewport() &&
compactStickyEnabled() &&
!body.classList.contains("is-index-complet-page");
const compactFollowBand = () => {
const inner = follow.querySelector(".reading-follow__inner");
const innerRect = inner?.getBoundingClientRect();
const heroRect = hero.getBoundingClientRect();
if (innerRect && innerRect.height > 0) {
return {
top: innerRect.top,
bottom: innerRect.bottom,
height: innerRect.height,
};
}
const top = Math.max(readStickyTop(), heroRect.bottom || readStickyTop());
const height = 30;
return {
top,
bottom: top + height,
height,
};
};
const cleanFollowTitle = (el) => {
if (!el) return "";
const clone = el.cloneNode(true);
clone
.querySelectorAll(
[
".glossary-portal-section__count",
"[class*='count']",
"[class*='index']",
"[class*='meta']",
"[class*='eyebrow']",
"[aria-hidden='true']"
].join(",")
)
.forEach((node) => node.remove());
return clone.textContent?.replace(/\s+/g, " ").trim() ?? "";
};
const titleNodeFor = (node) =>
node?.matches?.("h2,h3,h4,[data-reading-title]")
? node
: node?.querySelector?.("h2,h3,h4,[data-reading-title]") ?? node;
const passedTitleStateFrom = (nodes) => {
const band = compactFollowBand();
const bandCenter = band.top + band.height / 2;
let active = null;
for (const node of nodes) {
const titleNode = titleNodeFor(node);
const title = cleanFollowTitle(titleNode);
if (!title) continue;
const rect = titleNode.getBoundingClientRect();
if (rect.height <= 0) continue;
/*
Règle perceptive stabilisée :
la traversée commence quand le bas du follow rencontre le haut
du titre réel, et s'achève quand le haut du follow rencontre
le bas du titre réel.
Comme le follow n'anime pas deux titres concurrents, le basculement
se fait au milieu de cette traversée : quand le centre du titre
est passé au-dessus du centre de la bande follow.
*/
const titleCenter = rect.top + rect.height / 2;
if (titleCenter <= bandCenter + 1) {
active = {
node,
titleNode,
title,
};
continue;
}
break;
}
return active;
};
const detailCandidatesFor = (sectionNode) => {
const section = sectionNode?.closest("section");
if (!section) return [];
const selector = [
".glossary-portal-panel__head",
"[class*='__head']",
"[class*='__title']",
"h3",
"h4"
].join(",");
return Array.from(section.querySelectorAll(selector)).filter((node) => {
if (node.closest(".glossary-portal-section__head")) return false;
const titleNode = titleNodeFor(node);
const title = cleanFollowTitle(titleNode);
if (!title) return false;
const rect = titleNode.getBoundingClientRect();
if (rect.height <= 0) return false;
return true;
});
};
const renderFollowTextLine = (inner, className, title) => {
if (!title) return;
let line = inner.querySelector(`.${className}`);
if (!line) {
line = document.createElement("div");
line.className = `rf-line ${className}`;
inner.appendChild(line);
}
line.textContent = title;
};
const setCompactFollowOff = () => {
lastCompactFollowTitle = null;
if (lastCompactFollowOn !== false) {
lastCompactFollowOn = false;
body.classList.remove(FOLLOW_ON_CLASS);
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
}
follow.style.display = "block";
follow.style.setProperty("opacity", "0", "important");
follow.style.setProperty("visibility", "hidden", "important");
follow.style.setProperty("pointer-events", "none", "important");
root.style.setProperty("--followbar-h", "0px");
};
const syncGenericCompactFollow = (condensed) => {
if (!isGenericCompactPortal()) return false;
if (!condensed) {
setCompactFollowOff();
return true;
}
const sectionHeads = Array.from(
document.querySelectorAll(".glossary-portal-section__head")
);
const sectionState = passedTitleStateFrom(sectionHeads);
if (!sectionState?.title) {
setCompactFollowOff();
return true;
}
const detailState = passedTitleStateFrom(detailCandidatesFor(sectionState.node));
follow.innerHTML = "";
const inner = document.createElement("div");
inner.className = "reading-follow__inner";
renderFollowTextLine(inner, "rf-h2", sectionState.title);
if (detailState?.title && detailState.title !== sectionState.title) {
renderFollowTextLine(inner, "rf-h3", detailState.title);
}
follow.appendChild(inner);
if (lastCompactFollowOn !== true) {
lastCompactFollowOn = true;
body.classList.add(FOLLOW_ON_CLASS);
follow.classList.add("is-on");
follow.setAttribute("aria-hidden", "false");
}
follow.style.display = "block";
follow.style.setProperty("opacity", "1", "important");
follow.style.setProperty("visibility", "visible", "important");
follow.style.setProperty("pointer-events", "auto", "important");
applyCompactFollowRail();
inner.style.setProperty("opacity", "1", "important");
inner.style.setProperty("visibility", "visible", "important");
inner.style.setProperty("display", "block", "important");
requestAnimationFrame(() => {
applyCompactFollowRail();
const h = Math.max(0, Math.round(follow.getBoundingClientRect().height || 0));
root.style.setProperty("--followbar-h", `${h}px`);
});
return true;
};
/* GENERIC_COMPACT_FOLLOW_CLEAN_END */
const maybeAutoCollapseOnScroll = () => {
if (isCompactViewport()) {
if (isCompactViewport() && !compactStickyEnabled()) {
lastScrollY = window.scrollY || 0;
return;
}
@@ -238,8 +562,9 @@ const {
const syncAll = () => {
stripLocalSticky();
applyCompactHeroRail();
if (isCompactViewport()) {
if (isCompactViewport() && !compactStickyEnabled()) {
body.classList.remove(FOLLOW_ON_CLASS);
body.classList.remove(CONDENSED_CLASS);
body.classList.remove(EXPANDED_CLASS);
@@ -272,14 +597,27 @@ const {
requestAnimationFrame(() => {
applyLocalStickyHeight();
syncFollowState();
applyCompactFollowRail();
if (syncGenericCompactFollow(condensed)) {
return;
}
try {
window.__archiUpdateFollow?.();
} catch {}
syncFollowState();
});
requestAnimationFrame(() => {
applyLocalStickyHeight();
applyCompactFollowRail();
if (syncGenericCompactFollow(condensed)) {
return;
}
try {
window.__archiUpdateFollow?.();
} catch {}
@@ -316,8 +654,19 @@ const {
heroResizeObserver?.observe(hero);
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
window.addEventListener("resize", () => {
heroPinStartY = null;
applyCompactHeroRail();
applyCompactFollowRail();
schedule();
});
window.addEventListener("pageshow", () => {
heroPinStartY = null;
applyCompactHeroRail();
applyCompactFollowRail();
captureHeroPinStart(true);
schedule();
});
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
@@ -335,6 +684,9 @@ const {
mqSmallLandscape.addListener(schedule);
}
applyCompactHeroRail();
applyCompactFollowRail();
captureHeroPinStart(true);
schedule();
};
@@ -422,66 +774,409 @@ const {
}
@media (max-width: 860px){
:global(body.is-glossary-portal-page #reading-follow),
:global(body.is-glossary-portal-page #reading-follow .reading-follow__inner){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-page) #reading-follow),
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.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-glossary-portal-page){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-page) #reading-follow),
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.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-glossary-portal-page){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-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){
:global(body.is-glossary-portal-page:not(.glossary-portal-compact-sticky):not(.is-index-complet-page) .glossary-portal-hero__toggle){
display: none !important;
}
}
/* =========================================================
Index complet — exception premium compacte portal
---------------------------------------------------------
Les portails ordinaires restent neutralisés en compact.
Lindex complet, lui, conserve la pile :
hero sticky → reading-follow → lettres flottantes.
========================================================= */
@media (max-width: 980px){
:global(body.is-index-complet-page[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]) .glossary-portal-hero,
:global(body.is-index-complet-page[data-edition-key="glossaire"][data-sticky-mode="glossary-portal"]) .glossary-page-hero{
position: sticky !important;
top: var(--glossary-sticky-top, calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))) !important;
z-index: 72 !important;
margin-bottom: 0 !important;
overflow: hidden !important;
transform: translateZ(0) !important;
backface-visibility: hidden !important;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
:global(body.is-index-complet-page #reading-follow){
display: block !important;
position: fixed !important;
left: var(--reading-left) !important;
width: var(--reading-width) !important;
top: calc(var(--glossary-sticky-top, var(--sticky-header-h, 0px)) + var(--glossary-local-sticky-h, 0px) - var(--followbar-h, 0px) - 1px) !important;
z-index: 71 !important;
visibility: hidden !important;
opacity: 0 !important;
pointer-events: none !important;
}
:global(body.is-index-complet-page.glossary-portal-follow-on #reading-follow){
visibility: visible !important;
opacity: 1 !important;
}
:global(body.is-index-complet-page #reading-follow .reading-follow__inner){
display: block !important;
visibility: visible !important;
opacity: 1 !important;
max-height: none !important;
margin-top: -1px !important;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}
:global(body.is-index-complet-page #gic-follow-letters){
position: fixed !important;
left: var(--reading-left) !important;
width: var(--reading-width) !important;
top: calc(var(--glossary-sticky-top, var(--sticky-header-h, 0px)) + var(--gic-premium-hero-h, 0px) + var(--gic-premium-follow-h, 0px) - 1px) !important;
z-index: 70 !important;
}
:global(body.is-index-complet-page.gic-letters-docked #gic-follow-letters){
display: flex !important;
visibility: visible !important;
opacity: 1 !important;
pointer-events: auto !important;
}
}
/* PORTAL_COMPACT_STICKY_CLEAN_START
Portails glossaire — comportement compact générique final.
- Aucune condensation en haut de page.
- Condensation seulement après seuil documentaire réel.
- Hero sticky sous ledition-bar.
- reading-follow collé sous le hero condensé.
- index-complet exclu.
*/
@media (min-width: 981px){
:global(body.is-glossary-portal-page:not(.glossary-portal-hero-condensed) #reading-follow),
:global(body.is-glossary-portal-page:not(.glossary-portal-hero-condensed) #reading-follow .reading-follow__inner){
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
}
@media (max-width: 980px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .glossary-portal-hero),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .glossary-page-hero){
position: sticky !important;
top: var(--glossary-sticky-top, calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))) !important;
z-index: 72 !important;
display: grid !important;
width: 100% !important;
max-width: 100% !important;
min-width: 0 !important;
overflow: hidden !important;
transform: translateZ(0) !important;
backface-visibility: hidden !important;
background:
linear-gradient(rgba(0,0,0,.72), rgba(0,0,0,.96)),
radial-gradient(780px 220px at 18% 0%, rgba(0,217,255,.08), transparent 60%) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page):not(.glossary-portal-hero-condensed) #reading-follow),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page):not(.glossary-portal-hero-condensed) #reading-follow .reading-follow__inner),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page):not(.glossary-portal-follow-on) #reading-follow),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page):not(.glossary-portal-follow-on) #reading-follow .reading-follow__inner){
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-page-hero){
padding: 8px 10px 9px !important;
row-gap: 4px !important;
border-radius: 16px 16px 0 0 !important;
margin-bottom: 0 !important;
box-shadow: 0 12px 30px rgba(0,0,0,.24) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero__kicker){
font-size: 9px !important;
line-height: 1.05 !important;
letter-spacing: .11em !important;
opacity: .72 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero h1){
font-size: clamp(1.35rem, 5.1vw, 1.72rem) !important;
line-height: 1.02 !important;
letter-spacing: -.03em !important;
margin: 0 !important;
max-width: 100% !important;
white-space: normal !important;
overflow: visible !important;
text-overflow: clip !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro--lead){
display: -webkit-box !important;
-webkit-box-orient: vertical !important;
-webkit-line-clamp: 2 !important;
line-clamp: 2 !important;
max-height: calc(2 * 1.12em) !important;
overflow: hidden !important;
font-size: .72rem !important;
line-height: 1.12 !important;
opacity: .78 !important;
margin: 0 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__more){
max-height: 0 !important;
opacity: 0 !important;
overflow: hidden !important;
pointer-events: none !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero__toggle){
min-height: 22px !important;
padding: 2px 0 !important;
font-size: 11px !important;
line-height: 1.05 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow){
display: block !important;
position: fixed !important;
left: var(--reading-left) !important;
width: var(--reading-width) !important;
top: calc(
var(--glossary-sticky-top, calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)))
+ var(--glossary-local-sticky-h, 0px)
- 1px
) !important;
z-index: 71 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-follow-on #reading-follow),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-follow-on #reading-follow .reading-follow__inner){
opacity: 1 !important;
visibility: visible !important;
pointer-events: auto !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .reading-follow__inner){
min-height: 26px !important;
padding: 5px 10px 6px !important;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
border-bottom-left-radius: 13px !important;
border-bottom-right-radius: 13px !important;
border-top: 1px solid rgba(127,127,127,.16) !important;
background:
linear-gradient(180deg, rgba(0,0,0,.80), rgba(0,0,0,.94)),
radial-gradient(620px 120px at 18% 0%, rgba(0,217,255,.055), transparent 60%) !important;
box-shadow: 0 10px 22px rgba(0,0,0,.18) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h1),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h3),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-actions){
display: none !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h2){
display: block !important;
font-size: .86rem !important;
line-height: 1.08 !important;
font-weight: 800 !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
}
@media (min-width: 761px) and (max-width: 980px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-page-hero){
padding: 8px 12px 8px !important;
border-radius: 16px 16px 0 0 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero h1){
font-size: clamp(1.48rem, 3vw, 1.82rem) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro--lead){
font-size: .76rem !important;
line-height: 1.14 !important;
max-height: calc(2 * 1.14em) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h2){
font-size: .9rem !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-page-hero){
padding: 5px 8px 5px !important;
row-gap: 2px !important;
border-radius: 12px 12px 0 0 !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed .glossary-portal-hero h1){
font-size: clamp(1rem, 3vw, 1.22rem) !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page).glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro--lead){
display: none !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .reading-follow__inner){
min-height: 22px !important;
padding: 4px 8px 5px !important;
border-bottom-left-radius: 11px !important;
border-bottom-right-radius: 11px !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h2){
font-size: .78rem !important;
line-height: 1.04 !important;
}
}
/* PORTAL_COMPACT_STICKY_CLEAN_END */
/* PORTAL_COMPACT_STICKY_OVERFLOW_FIX_START
Libération du contexte sticky sur les portails glossaire compacts.
Le hero ne peut pas coller sous ledition-bar si un ancêtre le piège
dans un overflow/contain compact.
*/
@media (max-width: 980px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .page),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .page-shell),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .reading),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) article.reading),
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) main){
overflow: visible !important;
overflow-x: visible !important;
overflow-y: visible !important;
contain: none !important;
transform: none !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) .glossary-portal-hero){
align-self: start !important;
justify-self: stretch !important;
position: sticky !important;
top: var(--glossary-sticky-top, calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px))) !important;
z-index: 72 !important;
}
}
/* PORTAL_COMPACT_STICKY_OVERFLOW_FIX_END */
/* PORTAL_COMPACT_FOLLOW_TWO_LINES_START
Le follow compact des portails génériques affiche deux niveaux :
section active + sous-tête interne active.
*/
@media (max-width: 980px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h2){
display: block !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h3){
display: block !important;
margin-top: 1px !important;
font-size: .68rem !important;
line-height: 1.05 !important;
letter-spacing: .01em !important;
opacity: .72 !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .reading-follow__inner){
padding-top: 5px !important;
padding-bottom: 6px !important;
}
}
@media (max-width: 520px){
:global(body.is-glossary-portal-page.glossary-portal-compact-sticky:not(.is-index-complet-page) #reading-follow .rf-h3){
font-size: .64rem !important;
line-height: 1.02 !important;
}
}
/* PORTAL_COMPACT_FOLLOW_TWO_LINES_END */
</style>

View File

@@ -931,14 +931,14 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
min-width: 0 !important;
}
:global(body[data-edition-key="glossaire"]) .glossary-hero,
:global(body[data-edition-key="glossaire"]:not([data-sticky-mode="glossary-home"]):not([data-sticky-mode="glossary-portal"])) .glossary-hero,
:global(body[data-edition-key="glossaire"]) .glossary-home,
:global(body[data-edition-key="glossaire"]) .glossary-map,
:global(body[data-edition-key="glossaire"]) .glossary-map-block,
:global(body[data-edition-key="glossaire"]) .glossary-map-section,
:global(body[data-edition-key="glossaire"]) .glossary-page-hero,
:global(body[data-edition-key="glossaire"]) .glossary-portal-hero,
:global(body[data-edition-key="glossaire"]) .scene-hero{
:global(body[data-edition-key="glossaire"]:not([data-sticky-mode="glossary-portal"])) .glossary-page-hero,
:global(body[data-edition-key="glossaire"]:not([data-sticky-mode="glossary-portal"])) .glossary-portal-hero,
:global(body[data-edition-key="glossaire"]:not([data-sticky-mode="glossary-portal"])) .scene-hero{
position: static !important;
top: auto !important;
left: auto !important;
@@ -953,7 +953,7 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
transform: none !important;
}
:global(body[data-edition-key="glossaire"]) #reading-follow{
:global(body[data-edition-key="glossaire"]:not([data-sticky-mode="glossary-portal"])) #reading-follow{
display: none !important;
}
}

View File

@@ -218,81 +218,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="archi-hero-more"
heroToggleId="archi-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -364,38 +293,4 @@ const prolongerLinks = [
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,6 +328,8 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="cf-hero-more"
heroToggleId="cf-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
</GlossaryLayout>

View File

@@ -335,80 +335,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="dyna-hero-more"
heroToggleId="dyna-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -563,38 +493,4 @@ const prolongerLinks = [
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

@@ -126,12 +126,6 @@ const prolongerLinks = [
<span class="gic-aside__pill">
{doctrinesCount} doctrine{doctrinesCount > 1 ? "s" : ""}
</span>
<span class="gic-aside__pill">
{verbesCount} verbe{verbesCount > 1 ? "s" : ""}
</span>
<span class="gic-aside__pill">
{casIaCount} entrée{casIaCount > 1 ? "s" : ""} cas IA
</span>
</div>
<p class="gic-aside__note">
@@ -232,6 +226,8 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="gic-hero-more"
heroToggleId="gic-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<script is:inline>
@@ -265,30 +261,39 @@ const prolongerLinks = [
body.classList.add(BODY_CLASS);
const syncPremiumStickyMetrics = () => {
const hero = document.querySelector("[data-glossary-portal-hero]");
const followInner = follow.querySelector(".reading-follow__inner");
const heroH = hero ? Math.round(hero.getBoundingClientRect().height || 0) : 0;
const followOn =
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
const followH = followOn && followInner
? Math.round(followInner.getBoundingClientRect().height || 0)
: 0;
const lettersH =
!lettersFollow.hidden && lettersFollow.getAttribute("aria-hidden") === "false"
? Math.round(lettersFollow.getBoundingClientRect().height || 0)
: 0;
root.style.setProperty("--gic-premium-hero-h", `${heroH}px`);
root.style.setProperty("--gic-premium-follow-h", `${followH}px`);
root.style.setProperty("--gic-premium-letters-h", `${lettersH}px`);
};
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);
follow.style.display = "";
syncPremiumStickyMetrics();
};
const isCompactViewport = () =>
mqMobile.matches || mqSmallLandscape.matches;
const computeFollowOn = () =>
!isCompactViewport() &&
follow.classList.contains("is-on") &&
follow.style.display !== "none" &&
follow.getAttribute("aria-hidden") !== "true";
@@ -320,7 +325,7 @@ const prolongerLinks = [
};
const syncLettersDockState = () => {
if (mqMobile.matches || !computeFollowOn()) {
if (!computeFollowOn()) {
body.classList.remove(LETTERS_DOCKED_CLASS);
lettersFollow.hidden = true;
lettersFollow.setAttribute("aria-hidden", "true");
@@ -503,6 +508,7 @@ const prolongerLinks = [
forceHideGlobalFollowOnCompactViewport();
syncFollowLettersTop();
syncLettersDockState();
syncPremiumStickyMetrics();
syncActiveLetter();
});
};
@@ -565,6 +571,777 @@ const prolongerLinks = [
}
})();
</script>
<script is:inline>
/*
INDEX COMPLET — STACK PREMIUM MOBILE/TABLETTE V2
Principe :
- uniquement sur /glossaire/index-complet/ ;
- rail vertical calculé en pixels réels ;
- cockpit compact :
header → hero condensé → follow H2 compact → lettres horizontales.
*/
(() => {
const boot = () => {
const body = document.body;
const root = document.documentElement;
const hero = document.querySelector("[data-glossary-portal-hero]");
const follow = document.getElementById("reading-follow");
const inner = follow?.querySelector(".reading-follow__inner");
const lettersSource = document.getElementById("gic-letters-source");
const lettersFollow = document.getElementById("gic-follow-letters");
if (!body || !root || !hero || !follow || !inner || !lettersSource || !lettersFollow) return;
const mqCompact = window.matchMedia("(max-width: 980px)");
const mqSmallLandscape = window.matchMedia(
"(orientation: landscape) and (max-width: 920px) and (max-height: 520px)"
);
const isCompact = () => mqCompact.matches || mqSmallLandscape.matches;
const pxVar = (name, fallback = 0) => {
const raw = getComputedStyle(root).getPropertyValue(name).trim();
const n = Number.parseFloat(raw);
return Number.isFinite(n) ? n : fallback;
};
const stackTop = () => {
const glossaryTop = pxVar("--glossary-sticky-top", NaN);
if (Number.isFinite(glossaryTop) && glossaryTop > 0) return glossaryTop;
const headerH = pxVar("--sticky-header-h", 0);
const gap = pxVar("--page-gap", 12);
return Math.max(0, Math.round(headerH + gap));
};
const heads = Array.from(
document.querySelectorAll(".glossary-portal-section__head, .gic-section__head")
);
const titleOf = (head) => {
const h = head?.querySelector("h2, h3");
return (h?.textContent || head?.textContent || "")
.replace(/\s+/g, " ")
.trim();
};
const writeFollow = (title) => {
const h1 = inner.querySelector(".rf-h1");
const h2 = inner.querySelector(".rf-h2");
const h3 = inner.querySelector(".rf-h3");
if (h1) h1.textContent = "Index complet";
if (h2) h2.textContent = title || "Index alphabétique";
if (h3) h3.textContent = "";
follow.classList.add("is-on");
follow.setAttribute("aria-hidden", "false");
follow.style.setProperty("display", "block", "important");
inner.style.setProperty("display", "block", "important");
inner.style.setProperty("visibility", "visible", "important");
inner.style.setProperty("opacity", "1", "important");
body.classList.add("glossary-portal-follow-on", "gic-premium-follow-on");
};
const clearFollow = () => {
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
body.classList.remove(
"glossary-portal-follow-on",
"gic-premium-follow-on",
"gic-letters-docked",
"gic-premium-letters-on"
);
lettersFollow.hidden = true;
lettersFollow.setAttribute("aria-hidden", "true");
root.style.setProperty("--gic-premium-follow-h", "0px");
root.style.setProperty("--gic-premium-letters-h", "0px");
root.style.setProperty("--gic-stack-h", "0px");
root.style.setProperty("--gic-follow-letters-offset", "0px");
};
const currentHead = () => {
const top = stackTop();
const heroH = pxVar("--gic-premium-hero-h", 0);
const followH = pxVar("--gic-premium-follow-h", 0);
const lettersH = pxVar("--gic-premium-letters-h", 0);
const threshold = top + heroH + followH + lettersH + 18;
let current = null;
for (const head of heads) {
const r = head.getBoundingClientRect();
if (r.top <= threshold) current = head;
else break;
}
return current;
};
const measure = () => {
const heroH = body.classList.contains("glossary-portal-hero-condensed")
? Math.max(0, Math.round(hero.getBoundingClientRect().height || 0))
: 0;
const followH = body.classList.contains("gic-premium-follow-on")
? Math.max(0, Math.round(inner.getBoundingClientRect().height || 0))
: 0;
const lettersH = body.classList.contains("gic-premium-letters-on")
? Math.max(0, Math.round(lettersFollow.getBoundingClientRect().height || 0))
: 0;
const stackH = heroH + followH + lettersH;
root.style.setProperty("--gic-premium-top", `${stackTop()}px`);
root.style.setProperty("--gic-premium-hero-h", `${heroH}px`);
root.style.setProperty("--gic-premium-follow-h", `${followH}px`);
root.style.setProperty("--gic-premium-letters-h", `${lettersH}px`);
root.style.setProperty("--gic-stack-h", `${stackH}px`);
root.style.setProperty("--glossary-local-sticky-h", `${stackH}px`);
root.style.setProperty("--followbar-h", `${followH}px`);
root.style.setProperty("--sticky-offset-px", `${stackTop() + stackH + 12}px`);
};
const syncLetters = () => {
if (!body.classList.contains("gic-premium-follow-on")) {
body.classList.remove("gic-letters-docked", "gic-premium-letters-on");
lettersFollow.hidden = true;
lettersFollow.setAttribute("aria-hidden", "true");
root.style.setProperty("--gic-follow-letters-offset", "0px");
return;
}
const sourceRect = lettersSource.getBoundingClientRect();
const followBottom = stackTop() + pxVar("--gic-premium-hero-h", 0) + pxVar("--gic-premium-follow-h", 0);
const shouldDock = sourceRect.top <= followBottom + 8;
body.classList.toggle("gic-letters-docked", shouldDock);
body.classList.toggle("gic-premium-letters-on", shouldDock);
lettersFollow.hidden = !shouldDock;
lettersFollow.setAttribute("aria-hidden", shouldDock ? "false" : "true");
if (shouldDock) {
lettersFollow.style.setProperty("display", "flex", "important");
root.style.setProperty(
"--gic-follow-letters-offset",
`${Math.max(0, Math.round(lettersFollow.getBoundingClientRect().height || 0)) + 12}px`
);
} else {
root.style.setProperty("--gic-follow-letters-offset", "0px");
}
};
let raf = 0;
const sync = () => {
raf = 0;
body.classList.add("is-index-complet-page", "is-glossary-portal-page");
if (!isCompact()) {
body.classList.remove(
"gic-premium-compact",
"gic-premium-follow-on",
"gic-premium-letters-on"
);
hero.style.removeProperty("position");
hero.style.removeProperty("top");
hero.style.removeProperty("z-index");
follow.style.removeProperty("display");
follow.style.removeProperty("top");
follow.style.removeProperty("left");
follow.style.removeProperty("width");
lettersFollow.style.removeProperty("display");
lettersFollow.style.removeProperty("top");
lettersFollow.style.removeProperty("left");
lettersFollow.style.removeProperty("width");
return;
}
body.classList.add("gic-premium-compact");
const top = stackTop();
const scrollY = window.scrollY || window.pageYOffset || 0;
const heroRect = hero.getBoundingClientRect();
const condensed = scrollY > 8 && heroRect.top <= top + 8;
body.classList.toggle("glossary-portal-hero-condensed", condensed);
hero.style.setProperty("position", "sticky", "important");
hero.style.setProperty("top", `${top}px`, "important");
hero.style.setProperty("z-index", "72", "important");
if (!condensed) {
clearFollow();
measure();
return;
}
measure();
const head = currentHead();
const rawTitle = titleOf(head) || "Index alphabétique";
const title = /^[A-ZÀÂÄÇÉÈÊËÎÏÔÖÙÛÜŸ]$/i.test(rawTitle)
? "Index alphabétique"
: rawTitle;
writeFollow(title);
measure();
syncLetters();
measure();
};
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(sync);
};
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (document.fonts?.ready) {
document.fonts.ready.then(schedule).catch(() => {});
}
if (mqCompact.addEventListener) mqCompact.addEventListener("change", schedule);
else if (mqCompact.addListener) mqCompact.addListener(schedule);
if (mqSmallLandscape.addEventListener) mqSmallLandscape.addEventListener("change", schedule);
else if (mqSmallLandscape.addListener) mqSmallLandscape.addListener(schedule);
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
<style is:global>
/* INDEX COMPLET — STACK PREMIUM MOBILE/TABLETTE V2 */
@media (max-width: 980px){
body.is-index-complet-page.gic-premium-compact{
scroll-padding-top: calc(var(--gic-premium-top, 0px) + var(--gic-stack-h, 0px) + 16px);
}
body.is-index-complet-page.gic-premium-compact .glossary-portal-hero,
body.is-index-complet-page.gic-premium-compact .glossary-page-hero{
position: sticky !important;
top: var(--gic-premium-top, var(--glossary-sticky-top, 0px)) !important;
z-index: 72 !important;
overflow: hidden !important;
margin-bottom: 12px !important;
transform: translateZ(0) !important;
backface-visibility: hidden !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero,
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-page-hero{
padding: 7px 10px 7px !important;
row-gap: 3px !important;
border-radius: 14px 14px 0 0 !important;
margin-bottom: 0 !important;
box-shadow: 0 12px 30px rgba(0,0,0,.24) !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero__kicker{
font-size: 8px !important;
line-height: 1 !important;
letter-spacing: .105em !important;
opacity: .66 !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero h1{
font-size: clamp(1.18rem, 4.8vw, 1.48rem) !important;
line-height: 1 !important;
letter-spacing: -.028em !important;
margin: 0 !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro{
display: -webkit-box !important;
-webkit-box-orient: vertical !important;
-webkit-line-clamp: 1 !important;
line-clamp: 1 !important;
max-height: 1.12em !important;
overflow: hidden !important;
font-size: .66rem !important;
line-height: 1.12 !important;
opacity: .72 !important;
margin: 0 !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__more{
max-height: 0 !important;
opacity: 0 !important;
overflow: hidden !important;
pointer-events: none !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero__toggle{
display: none !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow{
display: block !important;
position: fixed !important;
left: var(--reading-left) !important;
width: var(--reading-width) !important;
top: calc(var(--gic-premium-top, 0px) + var(--gic-premium-hero-h, 0px) - 1px) !important;
z-index: 71 !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
body.is-index-complet-page.gic-premium-compact.gic-premium-follow-on #reading-follow{
opacity: 1 !important;
visibility: visible !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow .reading-follow__inner{
display: block !important;
visibility: visible !important;
opacity: 1 !important;
max-height: none !important;
min-height: 0 !important;
margin-top: 0 !important;
padding: 5px 56px 5px 9px !important;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
box-shadow: 0 8px 18px rgba(0,0,0,.16) !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow .rf-h1,
body.is-index-complet-page.gic-premium-compact #reading-follow .rf-h3,
body.is-index-complet-page.gic-premium-compact #reading-follow .rf-actions{
display: none !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow .rf-h2{
display: block !important;
font-size: .78rem !important;
line-height: 1.08 !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
letter-spacing: -.012em !important;
}
body.is-index-complet-page.gic-premium-compact #gic-follow-letters{
position: fixed !important;
left: var(--reading-left) !important;
width: var(--reading-width) !important;
top: calc(
var(--gic-premium-top, 0px)
+ var(--gic-premium-hero-h, 0px)
+ var(--gic-premium-follow-h, 0px)
- 1px
) !important;
z-index: 70 !important;
display: none !important;
flex-wrap: nowrap !important;
gap: 6px !important;
overflow-x: auto !important;
overflow-y: hidden !important;
scrollbar-width: none !important;
-webkit-overflow-scrolling: touch !important;
margin: 0 !important;
padding: 6px 8px 7px !important;
border-radius: 0 0 12px 12px !important;
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
body.is-index-complet-page.gic-premium-compact #gic-follow-letters::-webkit-scrollbar{
display: none !important;
}
body.is-index-complet-page.gic-premium-compact #gic-follow-letters a{
flex: 0 0 auto !important;
min-width: 28px !important;
height: 28px !important;
padding: 0 9px !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
}
body.is-index-complet-page.gic-premium-compact.gic-premium-letters-on #gic-follow-letters{
display: flex !important;
opacity: 1 !important;
visibility: visible !important;
pointer-events: auto !important;
}
body.is-index-complet-page.gic-premium-compact .gic-section,
body.is-index-complet-page.gic-premium-compact .gic-group,
body.is-index-complet-page.gic-premium-compact .glossary-portal-section{
scroll-margin-top: calc(var(--gic-premium-top, 0px) + var(--gic-stack-h, 0px) + 18px) !important;
}
}
@media (min-width: 761px) and (max-width: 980px){
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero,
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-page-hero{
padding: 8px 12px 8px !important;
border-radius: 16px 16px 0 0 !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero h1{
font-size: clamp(1.48rem, 3vw, 1.82rem) !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro{
font-size: .76rem !important;
line-height: 1.14 !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow .rf-h2{
font-size: .86rem !important;
}
}
@media (orientation: landscape) and (max-width: 920px) and (max-height: 520px){
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero,
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-page-hero{
padding: 5px 8px 5px !important;
row-gap: 2px !important;
border-radius: 12px 12px 0 0 !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed .glossary-portal-hero h1{
font-size: clamp(1rem, 3vw, 1.22rem) !important;
}
body.is-index-complet-page.gic-premium-compact.glossary-portal-hero-condensed:not(.glossary-portal-hero-expanded) .glossary-portal-hero__intro{
display: none !important;
}
body.is-index-complet-page.gic-premium-compact #reading-follow .reading-follow__inner{
padding-top: 4px !important;
padding-bottom: 4px !important;
}
body.is-index-complet-page.gic-premium-compact #gic-follow-letters{
padding-top: 4px !important;
padding-bottom: 5px !important;
}
body.is-index-complet-page.gic-premium-compact #gic-follow-letters a{
min-width: 24px !important;
height: 24px !important;
padding: 0 7px !important;
}
}
</style>
<script is:inline>
/*
INDEX COMPLET — FOLLOW LABEL ET STABILITÉ DESKTOP
Sur cette page, les sections alphabétiques A/B/C… ne doivent pas
devenir le titre du reading-follow : la lettre active est déjà
portée par la barre alphabétique.
*/
(() => {
const boot = () => {
const body = document.body;
const follow = document.getElementById("reading-follow");
const inner = follow?.querySelector(".reading-follow__inner");
if (!body || !follow || !inner) return;
const LETTER_RE = /^[A-ZÀÂÄÇÉÈÊËÎÏÔÖÙÛÜŸ]$/i;
const normalize = () => {
if (!body.classList.contains("is-index-complet-page")) return;
const h1 = inner.querySelector(".rf-h1");
const h2 = inner.querySelector(".rf-h2");
const h3 = inner.querySelector(".rf-h3");
const txt = (h2?.textContent || "").replace(/\s+/g, " ").trim();
if (
h2 &&
(
LETTER_RE.test(txt) ||
body.classList.contains("gic-letters-docked") ||
body.classList.contains("gic-premium-letters-on")
)
) {
if (h1) h1.textContent = "Index complet du glossaire";
h2.textContent = "Index alphabétique";
if (h3) h3.textContent = "";
}
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
normalize();
});
};
const observer = new MutationObserver(schedule);
observer.observe(body, {
attributes: true,
attributeFilter: ["class"],
});
observer.observe(inner, {
childList: true,
subtree: true,
characterData: true,
});
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
<style is:global>
/* INDEX COMPLET — FOLLOW LABEL ET STABILITÉ DESKTOP */
@media (min-width: 981px){
body.is-index-complet-page.glossary-portal-follow-on #reading-follow{
top: calc(
var(--glossary-sticky-top, var(--sticky-header-h, 0px))
+ var(--glossary-local-sticky-h, 0px)
- 1px
) !important;
z-index: 71 !important;
}
body.is-index-complet-page.gic-letters-docked #gic-follow-letters{
top: calc(
var(--glossary-sticky-top, var(--sticky-header-h, 0px))
+ var(--glossary-local-sticky-h, 0px)
+ var(--followbar-h, 0px)
- 1px
) !important;
z-index: 70 !important;
}
body.is-index-complet-page.gic-letters-docked #reading-follow .rf-h2{
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
}
</style>
<script is:inline>
/*
INDEX COMPLET — DESKTOP FOLLOW GATE
Le reading-follow ne doit pas apparaître en haut de page.
Il devient visible seulement lorsque le hero est effectivement condensé.
*/
(() => {
const boot = () => {
const body = document.body;
const hero = document.querySelector("[data-glossary-portal-hero]");
const follow = document.getElementById("reading-follow");
if (!body || !hero || !follow) return;
const mqDesktop = window.matchMedia("(min-width: 981px)");
const sync = () => {
if (!mqDesktop.matches) {
body.classList.remove("gic-desktop-follow-gated");
return;
}
const condensed = body.classList.contains("glossary-portal-hero-condensed");
body.classList.toggle("gic-desktop-follow-gated", !condensed);
if (!condensed) {
follow.classList.remove("is-on");
follow.setAttribute("aria-hidden", "true");
}
};
let raf = 0;
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(() => {
raf = 0;
sync();
});
};
const observer = new MutationObserver(schedule);
observer.observe(body, {
attributes: true,
attributeFilter: ["class"],
});
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (mqDesktop.addEventListener) mqDesktop.addEventListener("change", schedule);
else if (mqDesktop.addListener) mqDesktop.addListener(schedule);
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
<style is:global>
/* INDEX COMPLET — DESKTOP FOLLOW GATE */
@media (min-width: 981px){
body.is-index-complet-page.gic-desktop-follow-gated #reading-follow,
body.is-index-complet-page.gic-desktop-follow-gated #reading-follow .reading-follow__inner{
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
body.is-index-complet-page.gic-desktop-follow-gated #gic-follow-letters{
opacity: 0 !important;
visibility: hidden !important;
pointer-events: none !important;
}
}
</style>
<script is:inline>
/*
INDEX COMPLET — AUTO-CENTER ACTIVE LETTER
Sur mobile, la barre alphabétique horizontale doit suivre le lecteur :
la lettre active est automatiquement recentrée dans gic-follow-letters.
*/
(() => {
const boot = () => {
const body = document.body;
const lettersFollow = document.getElementById("gic-follow-letters");
if (!body || !lettersFollow) return;
const mqCompact = window.matchMedia("(max-width: 760px)");
let lastHref = "";
let raf = 0;
const centerActiveLetter = () => {
raf = 0;
if (!mqCompact.matches) return;
if (!body.classList.contains("is-index-complet-page")) return;
if (!body.classList.contains("gic-premium-letters-on")) return;
const active =
lettersFollow.querySelector('a[aria-current="true"]') ||
lettersFollow.querySelector("a.is-active");
if (!active) return;
const href = active.getAttribute("href") || "";
const force = href !== lastHref;
lastHref = href;
const containerRect = lettersFollow.getBoundingClientRect();
const activeRect = active.getBoundingClientRect();
const activeCenter =
activeRect.left - containerRect.left + lettersFollow.scrollLeft + activeRect.width / 2;
const target =
activeCenter - lettersFollow.clientWidth / 2;
const max =
lettersFollow.scrollWidth - lettersFollow.clientWidth;
const next = Math.max(0, Math.min(max, Math.round(target)));
if (force || Math.abs(lettersFollow.scrollLeft - next) > 6) {
lettersFollow.scrollTo({
left: next,
behavior: "smooth",
});
}
};
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(centerActiveLetter);
};
const observer = new MutationObserver(schedule);
observer.observe(lettersFollow, {
subtree: true,
attributes: true,
attributeFilter: ["class", "aria-current"],
});
observer.observe(body, {
attributes: true,
attributeFilter: ["class"],
});
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
window.addEventListener("pageshow", schedule);
if (mqCompact.addEventListener) mqCompact.addEventListener("change", schedule);
else if (mqCompact.addListener) mqCompact.addListener(schedule);
schedule();
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot, { once: true });
} else {
boot();
}
})();
</script>
</GlossaryLayout>
<style>
@@ -1041,4 +1818,5 @@ const prolongerLinks = [
--sticky-offset-px: calc(var(--sticky-header-h, 0px) + var(--page-gap, 12px)) !important;
}
}
</style>

View File

@@ -351,6 +351,7 @@ const approfondirPortalItems = [
let raf = 0;
let activeHeading = null;
let clearTimer = 0;
let homeFollowOn = false;
function syncStickyTop() {
const headerHeight = header.getBoundingClientRect().height || 0;
@@ -368,8 +369,15 @@ const approfondirPortalItems = [
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 compactHomeSticky = window.matchMedia("(max-width: 980px)").matches;
const scaledFontSize = compactHomeSticky
? Math.min(20, Math.max(14, sourceFontSize * 0.56))
: Math.max(28, sourceFontSize * 0.9);
const scaledLineHeight = compactHomeSticky
? Math.max(scaledFontSize * 1.08, 16)
: Math.max(scaledFontSize * 1.04, sourceLineHeight * 0.92);
toEl.style.fontSize = `${scaledFontSize}px`;
toEl.style.lineHeight = `${scaledLineHeight}px`;
@@ -469,6 +477,7 @@ const approfondirPortalItems = [
function updateFollow() {
syncStickyTop();
const compactHomeSticky = window.matchMedia("(max-width: 980px)").matches;
const heroRect = hero.getBoundingClientRect();
const active = getCurrentHeading();
@@ -478,9 +487,23 @@ const approfondirPortalItems = [
.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;
const scrollY = window.scrollY || window.pageYOffset || 0;
const hasStartedScrolling = scrollY > 8;
const heroDocked = compactHomeSticky
? heroRect.top <= stickyTop + 8
: Math.abs(heroRect.top - stickyTop) <= 6;
const enterFollow = hasStartedScrolling && heroDocked;
const exitFollow = !hasStartedScrolling || heroRect.top > stickyTop + (compactHomeSticky ? 28 : 12);
if (enterFollow) {
homeFollowOn = true;
} else if (exitFollow) {
homeFollowOn = false;
}
const heroOut = homeFollowOn;
document.body.classList.toggle("glossary-home-follow-on", heroOut);
@@ -569,7 +592,7 @@ const approfondirPortalItems = [
}
.glossary-map-block{
padding: 18px 18px 20px;
padding: 16px 18px 18px;
border: 1px solid var(--glossary-border);
border-radius: 24px;
background: rgba(127,127,127,0.04);
@@ -577,9 +600,9 @@ const approfondirPortalItems = [
.glossary-map-block__head p{
max-width: 76ch;
margin: 12px 0 0;
font-size: 1rem;
line-height: 1.55;
margin: 9px 0 0;
font-size: .98rem;
line-height: 1.46;
opacity: .94;
text-wrap: pretty;
}
@@ -587,28 +610,56 @@ const approfondirPortalItems = [
.glossary-map{
display: grid;
justify-items: center;
gap: 10px;
margin-top: 18px;
gap: 6px;
margin-top: 14px;
}
.glossary-map__stage{
width: min(580px, 100%);
display: grid;
justify-items: center;
gap: 10px;
gap: 6px;
}
.glossary-map__title{
width: 100%;
text-align: center;
font-size: 1.08rem;
line-height: 1.25;
font-size: .98rem;
line-height: 1.16;
font-weight: 800;
letter-spacing: -.01em;
opacity: .96;
text-wrap: balance;
}
.glossary-map__node{
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 42px;
padding: 8px 14px;
border: 1px solid var(--glossary-border-strong);
border-radius: 999px;
background: var(--glossary-bg-soft);
color: var(--glossary-accent);
text-decoration: none;
text-align: center;
font-size: .94rem;
font-weight: 800;
letter-spacing: .04em;
line-height: 1.16;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease;
}
.glossary-map__arrow{
font-size: 1.18rem;
line-height: .9;
opacity: .68;
}
.glossary-map__roots{
width: 100%;
display: grid;
@@ -616,28 +667,6 @@ const approfondirPortalItems = [
gap: 8px;
}
.glossary-map__node{
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 50px;
padding: 10px 14px;
border: 1px solid var(--glossary-border-strong);
border-radius: 999px;
background: var(--glossary-bg-soft);
color: var(--glossary-accent);
text-decoration: none;
text-align: center;
font-size: .99rem;
font-weight: 800;
letter-spacing: .04em;
line-height: 1.2;
transition:
transform 120ms ease,
background 120ms ease,
border-color 120ms ease;
}
.glossary-map__node:hover{
background: var(--glossary-bg-soft-strong);
border-color: rgba(0,217,255,0.22);
@@ -650,12 +679,6 @@ const approfondirPortalItems = [
max-width: 100%;
}
.glossary-map__arrow{
font-size: 1.45rem;
line-height: 1;
opacity: .72;
}
.glossary-portal-card strong{
color: var(--glossary-accent);
font-size: 1.08rem;
@@ -720,11 +743,17 @@ const approfondirPortalItems = [
.glossary-map-block__head h2,
.glossary-section h2{
font-size: clamp(1.5rem, 7vw, 1.95rem);
line-height: 1.04;
font-size: clamp(1.42rem, 6.3vw, 1.82rem);
line-height: 1.03;
letter-spacing: -.022em;
}
.glossary-map-block__head h2{
hyphens: none;
word-break: normal;
overflow-wrap: normal;
}
.glossary-map-block__head p,
.glossary-intro{
font-size: .9rem;
@@ -742,35 +771,36 @@ const approfondirPortalItems = [
}
.glossary-map{
gap: 7px;
margin-top: 12px;
gap: 4px;
margin-top: 10px;
}
.glossary-map__stage{
gap: 7px;
gap: 4px;
width: 100%;
}
.glossary-map__title{
font-size: .9rem;
line-height: 1.2;
font-size: .82rem;
line-height: 1.12;
}
.glossary-map__roots{
grid-template-columns: 1fr;
gap: 6px;
gap: 5px;
}
.glossary-map__node{
min-height: 38px;
padding: 8px 10px;
font-size: .84rem;
line-height: 1.15;
min-height: 32px;
padding: 6px 10px;
font-size: .78rem;
line-height: 1.12;
}
.glossary-map__arrow{
font-size: 1rem;
opacity: .62;
font-size: .92rem;
line-height: .8;
opacity: .6;
}
}
@@ -804,23 +834,28 @@ const approfondirPortalItems = [
}
.glossary-map{
gap: 5px;
margin-top: 10px;
gap: 3px;
margin-top: 8px;
}
.glossary-map__stage{
gap: 5px;
gap: 3px;
}
.glossary-map__title{
font-size: .8rem;
line-height: 1.12;
font-size: .74rem;
line-height: 1.08;
}
.glossary-map__node{
min-height: 32px;
padding: 6px 8px;
font-size: .74rem;
min-height: 28px;
padding: 5px 8px;
font-size: .7rem;
}
.glossary-map__arrow{
font-size: .82rem;
line-height: .75;
}
.glossary-home .glossary-card,

View File

@@ -663,80 +663,10 @@ const usefulLinks = [
<GlossaryPortalStickySync
heroMoreId="pa-hero-more"
heroToggleId="pa-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -1072,38 +1002,4 @@ const usefulLinks = [
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

@@ -211,80 +211,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="theo-hero-more"
heroToggleId="theo-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -390,38 +320,4 @@ const prolongerLinks = [
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

@@ -313,80 +313,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="scene-hero-more"
heroToggleId="scene-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -523,38 +453,4 @@ const prolongerLinks = [
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

@@ -340,80 +340,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="tir-hero-more"
heroToggleId="tir-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -564,38 +494,4 @@ const prolongerLinks = [
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

@@ -256,6 +256,8 @@ const matrix = [
<GlossaryPortalStickySync
heroMoreId="topo-hero-more"
heroToggleId="topo-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
</GlossaryLayout>

View File

@@ -327,80 +327,10 @@ const prolongerLinks = [
<GlossaryPortalStickySync
heroMoreId="verbs-hero-more"
heroToggleId="verbs-hero-toggle"
mobileBreakpoint={980}
compactSticky={true}
/>
<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>
@@ -480,38 +410,4 @@ const prolongerLinks = [
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>