# Gasser hero parallax + navigation session note

Context: Astro marketing site for a regional construction company using a dark concrete hero, brand-red Gasser mark, and subtle Three.js motion.

## Durable lessons

- When a user reports “two logos over each other”, inspect whether both the DOM and WebGL layers render the same asset. The fix is not to tune opacity; establish one visual source of truth.
- For a 3D brand mark in the hero background:
  - Remove the separate hero `<img>` if the Three.js canvas owns the visual.
  - Keep only the canvas dataset for the 3D logo texture, e.g. `data-logo3d-src`.
  - Use pointer parallax by smoothing `targetPointerX/Y` into `pointerX/Y` inside `requestAnimationFrame`.
  - Move logo and plan/grid layers slightly against each other for depth.
  - Verify with DOM inspection that `.hero img` count is zero when the canvas is intended to be the only hero logo.
- If previous concept was “2D plan becomes 3D logo” but the client finds it unclear, simplify first: one 3D logo, one background grid, direct pointer response.

## Navigation microinteraction pattern

- Sticky header with `[data-scrolled]` after ~24px scroll: darker background, subtle border/shadow.
- Optional `[data-hidden]` when scrolling down past ~180px; reveal on upward scroll.
- Nav hover/focus: brand-red underline + small dot + 1–2px lift.
- Header sheen should trigger on hover/focus only, not loop continuously.

## Verification checklist

- `npm run build` passes.
- Browser QA visually confirms one large 3D logo, not stacked duplicates.
- Console has no JS errors.
- Programmatic sanity check: canvas exists, header exists, and no stray hero logo image remains if the design is WebGL-only.
