From d0c3abd79aadc5fb1349ee0573d137af1cd3472e Mon Sep 17 00:00:00 2001 From: NotSoToothless <67082114+FURRO404@users.noreply.github.com> Date: Sun, 7 Jun 2026 20:11:16 -0700 Subject: [PATCH] please (#1316) --- web/views/timeline.ejs | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/web/views/timeline.ejs b/web/views/timeline.ejs index 574fdea..8a7fe2b 100644 --- a/web/views/timeline.ejs +++ b/web/views/timeline.ejs @@ -111,13 +111,7 @@ @media (min-width: 1024px) { .timeline { - margin-top: 1.25rem; - /* Approx height of everything above row 1's bottom (header + - margin + row 1 cards). The row-1→row-2 gap is computed as - 100vh minus this, so row 2 always lands just below the fold - on any viewport height. THIS is the one knob to tune: raise - it if there's too much empty void, lower it if row 2 peeks. */ - --row1-fold-offset: 700px; + margin-top: 1.5rem; } .timeline-grid { grid-template-columns: repeat(3, 1fr); @@ -161,15 +155,12 @@ .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; } - /* Push row 2 below the fold so it stays hidden on load; the - connector line snakes down through this gap. Self-adjusts to - viewport height: bigger void on 1440, smaller on 1080, with a - 3rem floor. Subtract 10rem for the grid's own row gap. */ + /* Static fallback gap before row 2; JS (applyFirstGap) 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), .timeline-node:nth-child(5), - .timeline-node:nth-child(6) { - margin-top: max(3rem, calc(100vh - var(--row1-fold-offset) - 10rem)); - } + .timeline-node:nth-child(6) { margin-top: 8rem; } .timeline-node:nth-child(7) { grid-area: 3 / 1; } .timeline-node:nth-child(8) { grid-area: 3 / 2; } .timeline-node:nth-child(9) { grid-area: 3 / 3; } @@ -299,7 +290,7 @@ <%- include('partials/nav', { activePage: 'timeline' }) %> -
+

<%= t('timeline.eyebrow') %>

<%= t('timeline.heading') %>

@@ -459,8 +450,27 @@ 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() { + var rowTwo = [nodes[3], nodes[4], nodes[5]].filter(Boolean); + 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). + 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); + rowTwo.forEach(function (n) { n.style.marginTop = gap + 'px'; }); + } + function build() { _samples = null; + applyFirstGap(); // Use layout dimensions (not getBoundingClientRect) so the SVG // coordinate system matches the transform-independent getMarkerCenter. svg.setAttribute('viewBox', '0 0 ' + timeline.offsetWidth + ' ' + timeline.offsetHeight);