please (#1320)
This commit is contained in:
+41
-21
@@ -45,8 +45,8 @@
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.timeline-hero {
|
||||
padding-top: 7.5rem;
|
||||
padding-bottom: 3.25rem; /* room between hero text and row 1 */
|
||||
padding-top: 8.5rem; /* clearance below the fixed nav */
|
||||
padding-bottom: 1.75rem; /* JS centering adds the rest of the hero→row1 gap */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.timeline {
|
||||
margin-top: 2.5rem;
|
||||
margin-top: 1.5rem; /* base; JS centering adds to this */
|
||||
}
|
||||
.timeline-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
@@ -169,7 +169,7 @@
|
||||
.timeline-node:nth-child(4) { grid-area: 2 / 3; }
|
||||
.timeline-node:nth-child(5) { grid-area: 2 / 2; }
|
||||
.timeline-node:nth-child(6) { grid-area: 2 / 1; }
|
||||
/* Static fallback gap before row 2; JS (applyFirstGap) overrides
|
||||
/* Static fallback gap before row 2; JS (layoutFirstScreen) overrides
|
||||
this on desktop with a measured value so row 2 lands just below
|
||||
the fold on any viewport height. */
|
||||
.timeline-node:nth-child(4),
|
||||
@@ -191,10 +191,10 @@
|
||||
already have that room, so they keep the roomier sizing above. */
|
||||
@media (min-width: 1024px) and (max-height: 1080px) {
|
||||
.timeline-hero {
|
||||
padding-top: 4.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
padding-top: 6.5rem; /* nav clearance on short screens */
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.timeline { margin-top: 1rem; }
|
||||
.timeline { margin-top: 0.75rem; }
|
||||
.timeline-card { padding: 1.85rem; }
|
||||
.timeline-title { font-size: 1.5rem; }
|
||||
.timeline-desc { font-size: 1.02rem; line-height: 1.6; }
|
||||
@@ -479,27 +479,47 @@
|
||||
return { x: x, y: y };
|
||||
}
|
||||
|
||||
// Size the gap before row 2 so it sits just below the fold on load,
|
||||
// measured from the real row-1 bottom and the real viewport height —
|
||||
// no per-resolution magic numbers. Desktop (3-col) only.
|
||||
function applyFirstGap() {
|
||||
// Desktop layout pass: vertically centre row 1 + the comet's breathing
|
||||
// band in the viewport (spare space split evenly above row 1 and below
|
||||
// the comet), then push row 2 just under the fold so it stays hidden.
|
||||
// This keeps the same balanced look on any viewport height — no
|
||||
// per-resolution magic numbers.
|
||||
var COMET_BAND = 90; // breathing room reserved below row 1 for the comet
|
||||
function layoutFirstScreen() {
|
||||
var rowTwo = [nodes[3], nodes[4], nodes[5]].filter(Boolean);
|
||||
// Reset both adjustables so we measure the natural layout each time.
|
||||
timeline.style.marginTop = '';
|
||||
rowTwo.forEach(function (n) { n.style.marginTop = ''; });
|
||||
if (!window.matchMedia('(min-width: 1024px)').matches) return;
|
||||
if (!rowTwo.length) return;
|
||||
if (!window.matchMedia('(min-width: 1024px)').matches) {
|
||||
rowTwo.forEach(function (n) { n.style.marginTop = ''; });
|
||||
return;
|
||||
}
|
||||
// Measure row 2's natural top with no extra gap (grid row gap only).
|
||||
|
||||
var vh = window.innerHeight;
|
||||
rowTwo.forEach(function (n) { n.style.marginTop = '0px'; });
|
||||
var top = rowTwo[0].getBoundingClientRect().top + window.pageYOffset;
|
||||
// +32 so the marker (which pokes ~1.8rem above the node) clears too.
|
||||
var gap = Math.max(48, (window.innerHeight + 32) - top);
|
||||
|
||||
// Natural row-1 extent (tallest of the first three cards).
|
||||
var row1Top = Infinity, row1Bottom = 0;
|
||||
for (var k = 0; k < 3 && k < nodes.length; k++) {
|
||||
var r = nodes[k].getBoundingClientRect();
|
||||
row1Top = Math.min(row1Top, r.top);
|
||||
row1Bottom = Math.max(row1Bottom, r.bottom);
|
||||
}
|
||||
var row1Height = row1Bottom - row1Top;
|
||||
|
||||
// Centre: half the leftover height goes above row 1, half below comet.
|
||||
var spare = vh - row1Top - row1Height - COMET_BAND;
|
||||
var topMargin = Math.max(0, spare * 0.5);
|
||||
var base = parseFloat(getComputedStyle(timeline).marginTop) || 0;
|
||||
timeline.style.marginTop = (base + topMargin) + 'px';
|
||||
|
||||
// After the shift, drop row 2 just under the fold (+40 clears its marker).
|
||||
var row2Top = rowTwo[0].getBoundingClientRect().top;
|
||||
var gap = Math.max(48, (vh + 40) - row2Top);
|
||||
rowTwo.forEach(function (n) { n.style.marginTop = gap + 'px'; });
|
||||
}
|
||||
|
||||
function build() {
|
||||
_samples = null;
|
||||
applyFirstGap();
|
||||
layoutFirstScreen();
|
||||
// Use layout dimensions (not getBoundingClientRect) so the SVG
|
||||
// coordinate system matches the transform-independent getMarkerCenter.
|
||||
svg.setAttribute('viewBox', '0 0 ' + timeline.offsetWidth + ' ' + timeline.offsetHeight);
|
||||
@@ -568,7 +588,7 @@
|
||||
// reveal line is the frontier. This keeps the comet just below the last
|
||||
// in-view card on load, then leading the draw as you scroll, instead of
|
||||
// jumping ahead off-screen.
|
||||
var REVEAL_FRACTION = 0.82;
|
||||
var REVEAL_FRACTION = 0.85;
|
||||
function frontierProgress() {
|
||||
if (!pathLength || !_samples) return state.progress;
|
||||
var revealY = window.innerHeight * REVEAL_FRACTION - timeline.getBoundingClientRect().top;
|
||||
|
||||
Reference in New Issue
Block a user