diff --git a/src/app.css b/src/app.css index a95068e..b844881 100644 --- a/src/app.css +++ b/src/app.css @@ -32,6 +32,7 @@ --font-family-heading: 'Fraunces', ui-serif, Georgia, 'Times New Roman', serif; --font-size-base: 18px; + --font-size-xs: 14px; --font-size-small: 15px; --font-size-medium: 16px; --font-size-large: 20px; @@ -382,6 +383,14 @@ a { &:active { transform: translateY(0); } + + &.small { + border-radius: var(--border-radius-small); + font-size: var(--font-size-xs); + min-height: 36px; + min-width: fit-content; + padding: 0.5rem 1rem; + } } .icon-button { diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index 1238201..5ade257 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -53,6 +53,13 @@ Terms of Service + @@ -82,4 +89,22 @@ justify-content: center; gap: var(--space-xs); } + + .legal-notice { + margin-top: var(--space-md); + font-size: var(--font-size-xs); + font-weight: var(--font-weight-normal); + color: var(--color-text-tertiary); + max-width: 100%; + } + + .legal-notice a { + color: var(--color-primary); + text-decoration: underline; + text-underline-offset: 0.2em; + } + + .legal-notice a:hover { + color: var(--color-primary-hover); + } diff --git a/src/lib/components/Navigation.svelte b/src/lib/components/Navigation.svelte index 9561c63..2ca252f 100644 --- a/src/lib/components/Navigation.svelte +++ b/src/lib/components/Navigation.svelte @@ -32,7 +32,10 @@ - + + + mifi Ventures home page + + + + + + + diff --git a/src/routes/privacy-policy/+page.svelte b/src/routes/privacy-policy/+page.svelte index a5afc0e..d874668 100644 --- a/src/routes/privacy-policy/+page.svelte +++ b/src/routes/privacy-policy/+page.svelte @@ -1,8 +1,30 @@ @@ -36,6 +58,16 @@ https://mifi.ventures + {:else if section.links} + {#each linkify(para, section.links) as segment} + {#if typeof segment === 'string'} + {segment} + {:else} + {segment.label} + {/if} + {/each} {:else} {para} {/if} @@ -116,6 +148,16 @@ margin: 0 0 var(--space-md) 0; } + .legal-content a { + color: var(--color-primary); + text-decoration: underline; + text-underline-offset: 0.2em; + } + + .legal-content a:hover { + color: var(--color-primary-hover); + } + .legal-section { margin-bottom: var(--space-xl); } diff --git a/static/.well-known/appspecific/com.chrome.devtools.json b/static/.well-known/appspecific/com.chrome.devtools.json new file mode 100644 index 0000000..6c83099 --- /dev/null +++ b/static/.well-known/appspecific/com.chrome.devtools.json @@ -0,0 +1,5 @@ +{ + "name": "mifi Ventures", + "description": "mifi Ventures is a consulting firm that helps early-stage SaaS companies build and scale their businesses.", + "url": "https://mifi.ventures" +} diff --git a/static/assets/js/cookie-consent.js b/static/assets/js/cookie-consent.js new file mode 100644 index 0000000..e8d0370 --- /dev/null +++ b/static/assets/js/cookie-consent.js @@ -0,0 +1,113 @@ +// Cookie consent banner & third-party analytics loader +// - Stores preference in localStorage +// - Shows a bottom banner until user accepts or rejects +// - Loads Google Analytics and Microsoft Clarity only when accepted + +(function () { + 'use strict'; + + var STORAGE_KEY = 'mifi-ventures-cookie-consent'; + var BANNER_ID = 'cookie-banner'; + var BANNER_VISIBLE_CLASS = 'is-visible'; + var hasLoadedThirdParty = false; + + function loadThirdPartyAnalytics() { + if (hasLoadedThirdParty) return; + hasLoadedThirdParty = true; + + // Google Analytics (gtag.js + ga-init.js) + try { + var gtagScript = document.createElement('script'); + gtagScript.async = true; + gtagScript.src = + 'https://www.googletagmanager.com/gtag/js?id=G-36F29PDKRT'; + + gtagScript.onload = function () { + // Load the existing ga-init.js helper once gtag is ready + var gaInit = document.createElement('script'); + gaInit.defer = true; + gaInit.src = '/assets/js/ga-init.js'; + document.head.appendChild(gaInit); + }; + + document.head.appendChild(gtagScript); + } catch (e) { + // Fail silently – analytics are non-essential + console.error('Failed to load Google Analytics', e); + } + + // Microsoft Clarity + try { + var clarityScript = document.createElement('script'); + clarityScript.defer = true; + clarityScript.src = 'https://www.clarity.ms/tag/vuo5q3yf79?ref=bwt'; + document.head.appendChild(clarityScript); + } catch (e2) { + console.error('Failed to load Microsoft Clarity', e2); + } + } + + function hideBanner(banner) { + if (!banner) return; + banner.classList.remove(BANNER_VISIBLE_CLASS); + } + + function showBanner(banner) { + if (!banner) return; + banner.classList.add(BANNER_VISIBLE_CLASS); + } + + function init() { + var banner = document.getElementById(BANNER_ID); + if (!banner) return; + + var acceptBtn = banner.querySelector('[data-consent="accept"]'); + var rejectBtn = banner.querySelector('[data-consent="reject"]'); + + var pref; + try { + pref = window.localStorage.getItem(STORAGE_KEY); + } catch (_) { + pref = null; + } + + if (pref === 'accept') { + hideBanner(banner); + loadThirdPartyAnalytics(); + } else if (pref === 'reject') { + hideBanner(banner); + } else { + showBanner(banner); + } + + if (acceptBtn) { + acceptBtn.addEventListener('click', function () { + try { + window.localStorage.setItem(STORAGE_KEY, 'accept'); + } catch (_) { + // ignore + } + hideBanner(banner); + loadThirdPartyAnalytics(); + }); + } + + if (rejectBtn) { + rejectBtn.addEventListener('click', function () { + try { + window.localStorage.setItem(STORAGE_KEY, 'reject'); + } catch (_) { + // ignore + } + hideBanner(banner); + }); + } + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); + diff --git a/stylelint.config.js b/stylelint.config.js index f2bb310..a765f71 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -14,6 +14,12 @@ export default { 'no-descending-specificity': null, 'media-feature-name-value-no-unknown': null, 'selector-pseudo-element-colon-notation': null, + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: ['global'], + }, + ], }, overrides: [ { diff --git a/tests/cookie-options.spec.ts b/tests/cookie-options.spec.ts new file mode 100644 index 0000000..a1945ee --- /dev/null +++ b/tests/cookie-options.spec.ts @@ -0,0 +1,46 @@ +import { test, expect } from '@playwright/test'; + +test.describe('visual regression', () => { + test('cookie banner is visible', async ({ page }) => { + await page.goto('/'); + await expect(page.locator('#cookie-banner')).toBeVisible(); + }); + + test('cookie banner is not visible when choices are accepted', async ({ page }) => { + await page.goto('/'); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'accept'); + }); + + await page.goto('/'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); + }); + + test('cookie banner is not visible when choices are rejected', async ({ page }) => { + await page.goto('/'); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); + }); + + test('cookie banner is hidden when user selects accept', async ({ page }) => { + await page.goto('/'); + await expect(page.locator('#cookie-banner')).toBeVisible(); + await page.locator('[data-consent="accept"]').click(); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); + await expect(await page.evaluate(() => localStorage.getItem('mifi-ventures-cookie-consent'))).toBe('accept'); + }); + + test('cookie banner is hidden when user selects reject', async ({ page }) => { + await page.goto('/'); + await expect(page.locator('#cookie-banner')).toBeVisible(); + await page.locator('[data-consent="reject"]').click(); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); + await expect(await page.evaluate(() => localStorage.getItem('mifi-ventures-cookie-consent'))).toBe('reject'); + }); +}); diff --git a/tests/unit/cookie-consent.test.ts b/tests/unit/cookie-consent.test.ts new file mode 100644 index 0000000..7c0d678 --- /dev/null +++ b/tests/unit/cookie-consent.test.ts @@ -0,0 +1,119 @@ +/** + * @vitest-environment jsdom + */ +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const SCRIPT_PATH = join(__dirname, '../../static/assets/js/cookie-consent.js'); + +function createBannerDOM() { + const banner = document.createElement('div'); + banner.id = 'cookie-banner'; + + const acceptBtn = document.createElement('button'); + acceptBtn.type = 'button'; + acceptBtn.dataset.consent = 'accept'; + + const rejectBtn = document.createElement('button'); + rejectBtn.type = 'button'; + rejectBtn.dataset.consent = 'reject'; + + banner.appendChild(acceptBtn); + banner.appendChild(rejectBtn); + document.body.appendChild(banner); + + return { banner, acceptBtn, rejectBtn }; +} + +describe('cookie-consent.js', () => { + const STORAGE_KEY = 'mifi-ventures-cookie-consent'; + let dom: ReturnType; + + beforeEach(() => { + // Ensure a fresh DOM and storage for each test + document.body.innerHTML = ''; + window.localStorage.clear(); + dom = createBannerDOM(); + + const code = readFileSync(SCRIPT_PATH, 'utf8'); + // eslint-disable-next-line no-eval + eval(code); + document.dispatchEvent(new Event('DOMContentLoaded')); + }); + + afterEach(() => { + dom.banner.remove(); + vi.restoreAllMocks(); + window.localStorage.clear(); + }); + + it('shows banner when no preference is stored', () => { + expect(dom.banner.classList.contains('is-visible')).toBe(true); + }); + + it('hides banner and loads analytics when preference is "accept"', () => { + document.body.innerHTML = ''; + window.localStorage.setItem(STORAGE_KEY, 'accept'); + dom = createBannerDOM(); + + const appendChildSpy = vi.spyOn(document.head, 'appendChild'); + + const code = readFileSync(SCRIPT_PATH, 'utf8'); + // eslint-disable-next-line no-eval + eval(code); + document.dispatchEvent(new Event('DOMContentLoaded')); + + expect(dom.banner.classList.contains('is-visible')).toBe(false); + expect(appendChildSpy).toHaveBeenCalled(); + const urls = appendChildSpy.mock.calls + .map((args) => (args[0] as HTMLScriptElement).src) + .filter(Boolean); + expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(true); + }); + + it('hides banner when preference is "reject" and does not load analytics', () => { + document.body.innerHTML = ''; + window.localStorage.setItem(STORAGE_KEY, 'reject'); + dom = createBannerDOM(); + + const appendChildSpy = vi.spyOn(document.head, 'appendChild'); + + const code = readFileSync(SCRIPT_PATH, 'utf8'); + // eslint-disable-next-line no-eval + eval(code); + document.dispatchEvent(new Event('DOMContentLoaded')); + + expect(dom.banner.classList.contains('is-visible')).toBe(false); + const urls = appendChildSpy.mock.calls + .map((args) => (args[0] as HTMLScriptElement).src) + .filter(Boolean); + expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(false); + }); + + it('stores "accept" in localStorage, hides banner, and loads analytics on accept click', () => { + const appendChildSpy = vi.spyOn(document.head, 'appendChild'); + + dom.acceptBtn.click(); + + expect(window.localStorage.getItem(STORAGE_KEY)).toBe('accept'); + expect(dom.banner.classList.contains('is-visible')).toBe(false); + expect(appendChildSpy).toHaveBeenCalled(); + }); + + it('stores "reject" in localStorage and hides banner on reject click', () => { + const appendChildSpy = vi.spyOn(document.head, 'appendChild'); + + dom.rejectBtn.click(); + + expect(window.localStorage.getItem(STORAGE_KEY)).toBe('reject'); + expect(dom.banner.classList.contains('is-visible')).toBe(false); + const urls = appendChildSpy.mock.calls + .map((args) => (args[0] as HTMLScriptElement).src) + .filter(Boolean); + expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(false); + }); +}); + diff --git a/tests/visual.spec.ts b/tests/visual.spec.ts index 63b1cf3..4ad6be5 100644 --- a/tests/visual.spec.ts +++ b/tests/visual.spec.ts @@ -7,6 +7,14 @@ test.describe('visual regression', () => { await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('home.png', { fullPage: true }); }); @@ -15,6 +23,15 @@ test.describe('visual regression', () => { await expect(page).toHaveTitle(/SaaS Architecture Services | mifi Ventures/); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); + await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/services'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('services.png', { fullPage: true }); }); @@ -23,6 +40,16 @@ test.describe('visual regression', () => { await expect(page).toHaveTitle(/SaaS Product Architecture Consultant | mifi Ventures/); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); + await expect(page.locator('#faq')).toBeVisible(); + await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/services/hands-on-saas-architecture-consultant'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('services-hands-on-saas-architecture-consultant.png', { fullPage: true }); }); @@ -31,6 +58,16 @@ test.describe('visual regression', () => { await expect(page).toHaveTitle(/MVP Architecture & Launch Consultant | mifi Ventures/); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); + await expect(page.locator('#faq')).toBeVisible(); + await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/services/mvp-architecture-and-launch'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('services-mvp-architecture-and-launch.png', { fullPage: true }); }); @@ -39,6 +76,16 @@ test.describe('visual regression', () => { await expect(page).toHaveTitle(/Fractional CTO for Early-Stage SaaS | mifi Ventures/); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); + await expect(page.locator('#faq')).toBeVisible(); + await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/services/fractional-cto-for-early-stage-saas'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('services-fractional-cto-for-early-stage-saas.png', { fullPage: true }); }); @@ -47,6 +94,16 @@ test.describe('visual regression', () => { await expect(page).toHaveTitle(/Startup Infrastructure Strategy | mifi Ventures/); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); + await expect(page.locator('#faq')).toBeVisible(); + await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/services/stage-aligned-infrastructure'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('services-stage-aligned-infrastructure.png', { fullPage: true }); }); @@ -56,6 +113,14 @@ test.describe('visual regression', () => { await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/privacy-policy'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('privacy-policy.png', { fullPage: true }); }); @@ -65,6 +130,14 @@ test.describe('visual regression', () => { await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('#main')).toBeVisible(); await expect(page.locator('.footer')).toBeVisible(); + await expect(page.locator('#cookie-banner')).toBeVisible(); + + await page.evaluate(() => { + localStorage.setItem('mifi-ventures-cookie-consent', 'reject'); + }); + + await page.goto('/terms-of-service'); + await expect(page.locator('#cookie-banner')).not.toBeVisible(); await expect(page).toHaveScreenshot('terms-of-service.png', { fullPage: true }); }); }); diff --git a/tests/visual.spec.ts-snapshots/home-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/home-chromium-desktop-linux.png index 6548b8e..b2a0895 100644 Binary files a/tests/visual.spec.ts-snapshots/home-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/home-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/home-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/home-chromium-mobile-linux.png index 2d7d2f0..d4b89bc 100644 Binary files a/tests/visual.spec.ts-snapshots/home-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/home-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/privacy-policy-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/privacy-policy-chromium-desktop-linux.png index 4e5089e..1560296 100644 Binary files a/tests/visual.spec.ts-snapshots/privacy-policy-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/privacy-policy-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/privacy-policy-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/privacy-policy-chromium-mobile-linux.png index 0e80e89..8263097 100644 Binary files a/tests/visual.spec.ts-snapshots/privacy-policy-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/privacy-policy-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/services-chromium-desktop-linux.png index 8af9269..4545a2f 100644 Binary files a/tests/visual.spec.ts-snapshots/services-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/services-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/services-chromium-mobile-linux.png index 2561499..da47c15 100644 Binary files a/tests/visual.spec.ts-snapshots/services-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/services-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-desktop-linux.png index 6a30ca9..f641f5f 100644 Binary files a/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-mobile-linux.png index f2b8eda..f687805 100644 Binary files a/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/services-fractional-cto-for-early-stage-saas-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-desktop-linux.png index cb1bbe7..ed82f7b 100644 Binary files a/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-mobile-linux.png index e68678d..daaeda6 100644 Binary files a/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/services-hands-on-saas-architecture-consultant-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-desktop-linux.png index 707ffed..a8bd853 100644 Binary files a/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-mobile-linux.png index 2d618ba..0eba1dd 100644 Binary files a/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/services-mvp-architecture-and-launch-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-desktop-linux.png index 16fc5ef..c0b1eee 100644 Binary files a/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-mobile-linux.png index 94ec3a1..5e2759a 100644 Binary files a/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/services-stage-aligned-infrastructure-chromium-mobile-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/terms-of-service-chromium-desktop-linux.png b/tests/visual.spec.ts-snapshots/terms-of-service-chromium-desktop-linux.png index 10a56ed..0fbc592 100644 Binary files a/tests/visual.spec.ts-snapshots/terms-of-service-chromium-desktop-linux.png and b/tests/visual.spec.ts-snapshots/terms-of-service-chromium-desktop-linux.png differ diff --git a/tests/visual.spec.ts-snapshots/terms-of-service-chromium-mobile-linux.png b/tests/visual.spec.ts-snapshots/terms-of-service-chromium-mobile-linux.png index 29e6b9e..da429fa 100644 Binary files a/tests/visual.spec.ts-snapshots/terms-of-service-chromium-mobile-linux.png and b/tests/visual.spec.ts-snapshots/terms-of-service-chromium-mobile-linux.png differ