9 KiB
Site update v3 — Welcome dot, smaller cards, parallax topography, sticky scroll, hero polish
Six changes land together. All in protected/. Server-side untouched.
Files to replace
| File | What changed |
|---|---|
protected/index.html |
Welcome dot added; card sizes reduced 15%; topography layer added (markup + CSS); hero padding reduced; hero-foot restructured (moved into left column, arrow points down) |
protected/timeline.js |
Dot-nav click handler now supports external-* targets (Welcome routes back to /); setActiveDot skips external dots |
protected/bifrost.js |
cellSize and targetW adjusted for the shrunk grid; topography SVG generator + parallax driver added; sticky-scroll velocity damping added for non-pinned scenes |
Change-by-change
1. Welcome dot (nav position 1)
- 8th dot, placed FIRST in the dot-nav (before Timeline).
- On click, navigates to
/— the entrance page. Since the user's session is still valid, they land on the welcome step with the "Learn more" button. - Never shows as active — even when scrolling
/timeline, the Welcome dot stays in the default outlined state. It's a navigation link, not a section marker. - HTML:
<button class="dot-btn" data-target="external-welcome" data-href="/"> - JS:
timeline.js's click handler recognisesexternal-*prefixes and useswindow.location.hrefinstead of the page-switching flow.
2. Cards shrunk 15%
Applies to both animation phases:
Drop phase (.layer-card + .card-box):
- Cards previously spanned
left: 0 / right: 0. Now have7.5%margin on each side (= 15% total width reduction). .card-boxpadding reduced fromclamp(1.75rem, 3.2vw, 2.8rem)→clamp(1.5rem, 2.7vw, 2.4rem).min-heightreduced from 240px → 204px.- Content gap slightly tightened.
Grid phase (.in-grid .card-box):
width: 20vw→width: 17vw. Matchingmax-widthand inner padding also reduced.
bifrost.js (the two places that compute grid geometry):
cellSize = vw * 0.20→vw * 0.17(line ~298)targetW = vw * 0.20→vw * 0.17(line ~423)
3. Parallax topography layer
- New
<div id="overview-topography">sits inside#page-overview, atz-index: 0— behind the Europe map (z-index 1) and all content (z-index 2+). - At init,
bifrost.jsdraws 34 concentric rings (each with multi-harmonic sinusoidal distortion) into the SVG. Path coordinates match the entrance page's "currents" generator — intentionally a visual sibling — but with altered parameters:- 34 rings (vs 26 on entrance), tighter 28px step, larger 32px amplitude
- Positioned with bottom-left anchor (entrance uses top-right)
- Rotated 40° via CSS so the harmonic pattern reads as distinct from the entrance
- Lower opacity (0.04 / 0.07) — it sits behind the map, shouldn't compete
- Parallax: driven from
lenis.on('scroll'), translating the SVG byscrollTop * -0.15pixels (very slow — the layer barely moves, feels like atmospheric depth). - The CSS
rotate(40deg)is composed WITH the JStranslateY()in a single transform string so neither clobbers the other.
4. Sticky scroll (non-pinned scenes only)
- Velocity-damping hook on
lenis.on('scroll'). When a non-pinned scene's vertical midpoint is within ±20% of viewport height from the viewport center, damping engages. - While engaged: multiplies Lenis's
velocityby 0.82 per frame. The scene appears to "hold" the scroll briefly. - Hard cap: 300ms per scene entry. No scene can hold the user for longer than that — even if they stop scrolling in the zone, the damping window expires.
- Re-armed when scene leaves the zone. Each entry gets a fresh 300ms window.
- Excluded scenes:
stack-scene(S2) is already pinned + scrubbed by GSAP ScrollTrigger; damping on top would make its card-fall feel sluggish. Included:hero,words-scene,bifrost,bifrost-meaning,bifrost-join. - Implementation is in
bifrost.jsinit, as part of the Lenis scroll subscribers.
5. Hero text moved up
#heropadding-top:clamp(7rem, 14vh, 11rem)→clamp(3.5rem, 7vh, 5.5rem).#page-overview #hero .hero-wrappadding-top:clamp(6rem, 16vh, 12rem)→clamp(3rem, 8vh, 6rem).- The overview-specific rule is the more-specific selector — it's the one that actually wins on the Overview page. Both updated so a future refactor doesn't accidentally reintroduce the low position.
- Text size, weights, kerning: untouched.
6. Hero footer restructured
Before: <div class="hero-foot"> was position: absolute; bottom: 0 — a separate row spanning the full viewport width. "Supported by" on the left, "Scroll →" (with horizontal right-arrow) on the right.
After: Moved INSIDE the left column, placed immediately after the lede paragraph:
[eyebrow]
[headline]
[lede paragraph]
← margin-top: clamp(2rem, 5vh, 3.5rem)
[Supported by [Innov]] [↓ Scroll]
↑ same baseline ↑ aligned to right edge of left column
.hero-footis nowdisplay: flex; justify-content: space-between; align-items: baseline. Both items share the baseline of "Supported by"..scroll-hint .arrowrotated to vertical:width: 1px; height: 28px. The::afterchevron cap moved from top-right (pointing right) to bottom-left corner, rotated 45° to point down.@keyframes hint:translateX(6px)→translateY(6px). The arrow now bounces downward, matching its new meaning.- Mobile fallback override simplified (no longer needs
position: staticsince the element is no longer absolutely positioned).
Spot-check after deploy
Nav + Welcome dot
- 8 dots visible at bottom center.
- Leftmost dot, hover → tooltip reads "Welcome". Click → browser navigates to
/, entrance welcome step renders. - Second dot, hover → "Timeline". Click → Timeline page (P1) becomes active, Welcome dot stays in default state.
- Scroll through Overview. Watch the active dot cycle: Hero → Architecture → Words → Bifrost → Participate → Join. Welcome dot never lights up.
Cards
- S2 drop phase: cards appear visibly narrower than before (15% reduction — should be noticeable).
- S2 grid phase (scroll through the pin): the 2x2 grid is slightly smaller; text in copy panels doesn't overflow into the grid area.
Topography
- Open Overview page. Behind the Europe map, faint ring patterns visible in the paper — rotated, offset to bottom-left.
- Scroll slowly. The rings shift vertically at a much slower rate than the scene content — barely perceptible but present (parallax).
- The rings are visibly different from the entrance page's currents — rotated, denser, lower opacity.
Sticky scroll
- Scroll with a trackpad or mouse wheel through Overview. When a scene's middle is close to viewport-center, feel a brief slowdown (about 300ms).
- The effect is subtle — you can still scroll quickly through scenes with determined effort.
- Scene 2 (architecture, pinned) is NOT affected. Its scrubbed scroll speed is unchanged.
- No "hostile" feel. If it's too much, reduce
DAMP_FACTORfrom 0.82 → 0.88 in bifrost.js.
Hero
- Hero text (eyebrow, headline, lede) sits in the upper half of the viewport, closer to the site-mark.
- Below the lede, a row: "Supported by Innovationsfonden" on the LEFT, vertical-down "↓ Scroll" arrow on the RIGHT, same baseline.
- The arrow bounces DOWNWARD (translateY animation), not rightward.
- No absolutely-positioned element at the bottom of the hero viewport.
Tuning knobs
If any feel wrong after deploy:
| Tuning | File | Default | Change to |
|---|---|---|---|
| Parallax speed | bifrost.js |
PARALLAX_SPEED = 0.15 |
higher (faster) or lower (slower) |
| Topography density | bifrost.js |
RINGS = 34, STEP = 28 |
reduce rings or increase step for sparser pattern |
| Topography opacity | bifrost.js |
0.04 / 0.07 |
lower to fade further |
| Sticky damping strength | bifrost.js |
DAMP_FACTOR = 0.82 |
0.88 for weaker, 0.75 for stronger |
| Sticky zone size | bifrost.js |
DAMP_ZONE_VH = 0.20 |
0.15 narrower, 0.25 wider |
| Sticky hold duration | bifrost.js |
DAMP_MAX_MS = 300 |
200–500 |
| Hero text position | index.html |
clamp(3rem, 8vh, 6rem) |
increase for lower text |
Things NOT touched
public/entrance.html/entrance.js— unchanged. The currents pattern there remains the original.- S2 card content, S3 sentence, S5/S6 content — unchanged.
- Auth flow, session, invite system — unchanged.
- Nav labels (Welcome, Timeline, Hero, Architecture, Words, Bifrost, Participate, Join) — unchanged.
Race condition to watch
There's a race window between timeline.js's /auth/me fetch and bifrost.js's init. If the user clicks the Overview dot before the fetch resolves, S3 may render with the no-name fallback even for a named invite. On refresh, the name appears correctly. Not critical — flagged in previous CHANGES.md. If this bites in practice, the fix is to await the fetch in the Overview activation path.