customer-presentation/CHANGES 4.md
2026-04-23 13:31:11 +02:00

170 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Site update v5 — hero centered, real pin-scroll, card illustrations, bifrost headline breathing room
Four changes in this round. v4's wheelMultiplier sticky approach is replaced with a proper ScrollTrigger pin implementation because the previous attempts didn't feel sticky enough.
## Files to replace
| File | What changed |
|---|---|
| `protected/index.html` | Hero centered vertically (align-items + padding reset); AI + Agents cards get custom mask-image illustrations; Project Bifrost headline padding + looser line-height |
| `protected/bifrost.js` | wheelMultiplier approach removed; ScrollTrigger pins added on hero, each map stop, and #bifrost-join; map path rebuilds on ScrollTrigger refresh |
| `protected/timeline.js` | **No change** from v4 — copy only if you want fresh copy alongside |
## New files to upload
| File | Destination on server |
|---|---|
| `ai.png` | `/opt/fenja/protected/fenja/illustrations/ai.png` |
| `agents.png` | `/opt/fenja/protected/fenja/illustrations/agents.png` |
If you're using rsync with `--delete`, ensure the local `protected/fenja/illustrations/` folder contains both PNGs so they end up on the VPS. Otherwise the AI and Agents cards will show blank (the mask-image URL points to 404).
## Change-by-change
### 1. Hero vertically centered
- `#hero` is now `align-items: center` (was `start`) with `padding-top: 0`.
- `#page-overview #hero .hero-wrap` also has `padding-top: 0` — parent centering now handles vertical position.
- The whole block (eyebrow + title + lede + hero-foot row) reads as centered on viewport load. No block-level math needed — CSS grid does it.
### 2. Real scroll pinning via GSAP ScrollTrigger
v4's `wheelMultiplier` trick (reducing Lenis wheel input to 0.35× inside a "sticky zone") didn't produce the tactile "scroll a few times to pass" feel you wanted. **Replaced entirely** with proper GSAP ScrollTrigger pins.
**How it works:**
```js
ScrollTrigger.create({
trigger: el,
start: 'center center',
end: '+=300', // 300px of extra scroll distance held
pin: true,
pinSpacing: true, // document grows by 300px — user MUST scroll through
anticipatePin: 1,
});
```
**Pinned targets + their hold distances:**
| Target | Hold | Why |
|---|---|---|
| `#hero` | +300px | Gentle hold on entry |
| `#bifrost-meaning .map-stop--intro` | +260px | Short — it's just an intro card |
| `#bifrost-meaning .map-stop[data-stop="1"]` (Community) | +360px | Full artifact card — noticeable hold |
| `#bifrost-meaning .map-stop[data-stop="2"]` (Advisory Council) | +360px | Same |
| `#bifrost-meaning .map-stop[data-stop="3"]` (Pilot Projects) | +360px | Same |
| `#bifrost-join` | +260px | CTA gets a moment before footer |
**Deliberately NOT pinned** (they already have their own pin/scrub mechanics — double-pinning would fight):
- `#stack-scene` (S2 architecture — GSAP scrub pin)
- `#words-scene` (S3 — position:sticky pin inside tall parent)
- `#bifrost` (S4 — position:sticky pin on `.bifrost-pin`)
**Why pinSpacing:true matters:**
`pinSpacing: true` injects a spacer div that grows the document by the pin hold distance. Without it, the pin is visually held but the scroll counter advances normally — no "scroll multiple times" feeling. With it, every pin zone adds real scroll distance, so the user genuinely has to keep scrolling.
**The map path rebuild:**
`pinSpacing: true` pushes each subsequent map stop further down the document. The winding SVG path that connects the dots is computed from live DOM positions via `buildMapPath()`. To keep the path threading correctly through the shifted dots, `buildMapPath` now re-runs on every `ScrollTrigger.refresh` event. No manual intervention needed.
### 3. Card illustrations — AI + Agents
Two of the four architecture cards now carry bespoke illustrations:
- **The AI** (data-layer="0") → `/fenja/illustrations/ai.png` — the single topographic orb
- **The Agents** (data-layer="3") → `/fenja/illustrations/agents.png` — central orb with six connected smaller orbs
**How the rendering works:**
The PNGs are white line-art on black backgrounds. They're applied via CSS `mask-image` on the existing `.card-brain` element. The black background becomes transparent (mask excludes black) and the white lines paint through in the card's `paper` fill color. Because it's a mask, the lines render as a single flat color on every card background — matches the existing design system.
**Per-card overrides** (layers 1 and 2 keep the default brain mask):
```css
.layer-card[data-layer="0"] .card-brain {
mask-image: url('/fenja/illustrations/ai.png');
aspect-ratio: 1 / 1;
mask-size: contain;
mask-position: center;
}
.layer-card[data-layer="3"] .card-brain {
mask-image: url('/fenja/illustrations/agents.png');
aspect-ratio: 1 / 1;
mask-size: contain;
mask-position: center;
}
```
The PNGs **must be deployed** to `/opt/fenja/protected/fenja/illustrations/` or the cards will show blank. See "New files to upload" above.
### 4. Project Bifrost headline — room to breathe
`.bifrost-pin` has `overflow: hidden` (it clips the aurora arc's off-screen portions). Combined with `.bifrost-name`'s tight `line-height: 0.95` and the italic "Bifrost" token's gradient `background-clip: text`, the top and bottom edges of the headline were getting clipped.
**Fixes, both on `.bifrost-name`:**
- `line-height: 0.95``1.12` — room for ascenders and descenders
- Added `padding: 0.12em 0.08em` — generous vertical buffer absorbed into the headline's own box, so the parent `.bifrost-pin` overflow:hidden doesn't reach into the glyphs
Parent overflow:hidden stays (it's protecting the arc animation). The headline simply carries its own breathing room now.
## Spot-check after deploy
- [ ] Overview → hero text sits vertically centered on viewport load. Visually balanced — not clinging to top or bottom.
- [ ] Scroll past hero → real resistance. After a bit of wheel input, hero unpins and S2 comes in. NOT a smooth flyby.
- [ ] Scroll into treasure map. **Each stop visibly holds** as it reaches viewport center. You need several wheel flicks to pass through Community, then Advisory Council, then Pilot Projects.
- [ ] The winding SVG path still threads through each dot correctly — the path has rebuilt itself to account for the new document height from pin spacing.
- [ ] AI card shows a single textured orb illustration (white line-art, paper color on the card's color).
- [ ] Agents card shows the network-of-orbs illustration.
- [ ] Knowledge and Tools cards still show the default brain illustration.
- [ ] S4 Bifrost reveal: "Project Bifrost" headline visible top to bottom — no clipping on italic "Bifrost" tall letters.
## Tuning knobs
If the pin holds feel too aggressive:
| Target | In `bifrost.js` (`stickyPinSpecs` array) | Change |
|---|---|---|
| Less hero hold | `{ sel: '#hero', hold: 300 }` | → `150` |
| Less treasure map hold | `hold: 360` on `data-stop` entries | → `200` |
| Stronger hold | any `hold: N` | → higher N |
If a single pin feels wrong and you want to kill it without breaking others, just delete that entry from `stickyPinSpecs`.
If the pins break the map path threading (it's rebuilt on refresh but if something's off): open DevTools, scroll through, and verify `buildMapPath` is firing via the `ScrollTrigger.addEventListener('refresh', buildMapPath)` hook. The path uses live DOM positions so it should always match.
## Things NOT touched
- `public/entrance.html` / `entrance.js` — unchanged.
- Any of `src/` (auth, db, sessions) — unchanged.
- S2 architecture scene (scrub pin intact), S3 words fly-in (sticky pin intact), S4 aurora arc (sticky pin intact).
- The topography parallax behind Europe map (from v3) — still present, still working.
- The Welcome dot, 7-section nav, hero-foot restructure — all still in place.
## Deploy steps
```powershell
# Local — copy the new files in
Copy-Item -Force site-update-v5\protected\index.html protected\index.html
Copy-Item -Force site-update-v5\protected\timeline.js protected\timeline.js
Copy-Item -Force site-update-v5\protected\bifrost.js protected\bifrost.js
# Create the illustrations folder if it doesn't exist and copy PNGs
New-Item -ItemType Directory -Force -Path protected\fenja\illustrations
Copy-Item -Force site-update-v5\protected\fenja\illustrations\ai.png protected\fenja\illustrations\
Copy-Item -Force site-update-v5\protected\fenja\illustrations\agents.png protected\fenja\illustrations\
# Test locally
npm run dev
# Verify all four changes work before pushing
# Commit + deploy
git add protected/
git commit -m "Hero centered, real ScrollTrigger pins, AI+Agents card illustrations, Bifrost headline breathing room"
# rsync + VPS steps same as before — rsync picks up the new PNGs automatically
```
On the VPS after rsync, verify the PNGs landed:
```bash
ls -la /opt/fenja/protected/fenja/illustrations/
# Should show: ai.png, agents.png, and the three existing stop illustrations
```
Then `sudo systemctl restart fenja` and spot-check.