diff --git a/app/components/ArrowRightIcon.tsx b/app/components/ArrowRightIcon.tsx new file mode 100644 index 0000000..c506f3f --- /dev/null +++ b/app/components/ArrowRightIcon.tsx @@ -0,0 +1,17 @@ +// Replaces the Unicode "→" (U+2192) previously used inline in CTA links +// (Tools.tsx, Blog.tsx, ProductGrid.tsx) — that glyph isn't covered by the +// site's custom web fonts, so browsers fall back to a system font just for +// that one character. The fallback's vertical metrics differ enough by +// platform (confirmed: sat visibly low relative to the label text on a +// Samsung Galaxy S22/Android Chrome, not reproducible in desktop Chromium) +// that centering it via flex `items-center` alone isn't reliable across +// devices. An SVG has no font-fallback path — it renders identically +// everywhere. `currentColor` stroke follows the parent Link's own +// text/hover color, same as every other icon in this codebase. +export function ArrowRightIcon() { + return ( + + + + ); +} diff --git a/app/components/Blog.tsx b/app/components/Blog.tsx index 7aed233..1fc1072 100644 --- a/app/components/Blog.tsx +++ b/app/components/Blog.tsx @@ -2,6 +2,7 @@ import Link from "next/link"; import Image from "next/image"; import { getBlogPosts } from "../lib/payload"; import { Reveal, RevealGroup, RevealItem } from "./Reveal"; +import { ArrowRightIcon } from "./ArrowRightIcon"; export async function Blog() { const posts = await getBlogPosts(3); @@ -69,7 +70,7 @@ export async function Blog() { href={featured.href} className="flex items-center gap-1 font-bold text-body text-text-primary whitespace-nowrap hover:text-brand transition-colors" > - + Zum Beitrag @@ -122,7 +123,7 @@ export async function Blog() { href={post.href} className="flex items-center gap-1 font-bold text-body whitespace-nowrap hover:text-brand transition-colors" > - + Zum Beitrag diff --git a/app/components/Tools.tsx b/app/components/Tools.tsx index 05e7539..de9583d 100644 --- a/app/components/Tools.tsx +++ b/app/components/Tools.tsx @@ -1,6 +1,7 @@ import Link from "next/link"; import Image from "next/image"; import { Reveal, RevealGroup, RevealItem } from "./Reveal"; +import { ArrowRightIcon } from "./ArrowRightIcon"; import { getWerkzeugeCards } from "../lib/payload"; // Content now lives in Payload (WerkzeugeCards collection). Icons use a @@ -87,17 +88,14 @@ export async function Tools() { {tool.description}

- {/* flex items-center + arrow as its own span, not inline text - — the → glyph sits low relative to the surrounding text's - cap-height in the font used here, off-center against the - label if it's just part of the same text node (fixed - 2026-07-24, same pattern ProductGrid.tsx's "Mehr - erfahren" link already uses). */} + {/* SVG arrow, not a Unicode "→" character — see + ArrowRightIcon.tsx's own comment on why (font-fallback + vertical-metrics mismatch, platform-dependent). */} - + {tool.ctaLabel} diff --git a/app/konto/bestellungen/components/OrderFilters.tsx b/app/konto/bestellungen/components/OrderFilters.tsx index 097795f..f0c0a68 100644 --- a/app/konto/bestellungen/components/OrderFilters.tsx +++ b/app/konto/bestellungen/components/OrderFilters.tsx @@ -1,5 +1,6 @@ "use client"; +import { useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { CustomSelect } from "../../../components/CustomSelect"; @@ -31,6 +32,16 @@ export function OrderFilters({ const paymentStatus = searchParams.get("paymentStatus") ?? ""; const year = searchParams.get("year") ?? ""; const hasAnyFilter = Boolean(status || paymentStatus || year); + const activeCount = [status, paymentStatus, year].filter(Boolean).length; + + // Collapsed by default on mobile — with the account tab bar now also + // stacked above this (see KontoShell/AccountNav), 3 full-width dropdowns + // always visible left little room for the actual order list. Desktop + // (sm+) ignores this entirely and always shows the row inline, same as + // before. Starts expanded whenever a filter is already active (arriving + // via a shared/bookmarked filtered URL shouldn't hide what's applied) — + // a lazy initializer since it only needs to run once, on mount. + const [expanded, setExpanded] = useState(() => hasAnyFilter); function setParam(key: string, value: string) { const params = new URLSearchParams(searchParams.toString()); @@ -43,19 +54,38 @@ export function OrderFilters({ const yearOptions = years.map((y) => ({ value: y, label: y })); return ( -
- setParam("status", v)} /> - setParam("paymentStatus", v)} /> - setParam("year", v)} /> - {hasAnyFilter && ( - - )} +
+ +
+ setParam("status", v)} /> + setParam("paymentStatus", v)} /> + setParam("year", v)} /> + {hasAnyFilter && ( + + )} +
); } diff --git a/app/konto/bestellungen/page.tsx b/app/konto/bestellungen/page.tsx index c067048..98efeda 100644 --- a/app/konto/bestellungen/page.tsx +++ b/app/konto/bestellungen/page.tsx @@ -3,7 +3,6 @@ import { Suspense } from "react"; import { redirect } from "next/navigation"; import Link from "next/link"; import { Reveal } from "../../components/Reveal"; -import { Footer } from "../../components/Footer"; import { formatPrice, formatDate } from "../../lib/format"; import { getSessionCustomer, @@ -14,7 +13,7 @@ import { import { getOrderFilterEnabled } from "../../lib/payload"; import { OrderStatusBadge } from "../components/OrderStatusBadge"; import { PaymentStatusBadge } from "../components/PaymentStatusBadge"; -import { LogoutButton } from "../components/LogoutButton"; +import { KontoShell } from "../components/KontoShell"; import { OrderFilters } from "./components/OrderFilters"; // robots: noindex — account area, same reasoning as /checkout. @@ -60,9 +59,8 @@ export default async function KontoBestellungenPage({ ]); return ( - <> -
- + +

Meine Bestellungen

@@ -135,25 +133,7 @@ export default async function KontoBestellungenPage({
)} - {/* self-center below sm — this row otherwise inherits the parent - Reveal's items-start (left-aligned); centered here per its - own request, but only the row itself (self-center keeps its - shrink-to-fit content width, doesn't stretch it to the full - parent width the way w-full/justify-center on the parent - would). Back to left-aligned (matching the rest of the page) - from sm up. */} -
- - Profil & Adresse - - - Weiter einkaufen - - -
- - -