Replace the legacy plausible.js + data-domain tag with Plausible's new
per-site script (pa-*.js) plus its inline init queue. The site identity
is baked into the script hash, so data-domain is no longer needed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This reverts the hardcoded footer fallback. The footer stays fully CMS-driven;
the unom tenant's footer will be populated to mirror punktfunk's instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The unom tenant's footer doc has no sections yet (the multi-tenant migration
backfilled the old footer to the punktfunk tenant), so the footer rendered as
an empty, near-invisible bar. Render a sensible default (Übersicht/Rechtliches
links + site tagline) when there are no CMS sections; CMS content overrides it
once the unom footer is populated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Pull in @unom/ui (0.8.16) + @unom/style + peers; bump @unom/cms to 0.3.0.
- globals.css now provides the full semantic-token contract @unom/ui consumes
(primary/accent/background/ring/radius-card/…), expressed with unom's violet
brand + Inter/Ubuntu.
- Section wraps @unom/ui's Section (in-view animation orchestrator); PostCard,
LatestPosts, and the hero use AnimatedCard/AnimatedText/AnimatedButton/Heading.
- lib/cms.ts moves to the multi-tenant model (tenant=unom), header/footer as
per-tenant collections, + findProjects().
- New Projects section lists this tenant's projects on the landing page
(soft-fails to hidden when empty). Starts with punktfunk.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Title was hardcoded to the German string when I migrated the rest of
the site to paraglide — the rest of the site looked correct on /en/
because the localized meta came from the root route's head() which DID
use m.foo(). Index also passed 'de' literally to findPosts, ignoring
the request locale.
- project.inlang/settings.json with locales [de, en], baseLocale de.
- messages/{de,en}.json hold the strings (tagline, blog labels, etc.).
- vite.config.ts: paraglideVitePlugin compiles to src/paraglide/
(gitignored) on dev/build. Strategy: url → cookie →
preferredLanguage → baseLocale. URL pattern keeps German at /:path
(unprefixed) and English at /en/:path so existing URLs stay valid.
- server.tsx wraps the handler in paraglideMiddleware so AsyncLocalStorage
carries the per-request locale into SSR.
- router.tsx adds rewrite { input: deLocalizeUrl, output: localizeUrl }
so route matching stays locale-agnostic — the router sees /blog while
URLs show /en/blog.
- cms.ts narrows getLocale()'s union back to the de|en pair the CMS
supports, used as the default for find/findGlobal calls.
- Components/routes switch to m.foo() for user-visible strings; date
formatting picks de-DE / en-GB from getLocale().
- Root html lang reads getLocale() so the document language flips per
request.
Known minor: TanStack Start's { title } meta entry still serves the base
locale value (og:title and the description meta are localized correctly).
Will track separately.
- globals.css: tighter type scale (display h1 = 4xl, snug leading), section
spacing scales up at xl (45→80px y), section width caps at 1280 (was 1550)
for better text-line-length, paragraphs constrained to 65ch.
- Secondary text bumped to 0.78 lightness for better contrast on the dark
bg (was 0.85, too low).
- Hover: links get underline-offset + animated color transition; PostCard
lifts on hover with a brand-tinted ring.
- Markdown rhythm rewritten: h2 starts a new visual section (mt-12), p/li
use sensible margins. Drop whitespace-break-spaces (Lexical now emits
real linebreaks).
- Hero: gradient overlay so the tagline reads cleanly over the busy image,
subtle ↓ scroll hint at the bottom, logo scales between 180 / 220 px.
- Hero shrinks from 100vh to 90vh so a slice of below-fold content peeks.
- Logo is now in a normal flex column with the tagline 'Kreative
Webentwicklung aus Rottweil' centered beneath it.
- New LatestPosts section reads the two most recent posts from CMS via
the SDK and skips entirely if posts.length === 0 (so the section
doesn't materialize while the blog is empty).
- Add @payloadcms/sdk + @unom/cms (typed Config) to deps
- .npmrc maps @unom to git.unom.io/api/packages/unom/npm/
- Rewrite src/lib/cms.ts: PayloadSDK<Config> client + typed helpers
(findPageBySlug, findPostBySlug, findPosts, findFooter, findHeader)
- Re-export the structural types (Page, Post, Footer, Header) plus the
legacy aliases (RichTextBlock, LexRoot/LexNode, NavigationSection,
NavigationLink) so existing components keep compiling
- Dockerfile mounts /root/.npmrc as a build secret so bun install can
pull @unom/cms from the private gitea registry
- deploy.yml stages an .npmrc with REGISTRY_TOKEN auth + passes it as
the 'npmrc' build secret
- Add blog routes: /blog (list) + /blog/ (detail), PostCard, all
reading from the CMS via the SDK
- Fix two pre-existing TS errors (@fontsource/inter import, server.tsx
return type)
- Header link sizes to 70% of the header height (aspect-square) so it
fits at all breakpoints instead of overflowing the 100px default
height. Was hard-pinned to 120×120 which clipped on small headers.
- LegalPage adds pt-height-header so content starts below the fixed
header instead of being covered by it (the Landing route stays
full-bleed intentionally).
Without explicit dimensions the browser fell back to the SVG default
(300×150 CSS px), overflowing the 120×120 header link and hiding
behind the backdrop-blur.
Tailwind/CSS parser was normalizing the bare `100` lightness to
`10000%`, which is out of range — browsers fell back to the SVG
default (black), making the white logo invisible on the dark hero.
- Add src/lib/cms.ts: REST helpers (findPageBySlug, findFooter, findHeader)
- Add src/components/RichText.tsx: minimal Lexical → React renderer
(heading h1-h4, paragraph, list, listitem, link, text + linebreaks +
basic text-format bitflags).
- routes/legal/{imprint,privacy}.tsx now fetch via route loader; meta
title + description come from the Page's own fields.
- Footer reads the Footer global via the root route's loader using
getRouteApi('__root__'). Three sections + tagline match the previously
hardcoded structure (now editable via cms.unom.io/admin).
- Drop react-markdown + src/content/legal/*.md (CMS is the source of truth).
Replace the Astro static site with a TanStack Start (Bun runtime) app and
add Dockerfile + compose files so the site can be served from home-main-2
behind the home-reverse-proxy-1 Caddy instead of Netlify. CI workflow
rewritten to build a container image and SSH-deploy to the home host.