Files
soulseek-rs-modded/website/index.html
T
Michel de Graaf 74ad230150 fix(website): clear WCAG AA across both themes, and stop the hero shifting
Contrast was measured, not eyeballed: 41 foreground/background pairs across
both themes and the terminal surface, each against the darkest (light) or
lightest (dark) surface it actually sits on. Five failed. Links on manila
read 3.64:1 and the footer's "No telemetry. Ever." — a claim the site goes
out of its way to make — sat at 2.86:1.

The accent needed splitting rather than moving. #c1502e clears 4.5:1 as a
button fill behind white but only 3.99:1 as an 11px eyebrow on vinyl, so
--accent keeps the brand hue for fills and a new --accent-text carries the
readable cut. The terminal gets the same treatment dark emulators give their
palettes: alarm and oxide brighten inside .tui-content so "Failed" is
legible next to its glyph.

Reduced motion no longer nukes everything. A blanket 0.01ms also kills the
transitions that answer a click, which is feedback rather than movement;
looping and travelling animation stops, the rest caps at 80ms. The TUI
already skipped its opening run and still does.

The hero reserves its box with aspect-ratio from the first paint. It was
prerendered at full unscaled height and collapsed once JS measured, moving
everything below it by ~145px. Measured shift is now 0.

Also: the webfont loads non-blocking (display=swap meant the first frame
never waited for it anyway), footer link groups nest under a heading instead
of sitting level with page sections, and eight tokens nothing referenced
stop shipping.
2026-07-25 00:40:13 +02:00

77 lines
3.3 KiB
HTML

<!doctype html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Root-relative on purpose: Vite rewrites this against `base`, so the
deploy path lives in vite.config.ts alone. -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>soulseek-rs, a Soulseek client for your terminal</title>
<meta
name="description"
content="soulseek-rs is a keyboard-driven Soulseek client and a Rust protocol library. Search, share, browse, and chat from your terminal."
/>
<!-- Browser chrome follows the theme; one value would be wrong half the time. -->
<meta name="theme-color" content="#14110F" media="(prefers-color-scheme: dark)" />
<meta name="theme-color" content="#F2EDE4" media="(prefers-color-scheme: light)" />
<meta property="og:type" content="website" />
<meta property="og:title" content="soulseek-rs" />
<meta
property="og:description"
content="A Soulseek client and protocol library for Rust. Search, share, browse, and chat from your terminal."
/>
<!-- og:url and canonical are rewritten per route by scripts/prerender.ts. -->
<meta property="og:url" content="https://re-invention.nl/soulseek-rs/" />
<link rel="canonical" href="https://re-invention.nl/soulseek-rs/" />
<meta name="twitter:card" content="summary" />
<!-- IBM Plex Mono is the brand typeface. CDN rather than self-hosted
binaries, matching the design system's tokens/fonts.css. OFL 1.1.
Loaded non-blocking: as a plain stylesheet it sat on the critical
path, so first paint waited on a third-party DNS + TLS + fetch. It
buys nothing there — `display=swap` plus the ui-monospace fallback
means the first frame renders in the fallback either way. -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="preload"
as="style"
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700&display=swap"
onload="this.onload=null;this.rel='stylesheet'"
/>
<noscript>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700&display=swap"
/>
</noscript>
<script>
// Runs before first paint so the right theme is already on <html>.
// Without it the page flashes the wrong background on every load.
// Mirrors the resolution order in src/theme/theme-provider.tsx.
;(function () {
try {
var stored = localStorage.getItem('ssrs-theme')
var dark =
stored === 'dark' ||
((stored === null || stored === 'system') &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
var theme = dark ? 'dark' : 'light'
document.documentElement.dataset.theme = theme
document.documentElement.style.colorScheme = theme
} catch (e) {
// localStorage blocked; the dark default in the markup stands.
}
})()
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>