Identidad visual propia (ver docs-portal/docs/decisiones/0007-identidad-visual-propia.md): paleta terracota/espresso/pino/crema/carbon reemplaza los tokens --color-ari-cyan/magenta/yellow/blue (confirmado sin uso en ningun componente antes de tocarlos). Fraunces + Inter cargadas via next/font/google (antes "Inter" era solo un fallback de CSS sin garantia real de carga). Cambio minimo a proposito: nueva variant "primary" en button.tsx sin tocar la clase base compartida (radio, ring de foco quedan igual para el resto del sitio), aplicada como smoke test unico en el CTA y el precio de ProductCard. El resto de la propagacion (header, footer, badges, home, product detail) queda para las Sub-fases 2-5, cada una con su propio gate. Validado con `docker build --target builder` (npm ci + next build con typecheck completo) -- compila limpio.
36 lines
2.2 KiB
TypeScript
36 lines
2.2 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
|
import { Fraunces, Inter } from "next/font/google";
|
|
import "./globals.css";
|
|
import { CartDrawer } from "@/components/cart/cart-drawer";
|
|
import { Footer } from "@/components/layout/footer";
|
|
import { Navbar } from "@/components/layout/navbar";
|
|
import { WishlistDrawer } from "@/components/wishlist/wishlist-drawer";
|
|
import { getCategories, getProducts } from "@/lib/headless/client";
|
|
|
|
// El Navbar (categorias/colecciones/predictive search) vive en este layout
|
|
// compartido -- si alguna pagina futura queda estatica, este fetch se
|
|
// congelaria con datos de build time (mock) igual que le paso al home
|
|
// (ver app/page.tsx). Forzarlo aca protege el nav en cualquier ruta, no
|
|
// solo en las que hoy ya son dinamicas por otro motivo (searchParams, etc.).
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export const metadata: Metadata = {
|
|
metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL ?? "https://shop.cruzcloud.net"),
|
|
title: { default: "ARI Shopping | Juguetes, regalos y variedades", template: "%s | ARI Shopping" },
|
|
description: "Tienda online de juguetes, personajes, mochilas y regalos con atención personalizada.",
|
|
openGraph: { title: "ARI Shopping", description: "Tesoros para cada aventura.", type: "website", locale: "es_CO" },
|
|
};
|
|
|
|
export const viewport: Viewport = { width: "device-width", initialScale: 1, themeColor: "#2B1B13" };
|
|
|
|
// ADR 0007: Fraunces (titulares/precio) + Inter (UI/cuerpo) cargadas via
|
|
// next/font -- antes "Inter" era solo un nombre de fallback en el CSS, sin
|
|
// garantia real de que el navegador tuviera esa fuente instalada.
|
|
const inter = Inter({ subsets: ["latin"], variable: "--font-inter", display: "swap" });
|
|
const fraunces = Fraunces({ subsets: ["latin"], variable: "--font-fraunces", display: "swap" });
|
|
|
|
export default async function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
|
const [products, categories] = await Promise.all([getProducts(), getCategories()]);
|
|
return <html lang="es" className={`${inter.variable} ${fraunces.variable}`}><body><Navbar products={products} categories={categories} /><main>{children}</main><Footer /><CartDrawer /><WishlistDrawer /></body></html>;
|
|
}
|