# Gasser homepage intro animation, route-swap, and browser-cache pattern

Session-derived notes from tuning the Gasser Bauunternehmen Astro homepage intro.

## Problem observed

A homepage-only 3D logo intro looked like it was still using an older animation and appeared to blink/pulse twice, especially when navigating from `/leistungen/` back to `/` with Astro ClientRouter.

Root causes/pitfalls:

- If the homepage intro element defaults to visible and is then hidden by JS/sessionStorage, it can flash during client-side route swaps before the hiding class is applied.
- Page-transition overlays can have their own brand mark/text animation; users may perceive that as the same homepage logo blinking again.
- Browser cache can mask CSS/JS changes, especially in Firefox, making animation QA misleading.

## Durable implementation pattern

For a homepage-only first-visit intro in Astro:

1. Make the intro hidden by default:

```css
.site-intro { display: none; }
.has-pending-gasser-intro .site-intro { display: grid; }
.has-seen-gasser-intro .site-intro { display: none; }
```

2. In an inline head script, decide before body paint whether the intro should run:

```astro
<script is:inline define:vars={{ isHome }}>
  try {
    const introSeen = sessionStorage.getItem('gasserIntroSeen') === '1';
    document.documentElement.classList.remove('has-pending-gasser-intro', 'has-seen-gasser-intro');
    if (isHome && !introSeen) {
      document.documentElement.classList.add('has-pending-gasser-intro');
      sessionStorage.setItem('gasserIntroSeen', '1');
    } else {
      document.documentElement.classList.add('has-seen-gasser-intro');
      if (!isHome) sessionStorage.setItem('gasserIntroSeen', '1');
    }
  } catch (_) {
    if (isHome) document.documentElement.classList.add('has-pending-gasser-intro');
  }
</script>
```

This means:

- direct first homepage load: intro runs once;
- direct non-home load: mark the session as seen so internal navigation home does not trigger it;
- client-side route swaps to `/`: no visible intro flash because default CSS is hidden.

3. For “aufblenden + reinzoomen + gleichzeitig abblenden”, use one continuous animation, not pulse/settle keyframes:

```css
.site-intro {
  animation: gasser-intro-shell 1500ms linear both;
  pointer-events: none;
}

.site-intro__mark {
  transform-origin: 50% 50%;
  animation: gasser-intro-logo 1500ms linear both;
  will-change: transform, opacity;
  contain: layout paint style;
}

@keyframes gasser-intro-shell {
  0% { opacity: 0; }
  10% { opacity: 1; }
  56% { opacity: 0.72; }
  100% { opacity: 0; visibility: hidden; }
}

@keyframes gasser-intro-logo {
  0% { opacity: 0; transform: translate3d(0,0,0) scale(0.76); animation-timing-function: cubic-bezier(.18,.82,.2,1); }
  16% { opacity: 1; transform: translate3d(0,0,0) scale(1); animation-timing-function: cubic-bezier(.05,.78,.08,1); }
  62% { opacity: 0.62; transform: translate3d(0,0,0) scale(14); animation-timing-function: cubic-bezier(.2,.86,.18,1); }
  100% { opacity: 0; transform: translate3d(0,0,0) scale(74); }
}
```

4. Remove or hide brand-mark text from page-transition overlays if it can be confused with the homepage logo intro.

## Performance guidance

For this class of 1–1.5s fullscreen logo dive, CSS `transform` + `opacity` is usually better than Three.js:

- no renderer startup;
- no canvas lifecycle;
- no texture/camera setup;
- compositor-friendly;
- easier `prefers-reduced-motion` handling.

Use a small WebP version of the 3D logo and preload it on the homepage; keep PNG as fallback.

## QA checklist

- Direct homepage hard load with cleared sessionStorage: `has-pending-gasser-intro`, duration `1.5s`, image source is WebP.
- Direct homepage second load in same session: `has-seen-gasser-intro`, intro hidden.
- Non-home page load then navigate to `/`: intro element may exist after route swap, but computed display must be `none`.
- Page transition mark must not display if the user complained about duplicate logo blinking.
- Check browser console for errors.

## Firefox cache debugging for animation reviews

Tell the user:

- hard reload: `Ctrl+F5` on Windows/Linux, `Cmd+Shift+R` on Mac;
- per-site data: lock icon → “Cookies and Site Data” / “Cookies und Website-Daten löschen…”;
- DevTools Network tab: enable “Disable cache” while DevTools is open.
