Compare commits

..

4 Commits

Author SHA1 Message Date
531e1a49f8 fix: remove inline opacity: 0 from HeroSection and use animation-fill-mode both to prevent invisible text
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 47s
Build & Deploy / 🧪 QA (push) Successful in 1m14s
Build & Deploy / 🏗️ Build (push) Successful in 2m15s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-07-03 14:45:37 +02:00
324cfb0ca3 fix: ci hang in maintenance, restore hero animations, bump version 2.4.23
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 19s
Build & Deploy / 🏗️ Build (push) Successful in 2m11s
Build & Deploy / 🧪 QA (push) Successful in 1m19s
Build & Deploy / 🚀 Deploy (push) Successful in 27s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 49s
Build & Deploy / 🔔 Notify (push) Successful in 4s
2026-07-03 13:18:33 +02:00
69d2c42ef7 chore: bump version to 2.4.22
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 22s
Build & Deploy / 🧪 QA (push) Successful in 1m19s
Build & Deploy / 🏗️ Build (push) Failing after 22m7s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
2026-07-03 12:22:32 +02:00
6fb46278e0 fix: restore hero animations in tailwind v4 on 2.2.95
Some checks failed
Build & Deploy / 🧪 QA (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🔍 Prepare (push) Has been cancelled
2026-07-03 12:21:43 +02:00
11 changed files with 67 additions and 62 deletions

View File

@@ -47,14 +47,7 @@ jobs:
run: | run: |
echo "=== System Disk Usage ===" echo "=== System Disk Usage ==="
df -h || true df -h || true
echo "=== Tool Cache Usage ==="
du -sh /opt/hostedtoolcache/* || true
du -sh /opt/hostedtoolcache/.[!.]* || true
echo "Purging old tool caches skipped to prevent runner corruption." echo "Purging old tool caches skipped to prevent runner corruption."
echo "=== Host Disk Usage ==="
docker run --rm -v /:/host-root alpine df -h || true
echo "=== Host Inode Usage ==="
docker run --rm -v /:/host-root alpine df -i || true
echo "=== Running Host Containers ===" echo "=== Running Host Containers ==="
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" || true docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" || true
echo "=== Host Docker Info ===" echo "=== Host Docker Info ==="

View File

@@ -22,6 +22,7 @@ import { DynamicMobileBottomNav as MobileBottomNav } from '@/components/layout/D
import { DynamicCorporateBackground as CorporateBackground } from '@/components/decorations/DynamicCorporateBackground'; import { DynamicCorporateBackground as CorporateBackground } from '@/components/decorations/DynamicCorporateBackground';
import { DynamicPageTransitionShutter as PageTransitionShutter } from '@/components/providers/DynamicPageTransitionShutter'; import { DynamicPageTransitionShutter as PageTransitionShutter } from '@/components/providers/DynamicPageTransitionShutter';
import { DynamicFramerMotion as FramerMotionProvider } from '@/components/providers/DynamicFramerMotion';
const inter = Inter({ const inter = Inter({
subsets: ['latin'], subsets: ['latin'],
@@ -190,26 +191,28 @@ export default async function Layout(props: {
<body className="relative flex flex-col min-h-screen font-sans antialiased overflow-x-hidden selection:bg-primary/90 selection:text-white" suppressHydrationWarning> <body className="relative flex flex-col min-h-screen font-sans antialiased overflow-x-hidden selection:bg-primary/90 selection:text-white" suppressHydrationWarning>
<NextIntlClientProvider messages={clientMessages} locale={safeLocale}> <NextIntlClientProvider messages={clientMessages} locale={safeLocale}>
<TransitionProvider> <TransitionProvider>
<CorporateBackground /> <FramerMotionProvider>
<InitialLoader shouldShowLoader={!hasSeenLoader} /> <CorporateBackground />
<PageTransitionShutter /> <InitialLoader shouldShowLoader={!hasSeenLoader} />
<SkipLink /> <PageTransitionShutter />
<Header navLinks={navLinks} /> <SkipLink />
<MobileBottomNav navLinks={navLinks} currentLocale={safeLocale} /> <Header navLinks={navLinks} />
<MobileBottomNav navLinks={navLinks} currentLocale={safeLocale} />
<main <main
id="main-content" id="main-content"
className="flex-grow overflow-visible" className="flex-grow overflow-visible"
tabIndex={-1} tabIndex={-1}
> >
{children} {children}
</main> </main>
<Footer companyInfo={companyInfo} /> <Footer companyInfo={companyInfo} />
<JsonLd /> <JsonLd />
<AnalyticsShell /> <AnalyticsShell />
<FeedbackClientWrapper /> <FeedbackClientWrapper />
</FramerMotionProvider>
</TransitionProvider> </TransitionProvider>
</NextIntlClientProvider> </NextIntlClientProvider>
</body> </body>

View File

@@ -88,34 +88,30 @@
} }
/* trigger rebuild */ /* trigger rebuild */
@layer utilities { @keyframes hero-fade-in-up {
@keyframes hero-fade-in-up { from {
from { opacity: 0;
opacity: 0; transform: translateY(30px);
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
} }
to {
.animate-hero-fade-in-up { opacity: 1;
animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; transform: translateY(0);
} }
} }
@layer utilities { @utility animate-hero-fade-in-up {
@keyframes hero-zoom-out { animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
from { }
transform: scale(1.05);
}
to {
transform: scale(1);
}
}
.animate-hero-zoom-out { @keyframes hero-zoom-out {
animation: hero-zoom-out 1.5s ease-out forwards; from {
transform: scale(1.05);
}
to {
transform: scale(1);
} }
} }
@utility animate-hero-zoom-out {
animation: hero-zoom-out 1.5s ease-out forwards;
}

View File

@@ -60,26 +60,26 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
className={`max-w-4xl ${alignment === 'center' ? 'mx-auto' : ''}`} className={`max-w-4xl ${alignment === 'center' ? 'mx-auto' : ''}`}
> >
{badge && ( {badge && (
<div className="animate-hero-fade-in-up" style={{ animationDelay: '0.1s', opacity: 0, animationFillMode: 'forwards' }}> <div className="animate-hero-fade-in-up" style={{ animationDelay: '0.1s', animationFillMode: 'both' }}>
<Badge variant="saturated" className="mb-4 md:mb-8 shadow-lg"> <Badge variant="saturated" className="mb-4 md:mb-8 shadow-lg">
{badge} {badge}
</Badge> </Badge>
</div> </div>
)} )}
<div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.25s' : '0.1s', opacity: 0, animationFillMode: 'forwards' }}> <div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.25s' : '0.1s', animationFillMode: 'both' }}>
<Heading level={1} size="section" variant="white" align={alignment || 'left'} className="mb-4 md:mb-8"> <Heading level={1} size="section" variant="white" align={alignment || 'left'} className="mb-4 md:mb-8">
{title} {title}
</Heading> </Heading>
</div> </div>
{subtitle && ( {subtitle && (
<div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.4s' : '0.25s', opacity: 0, animationFillMode: 'forwards' }}> <div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.4s' : '0.25s', animationFillMode: 'both' }}>
<p className={`text-lg md:text-2xl text-white/70 font-medium leading-relaxed max-w-2xl ${alignment === 'center' ? 'mx-auto' : ''}`}> <p className={`text-lg md:text-2xl text-white/70 font-medium leading-relaxed max-w-2xl ${alignment === 'center' ? 'mx-auto' : ''}`}>
{subtitle} {subtitle}
</p> </p>
</div> </div>
)} )}
{ctaLabel && ctaHref && ( {ctaLabel && ctaHref && (
<div className={`mt-8 animate-hero-fade-in-up ${alignment === 'center' ? 'flex flex-wrap justify-center gap-4' : 'flex flex-wrap gap-4'}`} style={{ animationDelay: badge ? '0.55s' : '0.4s', opacity: 0, animationFillMode: 'forwards' }}> <div className={`mt-8 animate-hero-fade-in-up ${alignment === 'center' ? 'flex flex-wrap justify-center gap-4' : 'flex flex-wrap gap-4'}`} style={{ animationDelay: badge ? '0.55s' : '0.4s', animationFillMode: 'both' }}>
<Button <Button
href={ctaHref} href={ctaHref}
variant="accent" variant="accent"

View File

@@ -34,7 +34,7 @@ export function HeroVideo(props: HeroVideoProps) {
let defaultPoster = "/assets/photos/DJI_0048.JPG"; let defaultPoster = "/assets/photos/DJI_0048.JPG";
if (videoUrl && videoUrl.endsWith('.mp4')) { if (videoUrl && videoUrl.endsWith('.mp4')) {
defaultPoster = videoUrl.replace('.mp4', '-poster.webp'); defaultPoster = videoUrl.replace('.mp4', '-poster.jpg');
} }
const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster; const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster;

View File

@@ -0,0 +1,7 @@
'use client';
import dynamic from 'next/dynamic';
export const DynamicFramerMotion = dynamic(
() => import('./FramerMotionProvider').then((mod) => mod.FramerMotionProvider),
{ ssr: true }
);

View File

@@ -0,0 +1,11 @@
'use client';
import { LazyMotion } from 'framer-motion';
const loadFeatures = () => import('@/lib/framer-features').then(res => res.default);
export function FramerMotionProvider({ children }: { children: React.ReactNode }) {
return (
<LazyMotion features={loadFeatures} strict>
{children}
</LazyMotion>
);
}

View File

@@ -2,9 +2,6 @@
import React, { createContext, useContext, useState, useCallback, ReactNode, useEffect } from 'react'; import React, { createContext, useContext, useState, useCallback, ReactNode, useEffect } from 'react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { LazyMotion } from 'framer-motion';
const loadFeatures = () => import('@/lib/framer-features').then(res => res.default);
interface TransitionContextType { interface TransitionContextType {
isTransitioning: boolean; isTransitioning: boolean;
@@ -71,9 +68,7 @@ export function TransitionProvider({ children }: { children: ReactNode }) {
setTransitionMessage={setTransitionMessage} setTransitionMessage={setTransitionMessage}
/> />
</React.Suspense> </React.Suspense>
<LazyMotion features={loadFeatures}> {children}
{children}
</LazyMotion>
</TransitionContext.Provider> </TransitionContext.Provider>
); );
} }

View File

@@ -449,7 +449,7 @@ const nextConfig = {
}, },
images: { images: {
qualities: [25, 50, 75, 100], qualities: [25, 50, 75, 100],
formats: ['image/webp'], formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
remotePatterns: [ remotePatterns: [
{ {

View File

@@ -139,7 +139,7 @@
"prepare": "husky", "prepare": "husky",
"preinstall": "npx only-allow pnpm" "preinstall": "npx only-allow pnpm"
}, },
"version": "2.2.94", "version": "2.4.24",
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@parcel/watcher", "@parcel/watcher",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB