patx/afterdarklabs
fix mobile reveals indexerd
Commit ceb0356 · patx · 2026-09-03T17:48:06-04:00
Comments
No comments yet.
Diff
diff --git a/docs/indexerd.html b/docs/indexerd.html
index c113031..03a7e4e 100644
--- a/docs/indexerd.html
+++ b/docs/indexerd.html
@@ -63,7 +63,13 @@
--site-nav-height: 5.75rem;
}
- html { scroll-behavior: smooth; }
+ html {
+ max-width: 100%;
+ overflow-x: hidden;
+ overflow-x: clip;
+ overscroll-behavior-x: none;
+ scroll-behavior: smooth;
+ }
@media (min-width: 1024px) {
:root {
@@ -91,10 +97,19 @@
}
body {
+ max-width: 100%;
+ overflow-x: hidden;
+ overflow-x: clip;
+ overscroll-behavior-x: none;
background: var(--page-bg);
font-family: 'Ubuntu', system-ui, sans-serif;
}
+ nav {
+ -webkit-backdrop-filter: none !important;
+ backdrop-filter: none !important;
+ }
+
.heading,
.logo-font { font-family: inherit; color: #fff; }
@@ -530,6 +545,7 @@
gap: clamp(0.3rem, 0.6vw, 0.65rem);
overflow: visible;
padding: 0;
+ touch-action: pan-y pinch-zoom;
}
#work-scroller > article {
@@ -644,6 +660,10 @@
skewY(var(--card-skew, 0deg))
scale(var(--card-scale-x, 0.94), var(--card-scale-y, 1.04));
transform-origin: center bottom;
+ will-change: auto;
+ }
+
+ .portfolio-scroll-ready #work-scroller > article.is-card-animating {
will-change: opacity, filter, transform;
}
@@ -667,7 +687,7 @@
}
}
- @media (max-width: 767px) {
+ @media (hover: none), (pointer: coarse) {
#work-scroller > article {
cursor: pointer;
}
@@ -675,6 +695,15 @@
#work-scroller > article.is-description-visible {
cursor: default;
}
+
+ .portfolio-scroll-ready #work-scroller > article {
+ filter: none;
+ }
+
+ #work-scroller > article > .portfolio-details {
+ -webkit-backdrop-filter: none;
+ backdrop-filter: none;
+ }
}
@media (prefers-reduced-motion: reduce) {
@@ -1175,8 +1204,12 @@
if (!cards.length) return;
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
- const mobileLayout = window.matchMedia('(max-width: 767px)');
+ const touchDisclosure = window.matchMedia('(hover: none), (pointer: coarse)');
let cardTops = [];
+ let cardStates = cards.map(() => -1);
+ let layoutWidth = 0;
+ let layoutHeight = 0;
+ let lastScrollY = -1;
let updateFrame = 0;
let resizeFrame = 0;
@@ -1227,14 +1260,28 @@
function updateCards() {
updateFrame = 0;
- if (reduceMotion.matches) return;
+ if (reduceMotion.matches) {
+ cards.forEach(card => card.classList.remove('is-card-animating'));
+ return;
+ }
- const viewportHeight = window.visualViewport?.height || window.innerHeight;
+ const scrollY = Math.max(0, window.scrollY);
+ const viewportHeight = layoutHeight || document.documentElement.clientHeight || window.innerHeight;
+ if (scrollY === lastScrollY) return;
+
+ lastScrollY = scrollY;
const revealDistance = Math.max(240, viewportHeight * 0.58);
- const travelX = Math.min(72, window.innerWidth * 0.06);
+ const travelX = Math.min(72, document.documentElement.clientWidth * 0.06);
cards.forEach((card, index) => {
- const progress = clamp((window.scrollY + viewportHeight * 0.94 - cardTops[index]) / revealDistance);
+ const progress = clamp((scrollY + viewportHeight * 0.94 - cardTops[index]) / revealDistance);
+ const state = progress <= 0 ? 0 : progress >= 1 ? 1 : 2;
+ if (cardStates[index] !== state) {
+ card.classList.toggle('is-card-animating', state === 2);
+ }
+ if (state !== 2 && cardStates[index] === state) return;
+
+ cardStates[index] = state;
const eased = 1 - Math.pow(1 - progress, 3);
const remaining = 1 - eased;
const direction = index % 2 === 0 ? -1 : 1;
@@ -1261,7 +1308,20 @@
function measureCards() {
resizeFrame = 0;
+ const nextLayoutWidth = document.documentElement.clientWidth;
+ const nextLayoutHeight = document.documentElement.clientHeight || window.innerHeight;
+ const widthChanged = Math.abs(nextLayoutWidth - layoutWidth) >= 2;
+ const desktopHeightChanged = !touchDisclosure.matches && Math.abs(nextLayoutHeight - layoutHeight) >= 2;
+ if (layoutWidth && !widthChanged && !desktopHeightChanged) {
+ scheduleCardUpdate();
+ return;
+ }
+
+ layoutWidth = nextLayoutWidth;
+ layoutHeight = nextLayoutHeight;
cardTops = cards.map(getDocumentTop);
+ cardStates = cards.map(() => -1);
+ lastScrollY = -1;
fitDescriptions();
updateCards();
}
@@ -1274,6 +1334,11 @@
if (!resizeFrame) resizeFrame = window.requestAnimationFrame(measureCards);
}
+ function scheduleCardRemeasure() {
+ layoutWidth = 0;
+ scheduleCardMeasure();
+ }
+
function closeDescriptions(exceptCard = null) {
cards.forEach(card => {
if (card !== exceptCard) card.classList.remove('is-description-visible');
@@ -1282,7 +1347,7 @@
cards.forEach(card => {
card.addEventListener('click', event => {
- if (!mobileLayout.matches || event.target.closest('.portfolio-live-link')) return;
+ if (!touchDisclosure.matches || event.target.closest('.portfolio-live-link')) return;
closeDescriptions(card);
card.classList.add('is-description-visible');
@@ -1290,21 +1355,21 @@
});
document.addEventListener('pointerdown', event => {
- if (!mobileLayout.matches || event.target.closest('#work-scroller > article')) return;
+ if (!touchDisclosure.matches || event.target.closest('#work-scroller > article')) return;
closeDescriptions();
const activeCard = document.activeElement?.closest?.('#work-scroller > article');
if (activeCard) document.activeElement.blur();
}, { passive: true });
- mobileLayout.addEventListener('change', () => closeDescriptions());
+ touchDisclosure.addEventListener('change', () => closeDescriptions());
section.classList.add('portfolio-scroll-ready');
window.addEventListener('scroll', scheduleCardUpdate, { passive: true });
window.addEventListener('resize', scheduleCardMeasure);
window.visualViewport?.addEventListener('resize', scheduleCardMeasure);
- window.addEventListener('pageshow', scheduleCardMeasure);
- reduceMotion.addEventListener('change', scheduleCardMeasure);
- document.fonts?.ready.then(scheduleCardMeasure);
+ window.addEventListener('pageshow', scheduleCardRemeasure);
+ reduceMotion.addEventListener('change', scheduleCardRemeasure);
+ document.fonts?.ready.then(scheduleCardRemeasure);
measureCards();
})();