fix: resolve 5 UI issues from post-deploy review
- CloudDivider: replace Tailwind fill classes with inline CSS var() (fixes black separators) - ServiceCard: add p-6 md:p-7 padding, reduce border-top to 3px (fixes broken card layout) - Hero: increase eyebrow font-size 0.7rem→0.8rem, badges text-sm→text-base (fixes tiny fonts) - LenisScroll: duration 1.2→0.8, remove double RAF bug, add ScrollTrigger.update sync, reduced-motion guard (fixes slow scroll + missing animations) - global.css: remove scroll-behavior:smooth from html (conflicted with Lenis)
This commit is contained in:
@@ -2,20 +2,20 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
variant?: 'wave' | 'cloud';
|
variant?: 'wave' | 'cloud';
|
||||||
flip?: boolean;
|
flip?: boolean;
|
||||||
fillClass?: string;
|
fill?: string;
|
||||||
}
|
}
|
||||||
const { variant = 'wave', flip = false, fillClass = 'fill-hds-bg' } = Astro.props;
|
const { variant = 'wave', flip = false, fill = 'var(--hds-bg)' } = Astro.props;
|
||||||
---
|
---
|
||||||
{variant === 'wave' ? (
|
{variant === 'wave' ? (
|
||||||
<div class={`w-full overflow-hidden leading-none ${flip ? 'rotate-180' : ''}`} aria-hidden="true">
|
<div class={`w-full overflow-hidden leading-none ${flip ? 'rotate-180' : ''}`} aria-hidden="true">
|
||||||
<svg class="w-full h-12 md:h-16" viewBox="0 0 1440 80" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-full h-12 md:h-16" viewBox="0 0 1440 80" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path class={fillClass} d="M0,32 C240,80 480,0 720,32 C960,64 1200,16 1440,48 L1440,80 L0,80 Z" />
|
<path style={`fill: ${fill};`} d="M0,32 C240,80 480,0 720,32 C960,64 1200,16 1440,48 L1440,80 L0,80 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class={`w-full overflow-hidden leading-none ${flip ? 'rotate-180' : ''}`} aria-hidden="true">
|
<div class={`w-full overflow-hidden leading-none ${flip ? 'rotate-180' : ''}`} aria-hidden="true">
|
||||||
<svg class="w-full h-16 md:h-24" viewBox="0 0 1440 120" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-full h-16 md:h-24" viewBox="0 0 1440 120" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path class={fillClass} d="M0,60 C120,100 240,20 360,50 C480,80 600,30 720,55 C840,80 960,40 1080,60 C1200,80 1320,45 1440,65 L1440,120 L0,120 Z" />
|
<path style={`fill: ${fill};`} d="M0,60 C120,100 240,20 360,50 C480,80 600,30 720,55 C840,80 960,40 1080,60 C1200,80 1320,45 1440,65 L1440,120 L0,120 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ const { t, whatsappUrl } = Astro.props;
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="hero-badges" class="flex flex-wrap items-center gap-x-8 gap-y-3 text-sm opacity-0" style="color: var(--hds-fg-muted);">
|
<div id="hero-badges" class="flex flex-wrap items-center gap-x-8 gap-y-3 text-base opacity-0" style="color: var(--hds-fg-muted);">
|
||||||
<span class="flex items-center gap-2">
|
<span class="flex items-center gap-2">
|
||||||
<span style="color: var(--color-hds-naranja);">●</span>
|
<span style="color: var(--color-hds-naranja);">●</span>
|
||||||
{t('hero.badge26')}
|
{t('hero.badge26')}
|
||||||
|
|||||||
@@ -1,37 +1,34 @@
|
|||||||
---
|
---
|
||||||
// Lenis smooth scroll — Phase 5
|
// Lenis smooth scroll — synced with GSAP ScrollTrigger
|
||||||
// Synced with GSAP ticker for scroll-driven animations
|
// Skipped entirely when prefers-reduced-motion is active
|
||||||
---
|
---
|
||||||
<script>
|
<script>
|
||||||
import Lenis from '@studio-freight/lenis';
|
import Lenis from '@studio-freight/lenis';
|
||||||
import gsap from 'gsap';
|
import gsap from 'gsap';
|
||||||
|
import { ScrollTrigger } from 'gsap/ScrollTrigger';
|
||||||
|
|
||||||
const lenis = new Lenis({
|
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
duration: 1.2,
|
|
||||||
easing: (t: number) => 1 - Math.pow(1 - t, 3),
|
|
||||||
smoothWheel: true,
|
|
||||||
wheelMultiplier: 1,
|
|
||||||
touchMultiplier: 1.5,
|
|
||||||
});
|
|
||||||
|
|
||||||
function raf(time: number) {
|
if (!prefersReducedMotion) {
|
||||||
lenis.raf(time);
|
// Disable native smooth scroll — Lenis handles it
|
||||||
requestAnimationFrame(raf);
|
document.documentElement.style.scrollBehavior = 'auto';
|
||||||
|
|
||||||
|
const lenis = new Lenis({
|
||||||
|
duration: 0.8,
|
||||||
|
easing: (t: number) => 1 - Math.pow(1 - t, 4),
|
||||||
|
smoothWheel: true,
|
||||||
|
wheelMultiplier: 1,
|
||||||
|
touchMultiplier: 1.5,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sync Lenis scroll → ScrollTrigger (critical for scroll-driven animations)
|
||||||
|
lenis.on('scroll', ScrollTrigger.update);
|
||||||
|
|
||||||
|
// Drive Lenis via GSAP ticker only — NO separate requestAnimationFrame
|
||||||
|
gsap.ticker.add((time: number) => {
|
||||||
|
lenis.raf(time * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
gsap.ticker.lagSmoothing(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(raf);
|
|
||||||
|
|
||||||
// Sync Lenis with GSAP ScrollTrigger
|
|
||||||
gsap.ticker.add((time: number) => {
|
|
||||||
lenis.raf(time * 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
gsap.ticker.lagSmoothing(0);
|
|
||||||
|
|
||||||
// Connect GSAP ScrollTrigger to Lenis scroll
|
|
||||||
const scrollTriggerConfig = {
|
|
||||||
onUpdate: (self: { direction: number; progress: number }) => {
|
|
||||||
// Lenis handles the actual scroll, GSAP reads from it
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ const { href, title, description, Icon, borderColor = 'var(--color-hds-naranja)'
|
|||||||
---
|
---
|
||||||
<a
|
<a
|
||||||
href={href}
|
href={href}
|
||||||
class="glass-card group flex flex-col h-full"
|
class="glass-card group flex flex-col h-full p-6 md:p-7"
|
||||||
style={`border-top: 4px solid ${borderColor}; padding-top: 1.5rem;`}
|
style={`border-top: 3px solid ${borderColor};`}
|
||||||
>
|
>
|
||||||
<div class="icon-circle mb-5" style="width: 48px; height: 48px;">
|
<div class="icon-circle mb-5" style="width: 48px; height: 48px;">
|
||||||
<Icon class="w-6 h-6" />
|
<Icon class="w-6 h-6" />
|
||||||
|
|||||||
@@ -26,16 +26,16 @@ const description = lang === 'en'
|
|||||||
>
|
>
|
||||||
<Hero t={t} whatsappUrl={whatsappUrl} />
|
<Hero t={t} whatsappUrl={whatsappUrl} />
|
||||||
|
|
||||||
<CloudDivider fillClass="fill-hds-bg-soft" />
|
<CloudDivider fill="var(--hds-bg-soft)" />
|
||||||
|
|
||||||
<StatsSection t={t} lang={lang} />
|
<StatsSection t={t} lang={lang} />
|
||||||
<DifferenceCards t={t} />
|
<DifferenceCards t={t} />
|
||||||
|
|
||||||
<CloudDivider fillClass="fill-hds-bg" flip={true} />
|
<CloudDivider fill="var(--hds-bg)" flip={true} />
|
||||||
|
|
||||||
<ServicesSection t={t} lang={lang} />
|
<ServicesSection t={t} lang={lang} />
|
||||||
|
|
||||||
<CloudDivider fillClass="fill-hds-bg-soft" />
|
<CloudDivider fill="var(--hds-bg-soft)" />
|
||||||
|
|
||||||
<ProcessSteps t={t} />
|
<ProcessSteps t={t} />
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +209,7 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
font-size: 0.7rem;
|
font-size: 0.8rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: var(--tracking-eyebrow);
|
letter-spacing: var(--tracking-eyebrow);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|||||||
Reference in New Issue
Block a user