/** * Topbar - Défilement vertical (bas → haut) — Responsive auto-hauteur * Thème : Botiga / WooCommerce * Fichier : topbar-vertical.css *//* ─── Variables ────────────────────────────────────────────── */ :root { --topbar-bg: #1a1a1a; --topbar-color: #ffffff; --topbar-link-color: #d4af7a; --topbar-min-height: 40px; --topbar-font-size: 13px; --topbar-line-height: 1.5; --topbar-padding-v: 10px; --topbar-padding-h: 40px; --topbar-font-family: inherit; --topbar-speed: 500ms; --topbar-pause: 4000ms; }/* ─── Wrapper principal ────────────────────────────────────── */ #topbar-vertical { position: relative; z-index: 9999; width: 100%; min-height: var(--topbar-min-height); /* Hauteur pilotée par JS — transition douce entre messages */ transition: height var(--topbar-speed) cubic-bezier(0.4, 0, 0.2, 1); background-color: var(--topbar-bg); color: var(--topbar-color); font-family: var(--topbar-font-family); font-size: var(--topbar-font-size); line-height: var(--topbar-line-height); overflow: hidden; }/* ─── Zone de défilement ───────────────────────────────────── */ .topbar-track { position: relative; width: 100%; height: 100%; }/* ─── Messages individuels ─────────────────────────────────── */ .topbar-item { position: absolute; top: 0; left: 0; width: 100%; padding: var(--topbar-padding-v) var(--topbar-padding-h); box-sizing: border-box;display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 6px; text-align: center;transform: translateY(100%); opacity: 0; transition: transform var(--topbar-speed) cubic-bezier(0.4, 0, 0.2, 1), opacity var(--topbar-speed) cubic-bezier(0.4, 0, 0.2, 1); }/* Conteneur interne : gère le saut de ligne et le clamp */ .topbar-item-inner { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; /* Max 4 lignes */ overflow: hidden; text-align: center; word-break: break-word; white-space: normal; }.topbar-item.is-active { transform: translateY(0); opacity: 1; } .topbar-item.is-leaving { transform: translateY(-100%); opacity: 0; }/* ─── Lien CTA ─────────────────────────────────────────────── */ .topbar-item a { color: var(--topbar-link-color); text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; flex-shrink: 0; transition: opacity 0.2s; }.topbar-item a:hover { opacity: 0.75; }/* ─── Élément fantôme — mesure de hauteur ──────────────────── */ .topbar-measurer { position: absolute; top: 0; left: 0; width: 100%; padding: var(--topbar-padding-v) var(--topbar-padding-h); box-sizing: border-box; visibility: hidden; pointer-events: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0 6px; white-space: normal; word-break: break-word; font-size: var(--topbar-font-size); line-height: var(--topbar-line-height); font-family: var(--topbar-font-family); }/* ─── Bouton Fermer ────────────────────────────────────────── */ .topbar-close { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; background: none; border: none; cursor: pointer; color: rgba(255, 255, 255, 0.6); padding: 0; z-index: 10; display: flex; align-items: center; justify-content: center; transition: color 0.2s; }.topbar-close:hover { color: #fff; }.topbar-close svg { width: 10px; height: 10px; stroke: currentColor; stroke-width: 2; }/* ─── État fermé ───────────────────────────────────────────── */ #topbar-vertical.is-hidden { display: none; }/* ─── Responsive ───────────────────────────────────────────── */ @media (max-width: 768px) { :root { --topbar-font-size: 12px; --topbar-padding-v: 10px; --topbar-padding-h: 36px; } }@media (max-width: 480px) { :root { --topbar-font-size: 11.5px; --topbar-padding-h: 32px; } }
/** * Topbar - Défilement vertical (bas → haut) — Responsive auto-hauteur * Thème : Botiga / WooCommerce * Fichier : topbar-vertical.js */(function () { 'use strict';const STORAGE_KEY = 'topbar_vertical_closed';document.addEventListener('DOMContentLoaded', function () { const bar = document.getElementById('topbar-vertical'); if (!bar) return;/* Fermé dans la session → on masque directement */ if (sessionStorage.getItem(STORAGE_KEY) === '1') { bar.classList.add('is-hidden'); return; }const items = bar.querySelectorAll('.topbar-item'); const measurer = bar.querySelector('.topbar-measurer'); const closeBtn = bar.querySelector('.topbar-close');if (!items.length) return;/* ─── Lecture des CSS vars ────────────────────────────── */ function getCssMs(prop, fallback) { const val = getComputedStyle(document.documentElement) .getPropertyValue(prop).trim(); return parseInt(val) || fallback; }/* ─── Mesure la hauteur naturelle d'un item ──────────── */ /* * On copie le contenu de l'item dans l'élément fantôme * (.topbar-measurer), qui est position:absolute; visibility:hidden * → rendu en DOM, invisible, mesurable via offsetHeight. */ function measureHeight(index) { if (!measurer) return bar.offsetHeight; measurer.innerHTML = items[index].innerHTML; return measurer.offsetHeight; }/* ─── Applique la hauteur au wrapper ─────────────────── */ function applyHeight(index) { const h = measureHeight(index); bar.style.height = h + 'px'; }/* ─── Variables d'état ───────────────────────────────── */ let current = 0; let timer = null; let isRunning = true;/* ─── Afficher un message ────────────────────────────── */ function showItem(nextIndex) { const prev = current; current = nextIndex; const speed = getCssMs('--topbar-speed', 500);/* 1. Animer la hauteur vers celle du prochain message */ applyHeight(current);/* 2. Sortie de l'ancien (vers le haut) */ items[prev].classList.remove('is-active'); items[prev].classList.add('is-leaving');setTimeout(function () { items[prev].classList.remove('is-leaving'); }, speed);/* 3. Entrée du nouveau (depuis le bas) */ items[current].classList.add('is-active'); }/* ─── Défilement automatique ─────────────────────────── */ function startTicker() { clearInterval(timer); const pause = getCssMs('--topbar-pause', 4000); timer = setInterval(function () { if (!isRunning) return; showItem((current + 1) % items.length); }, pause); }/* ─── Pause au survol ────────────────────────────────── */ bar.addEventListener('mouseenter', function () { isRunning = false; }); bar.addEventListener('mouseleave', function () { isRunning = true; });/* ─── Bouton Fermer ──────────────────────────────────── */ if (closeBtn) { closeBtn.addEventListener('click', function () { clearInterval(timer); bar.classList.add('is-hidden'); sessionStorage.setItem(STORAGE_KEY, '1'); }); }/* ─── Recalcul hauteur au resize (orientation mobile) ── */ var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { applyHeight(current); }, 100); });/* ─── Démarrage ──────────────────────────────────────── */ /* Un seul message : pas de ticker, juste afficher */ if (items.length === 1) { items[0].classList.add('is-active'); applyHeight(0); return; }items[0].classList.add('is-active'); applyHeight(0); startTicker(); }); })();