diff --git a/prototyp-app.html b/prototyp-app.html index 849ff99..a0228b1 100644 --- a/prototyp-app.html +++ b/prototyp-app.html @@ -178,7 +178,8 @@ #explore{padding:0; --xs:max(env(safe-area-inset-top, 0px), 64px);} #explore.active{display:flex; flex-direction:column; height:100dvh; overflow:hidden;} .x-blur{position:absolute; inset:-50px; pointer-events:none; z-index:0; - filter:blur(36px) brightness(.78) saturate(1.15); transform:scale(1.08); transition:background .3s;} + filter:blur(36px) brightness(.78) saturate(1.15); transform:scale(1.08); + transition:background .7s ease, opacity .25s ease;} .x-hood{position:absolute; inset:0; pointer-events:none; z-index:2;} .x-hood svg{position:absolute; top:calc(var(--xs) - 14px); left:0; display:block; width:100%; height:120px;} .x-hood .solid{position:absolute; top:calc(var(--xs) + 105px); left:0; right:0; bottom:0; background:var(--bg);} @@ -216,7 +217,7 @@ .x-empty{position:absolute; inset:0; border-radius:26px; background:#141414; border:1px dashed rgba(255,255,255,.15); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;} .x-actions{position:relative; z-index:3; display:flex; justify-content:center; align-items:center; gap:22px; - padding:6px 0 calc(96px + env(safe-area-inset-bottom));} + padding:6px 0 84px;} .x-act{width:56px; height:56px; border-radius:100px; background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.12); display:grid; place-items:center; cursor:pointer; font-size:20px; color:rgba(255,255,255,.8); transition:transform .12s;} .x-act:active{transform:scale(.92);} @@ -251,21 +252,19 @@ .p-hero p{color:var(--mut); font-size:13px; margin-top:3px;} /* ================= Bottom-Navigation ================= */ - /* Liquid-Glass-Nav (aus BrandLoop.dc.html): Turbulenz-Filter als backdrop, - blur(20px) als Fallback falls der Browser url()-backdrop-filter nicht kann */ + /* Liquid-Glass-Nav (aus BrandLoop.dc.html): verzerrter Glas-Backdrop + (bl-glass-distortion mit Specular-Highlight) + heller Weiss-Layer + Kanten-Ring. + bottom:14px OHNE Safe-Area-Aufschlag = exakt die Hoehe aus dem Design. */ .nav{position:fixed; bottom:14px; left:50%; transform:translateX(-50%); z-index:30; display:flex; align-items:center; gap:6px; padding:8px 10px; border-radius:100px; - margin-bottom:env(safe-area-inset-bottom);} - .nav::before{content:''; position:absolute; inset:0; z-index:-1; border-radius:100px; - background:rgba(10,10,10,.18); - -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px); - -webkit-backdrop-filter:url(#bl-liquid-glass); backdrop-filter:url(#bl-liquid-glass);} + background:rgba(255,255,255,.25); + box-shadow:0 6px 6px rgba(0,0,0,.2), 0 0 20px rgba(0,0,0,.1); + transition:all .7s cubic-bezier(.175,.885,.32,2.2);} + .nav::before{content:''; position:absolute; inset:0; z-index:-1; border-radius:100px; overflow:hidden; + -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); + filter:url(#bl-glass-distortion); isolation:isolate;} .nav::after{content:''; position:absolute; inset:0; z-index:2; border-radius:100px; pointer-events:none; - box-shadow:0 0 8px rgba(0,0,0,.03), 0 2px 6px rgba(0,0,0,.08), - inset 3px 3px .5px -3.5px rgba(255,255,255,.09), inset -3px -3px .5px -3.5px rgba(255,255,255,.85), - inset 1px 1px 1px -.5px rgba(255,255,255,.6), inset -1px -1px 1px -.5px rgba(255,255,255,.6), - inset 0 0 6px 6px rgba(255,255,255,.12), inset 0 0 2px 2px rgba(255,255,255,.06), - 0 0 12px rgba(0,0,0,.15);} + box-shadow:inset 2px 2px 1px 0 rgba(255,255,255,.5), inset -1px -1px 1px 1px rgba(255,255,255,.5);} .nav button{display:flex; align-items:center; gap:8px; background:none; border:none; font-family:inherit; width:40px; height:40px; justify-content:center; border-radius:100px; color:rgba(255,255,255,.6); font-size:13.5px; font-weight:600; cursor:pointer; transition:background .2s, color .2s, width .2s;} @@ -299,12 +298,19 @@
'; + : cardTransform(depth); + html+='
'; var bg=u ? '#141414 url("'+u+'") center / cover no-repeat' : dummy(hue); html+='
'; if(top){ @@ -1054,6 +1066,14 @@ function renderDeck(){ host.innerHTML=html; var topEl=host.querySelector('.x-card.top'); if(topEl) topEl.addEventListener('pointerdown', onDown); + if(settle){ + requestAnimationFrame(function(){ requestAnimationFrame(function(){ + host.querySelectorAll('.x-card').forEach(function(el){ + el.style.transition='transform .45s cubic-bezier(.22,1,.36,1)'; + el.style.transform=cardTransform(+el.dataset.i); + }); + });}); + } } function fling(dir){ @@ -1062,14 +1082,15 @@ function fling(dir){ X.anim=true; var topEl=document.querySelector('#xDeck .x-card.top'); if(topEl){ - topEl.style.transition='transform .28s ease'; + topEl.style.transition='transform .3s cubic-bezier(.4,0,.7,1), opacity .3s ease'; topEl.style.transform='translateX('+(dir*640)+'px) rotate('+(dir*640/22)+'deg)'; + topEl.style.opacity='0'; } setTimeout(function(){ if(dir>0 && post) X.liked.push(post.id); X.idx++; X.dx=0; X.imgIdx=0; X.anim=false; - renderDeck(); - },280); + renderDeck(true); + },300); } function onDown(e){ @@ -1093,7 +1114,7 @@ function onDown(e){ var d=ev.clientX-sx; if(Math.abs(d)>110){ fling(d>0?1:-1); return; } X.dx=0; - topEl.style.transition='transform .28s ease'; + topEl.style.transition='transform .45s cubic-bezier(.22,1,.36,1)'; topEl.style.transform='translateX(0) rotate(0)'; if(likeB) likeB.style.opacity=0; if(skipB) skipB.style.opacity=0; @@ -1108,8 +1129,17 @@ function onDown(e){ document.querySelectorAll('.x-tab').forEach(function(el){ el.addEventListener('click',function(){ - X.tab=el.dataset.tab; X.idx=0; X.dx=0; X.imgIdx=0; - renderTabs(); renderDeck(); animateHood(centerOf(X.tab), halfOf(X.tab)); + if(X.tab===el.dataset.tab) return; + var k=el.dataset.tab; + var deckEl=document.getElementById('xDeck'), blurEl=document.getElementById('xBlur'); + animateHood(centerOf(k), halfOf(k)); + deckEl.style.transition='opacity .18s ease'; + deckEl.style.opacity='0'; blurEl.style.opacity='0'; + setTimeout(function(){ + X.tab=k; X.idx=0; X.dx=0; X.imgIdx=0; + renderTabs(); renderDeck(true); + deckEl.style.opacity='1'; blurEl.style.opacity='1'; + },180); }); }); window.addEventListener('resize',function(){