Polish: subtle card hover-lift + scroll-fade-in for sections (respects reduced-motion)

This commit is contained in:
ask 2026-05-17 21:35:23 +05:00
parent aa3e1bd0cc
commit 141349c95e

View File

@ -30,6 +30,47 @@
html { scroll-behavior: smooth; } html { scroll-behavior: smooth; }
/* ── POLISH: shared hover transition for all card variants ── */
.tool-card, .create-card, .plan-step, .gloss-item, .project-card, .prompt-card, .eq-box {
transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
will-change: transform;
}
@media (hover: hover) {
.tool-card:hover, .create-card:hover, .plan-step:hover,
.gloss-item:hover, .prompt-card:hover, .eq-box:hover {
transform: translateY(-2px);
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06);
}
/* project-card already has its own hover (border + ring) — strengthen with lift */
.project-card:hover {
transform: translateY(-2px);
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06);
}
}
@media (prefers-reduced-motion: reduce) {
.tool-card, .create-card, .plan-step, .gloss-item, .project-card, .prompt-card, .eq-box {
transition: none;
}
.tool-card:hover, .create-card:hover, .plan-step:hover,
.gloss-item:hover, .project-card:hover, .prompt-card:hover, .eq-box:hover {
transform: none;
}
}
/* ── POLISH: scroll-triggered fade-in ── */
.reveal {
opacity: 0;
transform: translateY(8px);
transition: opacity 350ms ease, transform 350ms ease;
}
.reveal.in {
opacity: 1;
transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
.reveal { opacity: 1; transform: none; transition: none; }
}
body { body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #fff; background: #fff;
@ -2413,6 +2454,27 @@ const SCHEDULE = [
}); });
refreshHeader(); refreshHeader();
/* ── POLISH: scroll-triggered fade-in ────────────────────
Marks all direct content blocks inside <section class="section">
with .reveal, then toggles .in on intersection.
Respects prefers-reduced-motion via CSS fallback. */
(function initReveal() {
if (!('IntersectionObserver' in window)) return;
const targets = document.querySelectorAll(
'.section .container > *, .section .container .section-header > *'
);
targets.forEach(el => el.classList.add('reveal'));
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('in');
io.unobserve(e.target);
}
});
}, { rootMargin: '0px 0px -60px 0px', threshold: 0.05 });
targets.forEach(el => io.observe(el));
})();
</script> </script>
</body> </body>
</html> </html>