feat(docs-site): brand the docs to match the punktfunk website
apple / swift (push) Successful in 54s
deb / build-publish (push) Successful in 3m7s
decky / build-publish (push) Successful in 12s
ci / rust (push) Successful in 1m35s
ci / web (push) Successful in 28s
ci / docs-site (push) Successful in 39s
android / android (push) Successful in 3m17s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 4s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 27s
ci / bench (push) Successful in 4m44s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m39s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m51s
docker / deploy-docs (push) Successful in 19s
apple / swift (push) Successful in 54s
deb / build-publish (push) Successful in 3m7s
decky / build-publish (push) Successful in 12s
ci / rust (push) Successful in 1m35s
ci / web (push) Successful in 28s
ci / docs-site (push) Successful in 39s
android / android (push) Successful in 3m17s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 4s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 27s
ci / bench (push) Successful in 4m44s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m39s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m51s
docker / deploy-docs (push) Successful in 19s
Theme the Fumadocs docs site with the punktfunk identity, mirroring the marketing site: - Swap the stock `neutral` preset for `purple`, then override --color-fd-* with the violet lens-mark palette (#6c5bf3 / #a79ff8). The brand is the violet, not the site's blue marketing background, so the blue is not used as a reading surface; dark mode tints the chrome toward the app-icon violet-dark (#1c1530). - Adopt @unom/ui's token contract (--brand/--primary/--accent + bg-brand etc.) as the shared token source, and @source its dist. - Load Geist (the brand typeface) via @fontsource-variable/geist. - Add the BrandMark lens to the nav + landing hero, wire the brand favicon.svg, and add Docs/Website nav links. - Keep the Fumadocs light/dark toggle. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// punktfunk brand mark: two overlapping circles forming a lens — the violet
|
||||
// brand identity. Copied verbatim from the marketing site (flattened from the
|
||||
// clients/apple punktfunk_Logo.icon). Back-to-front: large light-violet circle,
|
||||
// deep-violet circle, light highlight where they overlap.
|
||||
export default function BrandMark({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
aria-label="punktfunk"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1000 1000"
|
||||
className={className}
|
||||
>
|
||||
<title>punktfunk</title>
|
||||
<path
|
||||
d="M403.037,791.672c107.586,0 194.41,-86.824 194.41,-194.41c0,-107.586 -86.824,-194.41 -194.41,-194.41c-107.586,0 -194.41,86.824 -194.41,194.41c0,107.586 86.824,194.41 194.41,194.41Z"
|
||||
fill="#a79ff8"
|
||||
/>
|
||||
<path
|
||||
d="M735.276,540.321c76.075,-76.075 76.075,-198.862 0,-274.937c-76.075,-76.075 -198.862,-76.075 -274.937,0c-76.075,76.075 -76.075,198.862 0,274.937c76.075,76.075 198.862,76.075 274.937,0Z"
|
||||
fill="#6c5bf3"
|
||||
/>
|
||||
<path
|
||||
d="M647.84,590.737c-64.853,17.403 -136.871,0.597 -187.885,-50.416c-51.013,-51.013 -67.819,-123.032 -50.416,-187.885c64.853,-17.403 136.871,-0.597 187.885,50.416c51.013,51.013 67.819,123.032 50.416,187.885Z"
|
||||
fill="#d2c9fb"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -1,10 +1,21 @@
|
||||
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'
|
||||
import BrandMark from '@/components/BrandMark'
|
||||
|
||||
// Shared chrome (nav title, links) for both the docs layout and the home layout.
|
||||
// The lens mark + wordmark mirror the punktfunk marketing site's header.
|
||||
export function baseOptions(): BaseLayoutProps {
|
||||
return {
|
||||
nav: {
|
||||
title: 'punktfunk',
|
||||
title: (
|
||||
<>
|
||||
<BrandMark className="size-6" />
|
||||
<span className="font-display font-semibold tracking-tight">punktfunk</span>
|
||||
</>
|
||||
),
|
||||
},
|
||||
links: [
|
||||
{ text: 'Docs', url: '/docs' },
|
||||
{ text: 'Website', url: 'https://punktfunk.unom.io' },
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { createRootRoute, HeadContent, Outlet, Scripts } from '@tanstack/react-router'
|
||||
import * as React from 'react'
|
||||
import { RootProvider } from 'fumadocs-ui/provider/tanstack'
|
||||
import '@fontsource-variable/geist'
|
||||
import appCss from '@/styles/app.css?url'
|
||||
|
||||
export const Route = createRootRoute({
|
||||
@@ -12,7 +13,10 @@ export const Route = createRootRoute({
|
||||
{ name: 'color-scheme', content: 'dark light' },
|
||||
{ title: 'punktfunk docs' },
|
||||
],
|
||||
links: [{ rel: 'stylesheet', href: appCss }],
|
||||
links: [
|
||||
{ rel: 'stylesheet', href: appCss },
|
||||
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
|
||||
],
|
||||
}),
|
||||
component: RootComponent,
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createFileRoute, Link } from '@tanstack/react-router'
|
||||
import { HomeLayout } from 'fumadocs-ui/layouts/home'
|
||||
import BrandMark from '@/components/BrandMark'
|
||||
import { baseOptions } from '@/lib/layout.shared'
|
||||
|
||||
export const Route = createFileRoute('/')({ component: Home })
|
||||
@@ -8,15 +9,16 @@ function Home() {
|
||||
return (
|
||||
<HomeLayout {...baseOptions()}>
|
||||
<main className="flex flex-1 flex-col items-center justify-center gap-6 px-4 py-24 text-center">
|
||||
<h1 className="text-4xl font-bold tracking-tight">punktfunk</h1>
|
||||
<BrandMark className="size-20 drop-shadow-[0_8px_30px_rgba(108,91,243,0.45)]" />
|
||||
<h1 className="font-display text-4xl font-bold tracking-tight">punktfunk</h1>
|
||||
<p className="max-w-xl text-fd-muted-foreground">
|
||||
A ground-up low-latency desktop and game streaming stack, built Linux-first, with a
|
||||
shared Rust protocol core and native clients per platform.
|
||||
Linux-first, low-latency desktop and game streaming — a shared Rust protocol
|
||||
core with native clients per platform.
|
||||
</p>
|
||||
<Link
|
||||
to="/docs/$"
|
||||
params={{ _splat: '' }}
|
||||
className="rounded-lg bg-fd-primary px-5 py-2.5 font-medium text-fd-primary-foreground"
|
||||
className="rounded-lg bg-brand px-5 py-2.5 font-medium text-white transition-colors hover:bg-brand/90"
|
||||
>
|
||||
Read the docs
|
||||
</Link>
|
||||
|
||||
@@ -1,6 +1,77 @@
|
||||
@import 'tailwindcss';
|
||||
@import 'fumadocs-ui/css/neutral.css';
|
||||
@import 'fumadocs-ui/css/purple.css';
|
||||
@import 'fumadocs-ui/css/preset.css';
|
||||
|
||||
/* Pull Fumadocs UI's own classes into the Tailwind 4 scan so they aren't purged. */
|
||||
/* Pull Fumadocs UI's own classes — and @unom/ui's compiled components — into
|
||||
the Tailwind 4 scan so their utilities aren't purged. @unom/ui is the shared
|
||||
design-token system the punktfunk marketing site also builds on. */
|
||||
@source '../../node_modules/fumadocs-ui/dist/**/*.js';
|
||||
@source '../../node_modules/@unom/ui/dist/**/*.{js,mjs}';
|
||||
|
||||
/* ── punktfunk brand ────────────────────────────────────────────────────────
|
||||
The brand colour is the violet lens mark. (The marketing site's blue is just
|
||||
a page background, not the brand.) These values feed both @unom/ui's semantic
|
||||
token contract (--brand/--primary/--accent/--highlight) and the Fumadocs
|
||||
--color-fd-* chrome, so the docs carry the same identity in light and dark. */
|
||||
:root {
|
||||
--pf-brand: #6c5bf3; /* deep violet — primary */
|
||||
--pf-brand-light: #a79ff8; /* light violet */
|
||||
--pf-highlight: #d2c9fb; /* lens highlight */
|
||||
|
||||
/* @unom/ui token contract. */
|
||||
--brand: var(--pf-brand);
|
||||
--primary: var(--pf-brand);
|
||||
--accent: var(--pf-brand);
|
||||
--highlight: var(--pf-highlight);
|
||||
--radius: 0.625rem;
|
||||
|
||||
/* Fumadocs accent → brand violet (light mode). */
|
||||
--color-fd-primary: var(--pf-brand);
|
||||
--color-fd-ring: var(--pf-brand);
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* Lighter violet reads better against the dark surface. */
|
||||
--primary: var(--pf-brand-light);
|
||||
--accent: var(--pf-brand-light);
|
||||
|
||||
--color-fd-primary: var(--pf-brand-light);
|
||||
--color-fd-ring: var(--pf-brand-light);
|
||||
|
||||
/* Tint Fumadocs' dark chrome toward the brand's violet-dark (the app-icon
|
||||
surface #1c1530) instead of the default neutral-dark. */
|
||||
--color-fd-background: #141019;
|
||||
--color-fd-card: #1c1530;
|
||||
--color-fd-popover: #1c1530;
|
||||
--color-fd-secondary: #221a36;
|
||||
--color-fd-muted: #1f1830;
|
||||
--color-fd-accent: #241c3d;
|
||||
--color-fd-border: #2a2148;
|
||||
}
|
||||
|
||||
@theme {
|
||||
/* Geist — the punktfunk brand typeface, same as the marketing site
|
||||
(the @fontsource-variable/geist face is loaded in __root.tsx). */
|
||||
--font-sans: 'Geist Variable', ui-sans-serif, system-ui, sans-serif;
|
||||
--font-display: 'Geist Variable', ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
/* Expose the shared brand + surface tokens as Tailwind colours (bg-brand,
|
||||
text-primary, bg-neutral…), mirroring @unom/ui's own @theme mapping so its
|
||||
utilities resolve to the docs' current (light/dark) surfaces. */
|
||||
@theme inline {
|
||||
--color-brand: var(--brand);
|
||||
--color-primary: var(--primary);
|
||||
--color-accent: var(--accent);
|
||||
--color-highlight: var(--highlight);
|
||||
--color-main: var(--color-fd-foreground);
|
||||
--color-secondary: var(--color-fd-muted-foreground);
|
||||
--color-neutral: var(--color-fd-background);
|
||||
--color-neutral-accent: var(--color-fd-secondary);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user