diff --git a/src/components/GlossaryHomeHero.astro b/src/components/GlossaryHomeHero.astro index ed7b879..5b2e5f2 100644 --- a/src/components/GlossaryHomeHero.astro +++ b/src/components/GlossaryHomeHero.astro @@ -540,4 +540,209 @@ const { 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; + } + } + \ No newline at end of file diff --git a/src/layouts/EditionLayout.astro b/src/layouts/EditionLayout.astro index 2ffc20f..ad177df 100644 --- a/src/layouts/EditionLayout.astro +++ b/src/layouts/EditionLayout.astro @@ -931,7 +931,7 @@ 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"])) .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, diff --git a/src/pages/glossaire/index.astro b/src/pages/glossaire/index.astro index fd1a959..c838011 100644 --- a/src/pages/glossaire/index.astro +++ b/src/pages/glossaire/index.astro @@ -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);