feat(website): sync the latest design changes

Headline now leads with agents alongside people, and the second callout
swaps sharing advice for what the shell subcommands make possible — cron, a
script, or an agent driving the client with no daemon to stand up.

Mobile gets the design's newer treatment: the eyebrow and the sub-heading
step aside so the headline and the install button are all that precede the
terminal, nav links and the button row centre, the footer keeps two columns
with the brand spanning both, and under 520px the platform strip drops its
labels to a centred row of icons. That last one makes the icon the only
thing naming the platform, so it carries an aria-label now rather than
being hidden from assistive tech.
This commit is contained in:
Michel de Graaf
2026-07-24 23:58:49 +02:00
parent 33bfc34dc8
commit f60aaac0a8
4 changed files with 66 additions and 33 deletions
+12 -9
View File
@@ -45,7 +45,7 @@ const COLUMNS: readonly FooterColumn[] = [
},
]
const LINK_CLASS = 'text-[13px] text-secondary hover:text-primary'
const LINK_CLASS = 'text-[12.5px] text-secondary hover:text-primary sm:text-[13px]'
const FooterAnchor = ({ label, href }: FooterLink) =>
href.startsWith('/') ? (
@@ -59,12 +59,15 @@ const FooterAnchor = ({ label, href }: FooterLink) =>
)
export const Footer = () => (
<footer className="border-t border-hairline bg-base pt-11 pb-10">
<footer className="border-t border-hairline bg-base pt-7 pb-6 sm:pt-11 sm:pb-10">
<Wrap>
<div className="grid grid-cols-1 gap-8 min-[520px]:grid-cols-2 md:grid-cols-[1.6fr_1fr_1fr_1fr]">
<div className="flex max-w-[320px] flex-col gap-3.5">
{/* Two columns even on the narrowest phone, with the brand spanning
both — one column per link group makes the footer taller than the
page it closes. */}
<div className="grid grid-cols-2 gap-x-4 gap-y-5 sm:gap-8 md:grid-cols-[1.6fr_1fr_1fr_1fr]">
<div className="col-span-2 flex max-w-[320px] flex-col gap-2 sm:gap-3.5 md:col-span-1">
<Wordmark size={22} />
<p className="text-[13px] leading-[22px] text-secondary">
<p className="text-xs leading-[19px] text-secondary sm:text-[13px] sm:leading-[22px]">
A Soulseek client and protocol library for Rust.
</p>
<p className="font-forum text-xs text-muted">
@@ -74,12 +77,12 @@ export const Footer = () => (
{COLUMNS.map((column) => (
<div key={column.heading}>
<h2 className="mb-3.5 text-label uppercase tracking-[var(--tracking-label)] text-secondary">
<h2 className="mb-2 text-label uppercase tracking-[var(--tracking-label)] text-secondary sm:mb-3.5">
{column.heading}
</h2>
<ul>
{column.links.map((link) => (
<li key={link.label} className="mb-2.5">
<li key={link.label} className="mb-1.5 sm:mb-2.5">
<FooterAnchor {...link} />
</li>
))}
@@ -88,10 +91,10 @@ export const Footer = () => (
))}
</div>
<div className="mt-11 flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-hairline pt-5.5 text-[12.5px] text-muted">
<div className="mt-5.5 flex flex-wrap items-center gap-x-4 gap-y-1 border-t border-hairline pt-4 text-[11.5px] text-muted sm:mt-11 sm:gap-x-6 sm:gap-y-2 sm:pt-5.5 sm:text-[12.5px]">
<span>MIT · © 2026 Michel de Graaf</span>
<span className="text-success">No telemetry. Ever.</span>
<span className="ml-auto">{VERSION}</span>
<span className="sm:ml-auto">{VERSION}</span>
</div>
</Wrap>
</footer>
+1 -1
View File
@@ -26,7 +26,7 @@ export const Nav = () => (
<nav
aria-label="Main"
className="order-3 flex w-full items-center gap-0.5 overflow-x-auto border-t border-hairline py-1 [-ms-overflow-style:none] [scrollbar-width:none] sm:order-none sm:w-auto sm:border-t-0 sm:py-0 [&::-webkit-scrollbar]:hidden"
className="order-3 flex w-full items-center justify-center gap-0.5 overflow-x-auto border-t border-hairline py-1 [-ms-overflow-style:none] [scrollbar-width:none] sm:order-none sm:w-auto sm:justify-start sm:border-t-0 sm:py-0 [&::-webkit-scrollbar]:hidden"
>
{ITEMS.map((item) => (
<NavLink
+18 -4
View File
@@ -1,3 +1,5 @@
import { cn } from '@/lib/utils'
export type OsName = 'macOS' | 'Linux' | 'Windows'
const PATHS: Record<Exclude<OsName, 'Windows'>, string> = {
@@ -10,12 +12,24 @@ const PATHS: Record<Exclude<OsName, 'Windows'>, string> = {
const WINDOWS_PATH =
'M2 3.6l8.5-1.2v9.1H2V3.6zm10 -1.35L22.5 1v10.5H12V2.25zM2 12.5h8.5v9.1L2 20.4v-7.9zm10 0h10.5V23L12 21.75V12.5z'
/** Decorative — the adjacent label already names the platform. */
export const OsIcon = ({ name }: { name: OsName }) => (
interface OsIconProps {
name: OsName
className?: string
}
/*
* Labelled rather than decorative: below 520px the adjacent text is hidden,
* so the icon becomes the only thing naming the platform.
*/
export const OsIcon = ({ name, className }: OsIconProps) => (
<svg
viewBox="0 0 24 24"
aria-hidden="true"
className="block size-[22px] shrink-0 text-primary"
role="img"
aria-label={name}
className={cn(
'block size-[22px] shrink-0 text-primary transition-colors group-hover:text-accent',
className,
)}
>
<path fill="currentColor" d={name === 'Windows' ? WINDOWS_PATH : PATHS[name]} />
</svg>