/* ============================================================ ZoomControl — Contrôle de zoom bas-gauche Même langage visuel que ContextualNavbar / navbar-content ============================================================ */ .zoom-control { position: fixed; bottom: 20px; left: 20px; z-index: 1000; animation: zoomControlSlideIn 0.6s cubic-bezier(0.22, 1, 0.36, 1); } @keyframes zoomControlSlideIn { from { opacity: 0; transform: translateY(20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } /* ============================================================ Bouton principal — pill solo identique à navbar-content ============================================================ */ .zoom-button { position: relative; width: 46px; height: 46px; border-radius: 50%; /* Même pastille que la barre d'actions */ background: var(--pz-surface); border: 1px solid var(--pz-line); box-shadow: var(--pz-shadow-lg); cursor: pointer; display: flex; align-items: center; justify-content: center; /* Même comportement que nav-button */ color: #2A2622; transition: border-color 160ms ease, transform 140ms var(--pz-ease); } @media (hover: hover) and (pointer: fine) { .zoom-button:hover { border-color: var(--pz-a300); } } .zoom-button:active { transform: scale(0.95); } .zoom-btn-icon { color: #2A2622; filter: drop-shadow(0 1px 2px rgba(42, 38, 34, 0.05)); transition: color 0.2s ease, transform 0.2s ease; } .zoom-button:hover .zoom-btn-icon { color: #93402A; } /* ============================================================ Panel slider (desktop, apparaît au hover) Même style que .navbar-annot-panel ============================================================ */ .zoom-slider-panel { position: absolute; bottom: calc(100% + 10px); left: 50%; width: 52px; padding: 14px 0 12px; /* Même panel que navbar-annot-panel */ background: var(--pz-surface); border: 1px solid var(--pz-line); border-radius: 999px; box-shadow: var(--pz-shadow-lg); display: flex; flex-direction: column; align-items: center; gap: 8px; /* Caché par défaut */ max-height: 0; overflow: hidden; opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(8px) scale(0.94); transition: max-height 0.35s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.25s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1); } .zoom-slider-panel.visible { max-height: 240px; opacity: 1; transform: translateX(-50%) translateY(0) scale(1); pointer-events: auto; } .zoom-panel-icon { color: #2A2622; opacity: 0.6; flex-shrink: 0; } /* ============================================================ Slider track custom ============================================================ */ .zoom-slider-track { width: 4px; height: 120px; background: var(--pz-line); border-radius: 3px; position: relative; cursor: ns-resize; flex-shrink: 0; user-select: none; } /* Zone de clic élargie */ .zoom-slider-track::before { content: ''; position: absolute; inset: 0 -12px; } .zoom-slider-fill { position: absolute; bottom: 0; left: 0; right: 0; background: var(--pz-a500); border-radius: 3px; pointer-events: none; } .zoom-slider-thumb { position: absolute; left: 50%; transform: translateX(-50%); width: 16px; height: 16px; background: var(--pz-ink); border: 3px solid var(--pz-surface); border-radius: 50%; box-shadow: 0 1px 4px rgba(42, 38, 34, 0.3); pointer-events: none; transition: transform 0.15s ease, border-color 0.15s ease; } .zoom-slider-track:hover .zoom-slider-thumb { transform: translateX(-50%) scale(1.15); } /* ============================================================ Responsive mobile ============================================================ */ @media (max-width: 768px) { .zoom-control { bottom: 12px; left: 12px; } .zoom-button { width: 44px; height: 44px; } /* Slider toujours visible sur mobile */ .zoom-slider-panel.visible { max-height: 240px; opacity: 1; transform: translateX(-50%) translateY(0) scale(1); pointer-events: auto; } .zoom-slider-track { cursor: pointer; } }