feat: plakat redesign for subpages (projects, books, legal, privacy)

- Shared SubpageShell (HeaderClient paper strip + ink footer) and SubpageIntro,
  btn/ghost/card helpers in app/_ui/subpage.tsx
- Projects list: poster cards with hard ink shadows, filter pills, ink search field;
  no fake 800ms skeleton and no framer-motion opacity:0 in SSR
- Project detail: poster hero, .plakat-prose markdown, links/stack aside,
  back link works without JS
- Books: server-side fetch (visible without JS), cover + rating pills
- Legal notice / privacy: moved to app/_ui/*Client.tsx, root routes removed
  (middleware always redirects to /[locale]), consent reset via useConsent
- ProjectThumbnail rebuilt on Plakat tokens
- Old Header.tsx + test removed; brown/cream/sand palettes and unused
  glass-panel/admin-glass(-light)/liquid-bg-blob/float CSS dropped
  (liquid palette, glass-card, admin-glass-card stay for admin + 404)
- .plakat-prose replaces the missing typography plugin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
denshooter
2026-10-16 00:00:58 +02:00
parent 4f5089ce38
commit 20b719893c
22 changed files with 918 additions and 1005 deletions
+9 -5
View File
@@ -18,11 +18,15 @@ import ScrollFadeIn from "@/app/components/ScrollFadeIn"
`AnimatePresence` is fine for modals and overlays that only appear after user interaction.
## Design system
- Colors: only `liquid-*` tokens — no hardcoded hex or raw Tailwind palette colors
- Cards: `bg-gradient-to-br from-liquid-*/15 via-liquid-*/10 to-liquid-*/15 backdrop-blur-sm border-2 rounded-xl`
- Headlines: `uppercase tracking-tighter` with accent dot `<span className="text-emerald-600">.</span>`
- Body text: `text-stone-600 dark:text-stone-400` — never `text-stone-400` alone (fails contrast)
## Design system (Plakat)
- Colors: only the Plakat tokens `signal`, `ink`, `paper`, `paper-2`, `ok` — no hex, no raw Tailwind palette, no `liquid-*` (left over only in admin and 404)
- Ink and paper swap roles in dark mode on their own; `signal` stays red
- Fonts: `font-display` (Bricolage, `[font-variation-settings:'wdth'_80]` for posters), `font-sans` (Geist), `font-mono` (Geist Mono)
- Cards: `rounded-[18px] border-2 border-ink` + hard offset shadow `shadow-[6px_6px_0_rgb(var(--plakat-ink))]`
- Pills: `rounded-full` with `shadow-[inset_0_0_0_1.5px_rgb(var(--plakat-ink))]`, filled variant `bg-ink text-paper`
- Labels: `font-mono text-[13px]`; nothing below 12px
- Subpages: wrap in `app/_ui/SubpageShell.tsx`, reuse `SubpageIntro`, `btn`, `ghost`, `card` from `app/_ui/subpage.tsx`; long text in `.plakat-prose`
- Motion: `ease-out` / `ease-drawer`, press feedback `active:scale-[0.97]`, never `transition-all`
## Async components
Every component that fetches data must have a Skeleton loading state shown while data loads.