{batch.products.map((product) => (
s.items);
+ const hasHydrated = useCartStore((s) => s.hasHydrated);
const subtotal = cartTotalCents(items);
const totalQuantity = cartItemCount(items);
const router = useRouter();
@@ -109,6 +111,15 @@ export function CheckoutForm({
}
}
+ // Der Cart-Store haelt seine Positionen nur im Browser (persist/localStorage)
+ // und liest sie erst nach dem ersten Client-Render nach. Ohne diese Weiche
+ // wuerde jede:r Kund:in mit gefuelltem Warenkorb kurz die "leer"-Meldung
+ // sehen, bevor auf das echte Formular umgeschaltet wird — ein grosser,
+ // messbarer Layout-Sprung (siehe CLS) und verwirrend fuer echte Kaeufer:innen.
+ if (!hasHydrated) {
+ return ;
+ }
+
if (items.length === 0) {
return (
@@ -179,7 +190,7 @@ export function CheckoutForm({
))}
{fulfillment === "VERSAND" ? (
-
+
{t.checkoutPage.deliveryTimeNote}
) : null}
diff --git a/src/app/warenkorb/warenkorb-content.tsx b/src/app/warenkorb/warenkorb-content.tsx
index a499fec..88e38f4 100644
--- a/src/app/warenkorb/warenkorb-content.tsx
+++ b/src/app/warenkorb/warenkorb-content.tsx
@@ -7,6 +7,7 @@ import { CartItemThumbnail } from "@/components/cart-item-thumbnail";
import { QuantityStepper } from "@/components/quantity-stepper";
import { ProductCard } from "@/components/product-card";
import { useCartStore, cartTotalCents, cartItemCount } from "@/store/cart-store";
+import WarenkorbLoading from "./loading";
import { useCartStock } from "@/hooks/use-cart-stock";
import { formatPrice } from "@/lib/format";
import { resolveShippingCostCents, getNextShippingTier, type ShippingTierLike } from "@/lib/shipping-calc";
@@ -27,6 +28,7 @@ export function WarenkorbContent({
}) {
const { t, locale } = useI18n();
const items = useCartStore((s) => s.items);
+ const hasHydrated = useCartStore((s) => s.hasHydrated);
const setQuantity = useCartStore((s) => s.setQuantity);
const removeItem = useCartStore((s) => s.removeItem);
// Live-Bestand je Position — derselbe Hinweis wie auf der Produktkarte/
@@ -53,6 +55,12 @@ export function WarenkorbContent({
.filter((product) => !cartProductIds.has(product.id))
.slice(0, CROSS_SELL_LIMIT);
+ // Siehe checkout-form.tsx: ohne diese Weiche flackert kurz die
+ // "leer"-Meldung auf, bevor der Cart-Store aus localStorage nachliest.
+ if (!hasHydrated) {
+ return ;
+ }
+
return (