From d2123ffb25f32980d14815ec67b4350c7beb307a Mon Sep 17 00:00:00 2001 From: Aurelius Wendelken Date: Sun, 13 Sep 2026 14:49:55 +0200 Subject: [PATCH] feat(ui): redesign community footer --- AGENTS.md | 2 +- app/assets/css/main.css | 23 ++++-- app/components/AppFooter.vue | 64 +++++++++++---- docs/design-reference.md | 4 +- docs/screenshots/desktop-blog.png | Bin 72479 -> 102433 bytes docs/screenshots/desktop-da-datenschutz.png | Bin 337328 -> 422130 bytes docs/screenshots/desktop-da-impressum.png | Bin 85947 -> 118036 bytes .../desktop-da-project-badestellenkarte.png | Bin 228747 -> 260841 bytes .../desktop-da-project-kulturbytes.png | Bin 303591 -> 335968 bytes .../desktop-da-project-kulturnacht-karte.png | Bin 182133 -> 214156 bytes .../desktop-da-project-open-city-planner.png | Bin 247960 -> 280404 bytes .../desktop-da-project-open-data-api.png | Bin 235352 -> 267574 bytes docs/screenshots/desktop-daten-sind-daten.png | Bin 129697 -> 160074 bytes docs/screenshots/desktop-de-datenschutz.png | Bin 414077 -> 496838 bytes docs/screenshots/desktop-de-impressum.png | Bin 92055 -> 122294 bytes .../desktop-de-project-badestellenkarte.png | Bin 256740 -> 287474 bytes .../desktop-de-project-kulturbytes.png | Bin 349657 -> 380168 bytes .../desktop-de-project-kulturnacht-karte.png | Bin 205310 -> 235979 bytes .../desktop-de-project-open-city-planner.png | Bin 283936 -> 314140 bytes .../desktop-de-project-open-data-api.png | Bin 265881 -> 296524 bytes docs/screenshots/desktop-en-datenschutz.png | Bin 341253 -> 422879 bytes docs/screenshots/desktop-en-impressum.png | Bin 83663 -> 115163 bytes .../desktop-en-project-badestellenkarte.png | Bin 228193 -> 259559 bytes .../desktop-en-project-kulturbytes.png | Bin 314634 -> 345995 bytes .../desktop-en-project-kulturnacht-karte.png | Bin 189678 -> 221231 bytes .../desktop-en-project-open-city-planner.png | Bin 245996 -> 277763 bytes .../desktop-en-project-open-data-api.png | Bin 234902 -> 266541 bytes docs/screenshots/desktop-home-footer.png | Bin 0 -> 41875 bytes docs/screenshots/desktop-home.png | Bin 579062 -> 609196 bytes docs/screenshots/desktop-mitmachen.png | Bin 276210 -> 306383 bytes docs/screenshots/desktop-projekte.png | Bin 456935 -> 487396 bytes docs/screenshots/desktop-ueber-uns-footer.png | Bin 0 -> 41840 bytes docs/screenshots/desktop-ueber-uns.png | Bin 153611 -> 184047 bytes docs/screenshots/mobile-blog.png | Bin 69428 -> 107348 bytes docs/screenshots/mobile-da-datenschutz.png | Bin 291755 -> 370328 bytes docs/screenshots/mobile-da-impressum.png | Bin 71694 -> 108932 bytes .../mobile-da-project-badestellenkarte.png | Bin 192578 -> 229578 bytes .../mobile-da-project-kulturbytes.png | Bin 263683 -> 300608 bytes .../mobile-da-project-kulturnacht-karte.png | Bin 155855 -> 192894 bytes .../mobile-da-project-open-city-planner.png | Bin 205430 -> 242482 bytes .../mobile-da-project-open-data-api.png | Bin 199926 -> 236913 bytes docs/screenshots/mobile-daten-sind-daten.png | Bin 109784 -> 147608 bytes docs/screenshots/mobile-de-datenschutz.png | Bin 362458 -> 448090 bytes docs/screenshots/mobile-de-impressum.png | Bin 73623 -> 111787 bytes .../mobile-de-project-badestellenkarte.png | Bin 215458 -> 253331 bytes .../mobile-de-project-kulturbytes.png | Bin 299012 -> 336749 bytes .../mobile-de-project-kulturnacht-karte.png | Bin 175420 -> 213187 bytes .../mobile-de-project-open-city-planner.png | Bin 232704 -> 270491 bytes .../mobile-de-project-open-data-api.png | Bin 225522 -> 263301 bytes docs/screenshots/mobile-en-datenschutz.png | Bin 287022 -> 365935 bytes docs/screenshots/mobile-en-impressum.png | Bin 69641 -> 107412 bytes .../mobile-en-project-badestellenkarte.png | Bin 189566 -> 227106 bytes .../mobile-en-project-kulturbytes.png | Bin 265960 -> 303468 bytes .../mobile-en-project-kulturnacht-karte.png | Bin 160658 -> 198240 bytes .../mobile-en-project-open-city-planner.png | Bin 204552 -> 242088 bytes .../mobile-en-project-open-data-api.png | Bin 197934 -> 235400 bytes docs/screenshots/mobile-home-footer.png | Bin 0 -> 46426 bytes docs/screenshots/mobile-home.png | Bin 343782 -> 381402 bytes docs/screenshots/mobile-mitmachen.png | Bin 223926 -> 261777 bytes docs/screenshots/mobile-projekte.png | Bin 494626 -> 532574 bytes docs/screenshots/mobile-ueber-uns-footer.png | Bin 0 -> 46403 bytes docs/screenshots/mobile-ueber-uns.png | Bin 133219 -> 170877 bytes docs/typography.md | 5 +- i18n/locales/da.json | 15 +++- i18n/locales/de.json | 15 +++- i18n/locales/en.json | 15 +++- tests/e2e/footer.spec.ts | 74 ++++++++++++++++++ tests/e2e/site.spec.ts | 10 ++- 68 files changed, 188 insertions(+), 39 deletions(-) create mode 100644 docs/screenshots/desktop-home-footer.png create mode 100644 docs/screenshots/desktop-ueber-uns-footer.png create mode 100644 docs/screenshots/mobile-home-footer.png create mode 100644 docs/screenshots/mobile-ueber-uns-footer.png create mode 100644 tests/e2e/footer.spec.ts diff --git a/AGENTS.md b/AGENTS.md index 78d7eef..29c80eb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,7 +56,7 @@ Do not hand-edit or commit generated runtime/tooling directories: `.nuxt/`, `.ou - Follow **“Variante 1 – klar & kartenbasiert”**: light, clear and friendly, with whitespace, subtle borders/shadows and small radii. No dark theme, neon, glassmorphism or pill buttons. - Reuse Tailwind tokens and shared classes in `app/assets/css/main.css`; avoid arbitrary inline styling, a second CSS system or large UI frameworks. Keep the local Manrope font. See [design-reference.md](docs/design-reference.md) and [typography.md](docs/typography.md). -- Body and descriptions: at least 16 px, important desktop copy 18 px with 28/32 px line height. Use the existing `.prose` (max 48rem), not `prose-sm`. Card titles are 20 px; desktop navigation/buttons at least 16 px, mobile navigation 18 px. Keep secondary copy/tags/footer at 14 px; `text-xs` is reserved for genuine microinformation (currently map attribution). Do not shrink copy to force it into a layout; allow reflow and preserve text contrast. +- Body and descriptions: at least 16 px, important desktop copy 18 px with 28/32 px line height. Use the existing `.prose` (max 48rem), not `prose-sm`. Card titles are 20 px; desktop navigation/buttons at least 16 px, mobile navigation 18 px. Keep secondary copy/tags/footer metadata at 14 px; main footer navigation uses 16 px; `text-xs` is reserved for genuine microinformation (currently map attribution). Do not shrink copy to force it into a layout; allow reflow and preserve text contrast. - The sole organisation master is [public/brand/oklabflensburg-logo.png](public/brand/oklabflensburg-logo.png), unchanged from the [canonical upstream PNG](https://github.com/oklabflensburg/.github/blob/main/resources/oklabflensburg_logo_quadrat.png). Use `site.logo` through `AppLogo.vue`, including header/footer/mobile navigation. No redraw, vectorization, crop, stretch, filters, recolouring, duplicate source or extra wordmark. - Keep organisation, individual project signets, supporting association and network identities distinct. The OK Lab logo is neither every project's icon nor the association/network logo. - Keep images/fonts local and retain provenance/licences. Prefer `NuxtImg` with explicit dimensions and meaningful alt text; existing direct SVG project images remain valid. Use existing assets; the approved Plausible integration in `app/app.vue` is the sole analytics integration (see [analytics.md](docs/analytics.md)). Do not add other trackers or unnecessary third-party embeds. diff --git a/app/assets/css/main.css b/app/assets/css/main.css index 97a1d21..6a6fce7 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -117,13 +117,22 @@ .join-card p { @apply mb-5 text-base leading-7 text-text-muted md:text-lg md:leading-8; } .blog-grid { @apply grid gap-6 md:grid-cols-2; } .blog-card .byline { @apply mb-0 mt-4 text-sm leading-6; } - .footer { @apply border-t border-border bg-white py-6; } - .footer-inner { @apply flex flex-wrap items-center justify-between gap-x-8 gap-y-5; } - .footer-tagline { @apply m-0 max-w-72 text-sm leading-6 text-text-muted; } - .footer-links { @apply flex flex-col gap-2 md:items-end; } - .footer-social { @apply flex items-center gap-2; } - .footer nav { @apply flex flex-wrap gap-x-4 gap-y-2; } - .footer nav a { @apply inline-flex min-h-11 items-center py-2 text-sm text-text-muted no-underline hover:text-brand hover:underline; } + .footer { @apply border-t border-border bg-surface-muted; } + .footer-inner { @apply grid gap-10 py-10 md:grid-cols-2 md:py-12 xl:grid-cols-[2fr_1fr_1fr_1fr] xl:gap-12; } + .footer-inner > * { @apply min-w-0; } + .footer-identity .brand { @apply mb-5 min-h-11 w-fit; } + .footer-tagline { @apply mb-5 max-w-md text-lg leading-8 font-semibold; } + .footer-meeting { @apply mb-6 flex items-start gap-3 text-base leading-7 text-text-muted; } + .footer-meeting svg { @apply mt-1; } + .footer-group-title { @apply mb-3 text-base leading-7 font-bold; } + .footer-group ul { @apply m-0 list-none p-0; } + .footer-group a { @apply inline-flex min-h-11 items-center gap-3 py-2 text-base leading-7 text-text-muted no-underline hover:text-brand hover:underline; } + .footer-meta { @apply flex flex-col gap-3 border-t border-border py-5 text-sm leading-6 text-text-muted xl:flex-row xl:items-center xl:justify-between xl:gap-8; } + .footer-affiliations { @apply flex flex-col sm:flex-row sm:flex-wrap sm:gap-x-6; } + .footer-affiliations p { @apply m-0; } + .footer-meta nav { @apply flex flex-wrap gap-x-5; } + .footer-meta a { @apply inline-flex min-h-11 items-center py-2 text-text-muted underline hover:text-brand; } + .breadcrumbs { @apply pt-6 text-sm text-text-muted; } .breadcrumbs ol { @apply m-0 flex list-none flex-wrap gap-2 p-0; } .breadcrumbs li:not(:last-child)::after { @apply ml-2 text-text-muted; content: '/'; } diff --git a/app/components/AppFooter.vue b/app/components/AppFooter.vue index 9862845..02ea4be 100644 --- a/app/components/AppFooter.vue +++ b/app/components/AppFooter.vue @@ -4,22 +4,58 @@ const localePath = useLocalePath()