diff --git a/public/_headers b/public/_headers index d2006af..e7e92a6 100644 --- a/public/_headers +++ b/public/_headers @@ -5,6 +5,12 @@ Permissions-Policy: accelerometer=(), camera=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=() Strict-Transport-Security: max-age=31536000; includeSubDomains +/_astro/* + Cache-Control: public, max-age=31536000, immutable + +/fonts/* + Cache-Control: public, max-age=31536000, immutable + /img/* Cache-Control: public, max-age=31536000, immutable diff --git a/public/icons/speedtest-tracker.png b/public/icons/speedtest-tracker.png deleted file mode 100644 index b477ea7..0000000 Binary files a/public/icons/speedtest-tracker.png and /dev/null differ diff --git a/public/icons/speedtest-tracker.webp b/public/icons/speedtest-tracker.webp new file mode 100644 index 0000000..eff8c94 Binary files /dev/null and b/public/icons/speedtest-tracker.webp differ diff --git a/public/icons/tdarr.png b/public/icons/tdarr.png deleted file mode 100644 index 419d4a6..0000000 Binary files a/public/icons/tdarr.png and /dev/null differ diff --git a/public/icons/tdarr.webp b/public/icons/tdarr.webp new file mode 100644 index 0000000..9e98ed9 Binary files /dev/null and b/public/icons/tdarr.webp differ diff --git a/scripts/check-dist.mjs b/scripts/check-dist.mjs index 62cf778..ed1be92 100644 --- a/scripts/check-dist.mjs +++ b/scripts/check-dist.mjs @@ -63,7 +63,7 @@ const files = [ ] .filter((f) => f !== SELF && statSync(f).isFile() && statSync(f).size < 3_000_000) /* Binary bytes produce meaningless matches. */ - .filter((f) => !/\.(png|jpe?g|ico|woff2?)$/i.test(f)); + .filter((f) => !/\.(png|jpe?g|webp|ico|woff2?)$/i.test(f)); report('hygiene', files.filter((f) => BANNED.test(read(f)))); /* Nothing authored here may carry a credential or a real private address. @@ -82,7 +82,7 @@ const SECRET = [ [/\b172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}\b/, 'private IP'], ]; const authored = [...globSync('src/**/*'), ...globSync('public/api/**/*')] - .filter((f) => statSync(f).isFile() && !/\.(png|jpe?g|ico|woff2?)$/i.test(f)); + .filter((f) => statSync(f).isFile() && !/\.(png|jpe?g|webp|ico|woff2?)$/i.test(f)); const secretHits = []; for (const f of authored) { const t = read(f); diff --git a/src/pages/index.astro b/src/pages/index.astro index 5e2a462..6610bc9 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -93,6 +93,13 @@ const schema = { href="/fonts/inter-latin.woff2" crossorigin /> + @@ -191,7 +198,7 @@ const schema = {
-
+
@@ -204,7 +211,7 @@ const schema = {
-
+
Monitoring @@ -385,17 +392,27 @@ function fitDemoWidgets() { } const screenW = demoScreen.clientWidth; if (screenW) demoScreen.style.setProperty('--sc', String(screenW / 393)); + /* Measure after --sc lands. The grid resizes with it. Both reads must come + before both writes, or each write forces another layout pass. */ const card = demoScreen.querySelector('.wcell'); - const w = card ? card.getBoundingClientRect().width : 0; - if (w) demoScreen.style.setProperty('--ws', String(w / 170)); const glass = demoScreen.querySelector('.np'); - if (glass && glass.clientWidth) { - demoScreen.style.setProperty('--nps', String(glass.clientWidth / 170)); - } + const cardW = card ? card.getBoundingClientRect().width : 0; + const glassW = glass ? glass.clientWidth : 0; + if (cardW) demoScreen.style.setProperty('--ws', String(cardW / 170)); + if (glassW) demoScreen.style.setProperty('--nps', String(glassW / 170)); +} +let fitQueued = false; +function queueFitDemoWidgets() { + if (fitQueued) return; + fitQueued = true; + requestAnimationFrame(() => { + fitQueued = false; + fitDemoWidgets(); + }); } fitDemoWidgets(); -addEventListener('resize', fitDemoWidgets); -phoneDemo.addEventListener('change', fitDemoWidgets); +addEventListener('resize', queueFitDemoWidgets); +phoneDemo.addEventListener('change', queueFitDemoWidgets); if (reduced) { const strip = document.querySelector('.marquee'); @@ -625,12 +642,12 @@ if (!reduced) { .foot-links{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:-10px 0} .foot-links a{font-size:14px;color:var(--a11y-dim);display:inline-flex;align-items:center;min-height:44px;padding:0 2px} .foot-links a:hover{color:var(--label-primary)} - .foot-links span{color:rgba(255,255,255,.28);font-size:13px} + .foot-links span{color:rgba(255,255,255,.5);font-size:13px} .foot-r{display:flex;flex-direction:column;align-items:flex-end;gap:12px} .verbadge{display:flex;border-radius:5px;overflow:hidden;font-size:12px;font-weight:600} .verbadge span{padding:4px 8px;background:var(--bg-elevated-tertiary);color:var(--label-secondary)} - .verbadge b{padding:4px 8px;background:#007ec6;color:#fff;font-weight:700} - .license{font-size:13px;color:rgba(255,255,255,.45)} + .verbadge b{padding:4px 8px;background:#0072b5;color:#fff;font-weight:700} + .license{font-size:13px;color:rgba(255,255,255,.5)} @media (max-width:1180px){