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