diff --git a/src/components/GlossaryPortalStickySync.astro b/src/components/GlossaryPortalStickySync.astro index c939e21..7c71acc 100644 --- a/src/components/GlossaryPortalStickySync.astro +++ b/src/components/GlossaryPortalStickySync.astro @@ -34,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"; @@ -49,14 +50,18 @@ 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 = () => - body.classList.contains("is-index-complet-page"); + Boolean(compactSticky) || body.classList.contains("is-index-complet-page"); const compactShouldDisablePortal = () => isCompactViewport() && !keepPortalPremiumOnCompact(); @@ -78,7 +83,40 @@ 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 = () => + body.classList.contains(CONDENSED_CLASS) && (!isCompactViewport() || compactStickyEnabled()) && follow.classList.contains("is-on") && follow.style.display !== "none" && @@ -87,10 +125,7 @@ const { const computeCondensed = () => { if (isCompactViewport() && !compactStickyEnabled()) return false; - const heroRect = hero.getBoundingClientRect(); - const stickyTop = readStickyTop(); - - return heroRect.top <= stickyTop + 2; + return hasReachedHeroPinStart(); }; const measureHeroHeight = () => @@ -107,10 +142,60 @@ 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 l’edition-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 l’index 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 = () => { @@ -227,6 +312,226 @@ 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() && !compactStickyEnabled()) { @@ -257,6 +562,7 @@ const { const syncAll = () => { stripLocalSticky(); + applyCompactHeroRail(); if (isCompactViewport() && !compactStickyEnabled()) { body.classList.remove(FOLLOW_ON_CLASS); @@ -291,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 {} @@ -335,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(() => {}); @@ -354,6 +684,9 @@ const { mqSmallLandscape.addListener(schedule); } + applyCompactHeroRail(); + applyCompactFollowRail(); + captureHeroPinStart(true); schedule(); }; @@ -441,65 +774,65 @@ const { } @media (max-width: 860px){ - :global(body.is-glossary-portal-page:not(.is-index-complet-page) #reading-follow), - :global(body.is-glossary-portal-page:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-page) #reading-follow), - :global(body.is-glossary-portal-page:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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:not(.is-index-complet-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; } } @@ -571,4 +904,279 @@ const { } } + /* 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 l’edition-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 l’edition-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 */ + \ No newline at end of file diff --git a/src/pages/glossaire/archicrations.astro b/src/pages/glossaire/archicrations.astro index 2c5f467..80d5085 100644 --- a/src/pages/glossaire/archicrations.astro +++ b/src/pages/glossaire/archicrations.astro @@ -218,81 +218,10 @@ const prolongerLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/concepts-fondamentaux.astro b/src/pages/glossaire/concepts-fondamentaux.astro index 2b512ea..89aaa74 100644 --- a/src/pages/glossaire/concepts-fondamentaux.astro +++ b/src/pages/glossaire/concepts-fondamentaux.astro @@ -328,6 +328,8 @@ const prolongerLinks = [ diff --git a/src/pages/glossaire/dynamiques-archicratiques.astro b/src/pages/glossaire/dynamiques-archicratiques.astro index 40b7df5..8ca1103 100644 --- a/src/pages/glossaire/dynamiques-archicratiques.astro +++ b/src/pages/glossaire/dynamiques-archicratiques.astro @@ -335,80 +335,10 @@ const prolongerLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/paradigme-archicratique.astro b/src/pages/glossaire/paradigme-archicratique.astro index 07da752..abf8448 100644 --- a/src/pages/glossaire/paradigme-archicratique.astro +++ b/src/pages/glossaire/paradigme-archicratique.astro @@ -663,80 +663,10 @@ const usefulLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/paradigmes.astro b/src/pages/glossaire/paradigmes.astro index bb6c995..0d939c6 100644 --- a/src/pages/glossaire/paradigmes.astro +++ b/src/pages/glossaire/paradigmes.astro @@ -211,80 +211,10 @@ const prolongerLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/scenes-archicratiques.astro b/src/pages/glossaire/scenes-archicratiques.astro index bd992fc..44fdecc 100644 --- a/src/pages/glossaire/scenes-archicratiques.astro +++ b/src/pages/glossaire/scenes-archicratiques.astro @@ -313,80 +313,10 @@ const prolongerLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/tensions-irreductibles.astro b/src/pages/glossaire/tensions-irreductibles.astro index 38cbf3c..8cae149 100644 --- a/src/pages/glossaire/tensions-irreductibles.astro +++ b/src/pages/glossaire/tensions-irreductibles.astro @@ -340,80 +340,10 @@ const prolongerLinks = [ - \ No newline at end of file diff --git a/src/pages/glossaire/topologie-regimes-regulation.astro b/src/pages/glossaire/topologie-regimes-regulation.astro index e34097d..5819625 100644 --- a/src/pages/glossaire/topologie-regimes-regulation.astro +++ b/src/pages/glossaire/topologie-regimes-regulation.astro @@ -256,6 +256,8 @@ const matrix = [ diff --git a/src/pages/glossaire/verbes-de-la-scene.astro b/src/pages/glossaire/verbes-de-la-scene.astro index 44d8384..45dcea8 100644 --- a/src/pages/glossaire/verbes-de-la-scene.astro +++ b/src/pages/glossaire/verbes-de-la-scene.astro @@ -327,80 +327,10 @@ const prolongerLinks = [ - \ No newline at end of file