Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/layouts/Base.astro
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ const jsonLd = {
);
document.querySelectorAll('.reveal').forEach((el) => observer.observe(el));

// Past the bottom of the page, the footer's colour rather than the theme's.
const footer = document.querySelector('footer');
if (footer) {
new IntersectionObserver(([entry]) =>
document.documentElement.classList.toggle('at-end', entry.isIntersecting),
).observe(footer);
}

// Besides page views, GoatCounter counts what a visitor came for: a PDF
// downloaded (CV, thesis), an email started, or a link followed out.
declare global {
Expand Down
9 changes: 9 additions & 0 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@
html {
scroll-behavior: smooth;
scroll-padding-top: 80px;
/* What a browser shows past the page's edges: behind Safari's toolbar on
iPhone, and when a scroll bounces. The theme's background at the top, the
footer's green once the footer is on screen (set in Base.astro), so the
page never ends on a band of another colour. */
background: var(--bg);
}

html.at-end {
background: var(--closing);
}

body {
Expand Down
15 changes: 15 additions & 0 deletions tests/site.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,21 @@ test('starts the name near the top on a phone, under a navigation that floats',
await expect(page.locator('#nav')).not.toHaveCSS('background-color', 'rgba(0, 0, 0, 0)');
});

test("paints past the page's edges in the theme's colour, then the footer's", async ({ page }) => {
await page.goto('/');
const html = page.locator('html');
const background = (selector: string) =>
page.locator(selector).evaluate((el) => getComputedStyle(el).backgroundColor);

// At the top, what shows past the edge matches the page.
expect(await background('html')).toBe(await background('body'));

// At the bottom, behind Safari's toolbar, it matches the footer.
await page.locator('footer').scrollIntoViewIfNeeded();
await expect(html).toHaveClass(/at-end/);
await expect(html).toHaveCSS('background-color', await background('footer'));
});

test('counts the visit, and the CV, the thesis, an email and a link out', async ({ page }) => {
// A stand-in for GoatCounter's script, which records what it is given.
await page.route('https://gc.zgo.at/count.js', (route) =>
Expand Down
Loading