Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aff47de037 | |||
| 85d366cfe2 | |||
| 5dc2a9fd37 | |||
| 57e5431e2a | |||
| a13b033b7d | |||
| 93714d2683 | |||
| b0fae48e65 | |||
| 60391b5a3f |
@@ -39,7 +39,6 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
|
||||
const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster;
|
||||
const posterAlt = props.backgroundImage?.alt || data?.posterImage?.alt || "E-TIB Gruppe Baustelle";
|
||||
const blurDataURL = (placeholders as Record<string, string>)[posterSrc] || undefined;
|
||||
|
||||
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
||||
const ctaHref = props.ctaHref || props.linkHref || data?.ctaHref || '#unternehmen';
|
||||
@@ -87,11 +86,10 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
src={posterSrc}
|
||||
alt={posterAlt}
|
||||
fill
|
||||
unoptimized
|
||||
className="object-cover z-[1] pointer-events-none filter contrast-125 saturate-110 brightness-90"
|
||||
sizes="100vw"
|
||||
priority
|
||||
placeholder={blurDataURL ? "blur" : "empty"}
|
||||
blurDataURL={blurDataURL}
|
||||
/>
|
||||
|
||||
{/* Render video on top if available, but defer src to avoid blocking LCP */}
|
||||
|
||||
@@ -46,22 +46,6 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
const scrollLeftRef = React.useRef(0);
|
||||
const isDraggingRef = React.useRef(false);
|
||||
const [isDragging, setIsDragging] = React.useState(false);
|
||||
const [paddingX, setPaddingX] = React.useState(24);
|
||||
|
||||
React.useEffect(() => {
|
||||
const updatePadding = () => {
|
||||
const containerEl = document.querySelector('#referenzen .container');
|
||||
if (containerEl) {
|
||||
const rect = containerEl.getBoundingClientRect();
|
||||
const computedStyle = window.getComputedStyle(containerEl);
|
||||
const pLeft = parseFloat(computedStyle.paddingLeft || '0');
|
||||
setPaddingX(rect.left + pLeft);
|
||||
}
|
||||
};
|
||||
updatePadding();
|
||||
window.addEventListener('resize', updatePadding);
|
||||
return () => window.removeEventListener('resize', updatePadding);
|
||||
}, []);
|
||||
|
||||
const badge = props.badge || data?.badge || t('badge');
|
||||
const title = props.title || data?.title || t('title');
|
||||
@@ -123,19 +107,19 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10">
|
||||
<div className="container relative z-10">
|
||||
<div className="absolute right-0 top-0 bottom-0 w-16 bg-gradient-to-l from-neutral-dark to-transparent z-20 md:hidden pointer-events-none" />
|
||||
|
||||
{/* Carousel: stays inside container for left alignment, breaks right to viewport edge */}
|
||||
<div
|
||||
ref={containerRef}
|
||||
onMouseDown={onMouseDown}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onMouseUp={onMouseUp}
|
||||
onMouseMove={onMouseMove}
|
||||
className={`select-none flex overflow-x-auto pb-8 pt-4 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
||||
style={{ marginRight: 'calc(-50vw + 50%)' }}
|
||||
className={`select-none flex gap-6 overflow-x-auto pb-8 pt-4 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
||||
>
|
||||
{/* Robust Left Spacer for Pixel-Perfect Alignment */}
|
||||
<div style={{ minWidth: paddingX }} className="flex-shrink-0 pointer-events-none" aria-hidden="true" />
|
||||
|
||||
{references.map((ref, i) => {
|
||||
const imgSrc = ref.image
|
||||
? (typeof ref.image === 'string' ? ref.image : ref.image.url)
|
||||
@@ -148,7 +132,7 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
transition={{ delay: i * 0.1, duration: 1.0, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto mr-6"
|
||||
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto"
|
||||
>
|
||||
<Link
|
||||
href={`/${locale}/referenzen#${ref.slug}`}
|
||||
@@ -182,6 +166,8 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
{/* Right padding spacer so last card doesn't clip at viewport edge */}
|
||||
<div className="flex-shrink-0 w-6" aria-hidden="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
</motion.div>
|
||||
<motion.span
|
||||
animate={{ y: isActive ? 0 : 2 }}
|
||||
className="text-[9px] font-bold mt-1 tracking-wide"
|
||||
className="text-[10px] font-bold mt-1 tracking-wide"
|
||||
>
|
||||
{item.label}
|
||||
</motion.span>
|
||||
@@ -144,7 +144,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
key={item.label}
|
||||
onClick={() => setIsFlyoutOpen(!isFlyoutOpen)}
|
||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none w-full focus:outline-none ${
|
||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
||||
isActive ? 'text-primary' : 'text-neutral-800 hover:text-neutral-900'
|
||||
}`}
|
||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||
>
|
||||
@@ -159,7 +159,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
href={mappedUrl}
|
||||
onClick={() => setIsFlyoutOpen(false)}
|
||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none ${
|
||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
||||
isActive ? 'text-primary' : 'text-neutral-800 hover:text-neutral-900'
|
||||
}`}
|
||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||
>
|
||||
|
||||
@@ -15,6 +15,7 @@ const nextConfig = {
|
||||
pagesBufferLength: 2,
|
||||
},
|
||||
experimental: {
|
||||
optimizeCss: true,
|
||||
staleTimes: {
|
||||
dynamic: 0,
|
||||
static: 30,
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.2.38",
|
||||
"version": "2.2.42",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
Reference in New Issue
Block a user