@cimplify/sdk 0.40.1 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dispatcher.mjs +3 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/templates/storefront-bakery/.env.example +5 -0
- package/templates/storefront-bakery/AGENTS.md +57 -0
- package/templates/storefront-bakery/app/about/page.tsx +21 -44
- package/templates/storefront-bakery/app/categories/[slug]/page.tsx +2 -1
- package/templates/storefront-bakery/app/collections/[slug]/page.tsx +2 -1
- package/templates/storefront-bakery/app/error.tsx +60 -0
- package/templates/storefront-bakery/app/faq/page.tsx +13 -89
- package/templates/storefront-bakery/app/layout.tsx +37 -2
- package/templates/storefront-bakery/app/llms.txt/route.ts +94 -0
- package/templates/storefront-bakery/app/not-found.tsx +39 -0
- package/templates/storefront-bakery/app/page.tsx +6 -6
- package/templates/storefront-bakery/app/privacy/page.tsx +24 -68
- package/templates/storefront-bakery/app/robots.ts +18 -0
- package/templates/storefront-bakery/app/shop/page.tsx +3 -2
- package/templates/storefront-bakery/app/sitemap.ts +62 -0
- package/templates/storefront-bakery/app/terms/page.tsx +24 -82
- package/templates/storefront-bakery/components/footer.tsx +88 -130
- package/templates/storefront-bakery/components/header.tsx +8 -16
- package/templates/storefront-bakery/lib/brand.ts +453 -0
- package/templates/storefront-fashion/.env.example +16 -0
- package/templates/storefront-fashion/AGENTS.md +52 -0
- package/templates/storefront-fashion/README.md +77 -0
- package/templates/storefront-fashion/app/about/page.tsx +41 -0
- package/templates/storefront-fashion/app/cart/page.tsx +9 -0
- package/templates/storefront-fashion/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-fashion/app/categories/[slug]/page.tsx +130 -0
- package/templates/storefront-fashion/app/checkout/page.tsx +17 -0
- package/templates/storefront-fashion/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-fashion/app/collections/[slug]/page.tsx +130 -0
- package/templates/storefront-fashion/app/error.tsx +61 -0
- package/templates/storefront-fashion/app/faq/page.tsx +46 -0
- package/templates/storefront-fashion/app/globals.css +46 -0
- package/templates/storefront-fashion/app/layout.tsx +76 -0
- package/templates/storefront-fashion/app/llms.txt/route.ts +94 -0
- package/templates/storefront-fashion/app/not-found.tsx +39 -0
- package/templates/storefront-fashion/app/orders/[id]/page.tsx +24 -0
- package/templates/storefront-fashion/app/page.tsx +183 -0
- package/templates/storefront-fashion/app/privacy/page.tsx +44 -0
- package/templates/storefront-fashion/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-fashion/app/products/[slug]/product-detail.tsx +71 -0
- package/templates/storefront-fashion/app/robots.ts +18 -0
- package/templates/storefront-fashion/app/shop/page.tsx +63 -0
- package/templates/storefront-fashion/app/shop/shop-client.tsx +32 -0
- package/templates/storefront-fashion/app/sitemap.ts +59 -0
- package/templates/storefront-fashion/app/terms/page.tsx +44 -0
- package/templates/storefront-fashion/components/brand-marquee.tsx +27 -0
- package/templates/storefront-fashion/components/cart-pill.tsx +32 -0
- package/templates/storefront-fashion/components/category-grid.tsx +28 -0
- package/templates/storefront-fashion/components/category-tiles.tsx +104 -0
- package/templates/storefront-fashion/components/collection-strip.tsx +45 -0
- package/templates/storefront-fashion/components/feature-hero.tsx +82 -0
- package/templates/storefront-fashion/components/footer.tsx +153 -0
- package/templates/storefront-fashion/components/header.tsx +43 -0
- package/templates/storefront-fashion/components/hero.tsx +28 -0
- package/templates/storefront-fashion/components/nav-link.tsx +20 -0
- package/templates/storefront-fashion/components/newsletter.tsx +50 -0
- package/templates/storefront-fashion/components/promo-banner.tsx +41 -0
- package/templates/storefront-fashion/components/providers.tsx +31 -0
- package/templates/storefront-fashion/components/section-heading.tsx +37 -0
- package/templates/storefront-fashion/components/store-product-card.tsx +83 -0
- package/templates/storefront-fashion/components/trade-in-cta.tsx +54 -0
- package/templates/storefront-fashion/components/trust-bar.tsx +66 -0
- package/templates/storefront-fashion/lib/brand.ts +421 -0
- package/templates/storefront-fashion/lib/cart.ts +27 -0
- package/templates/storefront-fashion/next.config.ts +40 -0
- package/templates/storefront-fashion/package.json +28 -0
- package/templates/storefront-fashion/postcss.config.mjs +7 -0
- package/templates/storefront-fashion/tsconfig.json +23 -0
- package/templates/storefront-grocery/.env.example +16 -0
- package/templates/storefront-grocery/AGENTS.md +39 -0
- package/templates/storefront-grocery/README.md +73 -0
- package/templates/storefront-grocery/app/about/page.tsx +38 -0
- package/templates/storefront-grocery/app/cart/page.tsx +9 -0
- package/templates/storefront-grocery/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-grocery/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-grocery/app/checkout/page.tsx +17 -0
- package/templates/storefront-grocery/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-grocery/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-grocery/app/error.tsx +60 -0
- package/templates/storefront-grocery/app/faq/page.tsx +46 -0
- package/templates/storefront-grocery/app/globals.css +45 -0
- package/templates/storefront-grocery/app/layout.tsx +75 -0
- package/templates/storefront-grocery/app/llms.txt/route.ts +94 -0
- package/templates/storefront-grocery/app/not-found.tsx +39 -0
- package/templates/storefront-grocery/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-grocery/app/page.tsx +97 -0
- package/templates/storefront-grocery/app/privacy/page.tsx +44 -0
- package/templates/storefront-grocery/app/robots.ts +18 -0
- package/templates/storefront-grocery/app/shop/page.tsx +31 -0
- package/templates/storefront-grocery/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-grocery/app/sitemap.ts +62 -0
- package/templates/storefront-grocery/app/terms/page.tsx +44 -0
- package/templates/storefront-grocery/components/cart-pill.tsx +32 -0
- package/templates/storefront-grocery/components/category-grid.tsx +28 -0
- package/templates/storefront-grocery/components/collection-strip.tsx +45 -0
- package/templates/storefront-grocery/components/footer.tsx +148 -0
- package/templates/storefront-grocery/components/header.tsx +43 -0
- package/templates/storefront-grocery/components/hero.tsx +25 -0
- package/templates/storefront-grocery/components/nav-link.tsx +20 -0
- package/templates/storefront-grocery/components/providers.tsx +31 -0
- package/templates/storefront-grocery/components/store-product-card.tsx +83 -0
- package/templates/storefront-grocery/lib/brand.ts +284 -0
- package/templates/storefront-grocery/lib/cart.ts +27 -0
- package/templates/storefront-grocery/next.config.ts +40 -0
- package/templates/storefront-grocery/package.json +28 -0
- package/templates/storefront-grocery/postcss.config.mjs +7 -0
- package/templates/storefront-grocery/tsconfig.json +23 -0
- package/templates/storefront-restaurant/.env.example +16 -0
- package/templates/storefront-restaurant/AGENTS.md +39 -0
- package/templates/storefront-restaurant/README.md +73 -0
- package/templates/storefront-restaurant/app/about/page.tsx +38 -0
- package/templates/storefront-restaurant/app/cart/page.tsx +9 -0
- package/templates/storefront-restaurant/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-restaurant/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-restaurant/app/checkout/page.tsx +17 -0
- package/templates/storefront-restaurant/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-restaurant/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-restaurant/app/error.tsx +60 -0
- package/templates/storefront-restaurant/app/faq/page.tsx +46 -0
- package/templates/storefront-restaurant/app/globals.css +44 -0
- package/templates/storefront-restaurant/app/layout.tsx +80 -0
- package/templates/storefront-restaurant/app/llms.txt/route.ts +94 -0
- package/templates/storefront-restaurant/app/not-found.tsx +39 -0
- package/templates/storefront-restaurant/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-restaurant/app/page.tsx +97 -0
- package/templates/storefront-restaurant/app/privacy/page.tsx +44 -0
- package/templates/storefront-restaurant/app/robots.ts +18 -0
- package/templates/storefront-restaurant/app/shop/page.tsx +31 -0
- package/templates/storefront-restaurant/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-restaurant/app/sitemap.ts +62 -0
- package/templates/storefront-restaurant/app/terms/page.tsx +44 -0
- package/templates/storefront-restaurant/components/cart-pill.tsx +32 -0
- package/templates/storefront-restaurant/components/category-grid.tsx +28 -0
- package/templates/storefront-restaurant/components/collection-strip.tsx +45 -0
- package/templates/storefront-restaurant/components/footer.tsx +148 -0
- package/templates/storefront-restaurant/components/header.tsx +43 -0
- package/templates/storefront-restaurant/components/hero.tsx +25 -0
- package/templates/storefront-restaurant/components/nav-link.tsx +20 -0
- package/templates/storefront-restaurant/components/product-modal.tsx +105 -0
- package/templates/storefront-restaurant/components/providers.tsx +31 -0
- package/templates/storefront-restaurant/components/store-product-card.tsx +83 -0
- package/templates/storefront-restaurant/lib/brand.ts +287 -0
- package/templates/storefront-restaurant/lib/cart.ts +27 -0
- package/templates/storefront-restaurant/next.config.ts +40 -0
- package/templates/storefront-restaurant/package.json +28 -0
- package/templates/storefront-restaurant/postcss.config.mjs +7 -0
- package/templates/storefront-restaurant/tsconfig.json +23 -0
- package/templates/storefront-retail/.env.example +5 -0
- package/templates/storefront-retail/AGENTS.md +64 -0
- package/templates/storefront-retail/app/about/page.tsx +24 -54
- package/templates/storefront-retail/app/categories/[slug]/page.tsx +2 -1
- package/templates/storefront-retail/app/collections/[slug]/page.tsx +2 -1
- package/templates/storefront-retail/app/error.tsx +61 -0
- package/templates/storefront-retail/app/faq/page.tsx +11 -92
- package/templates/storefront-retail/app/layout.tsx +37 -8
- package/templates/storefront-retail/app/llms.txt/route.ts +94 -0
- package/templates/storefront-retail/app/not-found.tsx +39 -0
- package/templates/storefront-retail/app/page.tsx +16 -73
- package/templates/storefront-retail/app/privacy/page.tsx +24 -81
- package/templates/storefront-retail/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-retail/app/products/[slug]/product-detail.tsx +71 -0
- package/templates/storefront-retail/app/robots.ts +18 -0
- package/templates/storefront-retail/app/shop/page.tsx +3 -3
- package/templates/storefront-retail/app/sitemap.ts +59 -0
- package/templates/storefront-retail/app/terms/page.tsx +24 -97
- package/templates/storefront-retail/components/brand-marquee.tsx +6 -15
- package/templates/storefront-retail/components/feature-hero.tsx +2 -1
- package/templates/storefront-retail/components/footer.tsx +85 -120
- package/templates/storefront-retail/components/header.tsx +10 -12
- package/templates/storefront-retail/components/newsletter.tsx +7 -9
- package/templates/storefront-retail/components/promo-banner.tsx +12 -15
- package/templates/storefront-retail/components/store-product-card.tsx +7 -7
- package/templates/storefront-retail/components/trade-in-cta.tsx +11 -17
- package/templates/storefront-retail/components/trust-bar.tsx +45 -5
- package/templates/storefront-retail/lib/brand.ts +567 -0
- package/templates/storefront-services/.env.example +16 -0
- package/templates/storefront-services/AGENTS.md +41 -0
- package/templates/storefront-services/README.md +73 -0
- package/templates/storefront-services/app/about/page.tsx +38 -0
- package/templates/storefront-services/app/cart/page.tsx +9 -0
- package/templates/storefront-services/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-services/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-services/app/checkout/page.tsx +17 -0
- package/templates/storefront-services/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-services/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-services/app/error.tsx +60 -0
- package/templates/storefront-services/app/faq/page.tsx +46 -0
- package/templates/storefront-services/app/globals.css +45 -0
- package/templates/storefront-services/app/layout.tsx +80 -0
- package/templates/storefront-services/app/llms.txt/route.ts +94 -0
- package/templates/storefront-services/app/not-found.tsx +39 -0
- package/templates/storefront-services/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-services/app/page.tsx +97 -0
- package/templates/storefront-services/app/privacy/page.tsx +44 -0
- package/templates/storefront-services/app/robots.ts +18 -0
- package/templates/storefront-services/app/shop/page.tsx +31 -0
- package/templates/storefront-services/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-services/app/sitemap.ts +62 -0
- package/templates/storefront-services/app/terms/page.tsx +44 -0
- package/templates/storefront-services/components/cart-pill.tsx +32 -0
- package/templates/storefront-services/components/category-grid.tsx +28 -0
- package/templates/storefront-services/components/collection-strip.tsx +45 -0
- package/templates/storefront-services/components/footer.tsx +148 -0
- package/templates/storefront-services/components/header.tsx +43 -0
- package/templates/storefront-services/components/hero.tsx +25 -0
- package/templates/storefront-services/components/nav-link.tsx +20 -0
- package/templates/storefront-services/components/product-modal.tsx +105 -0
- package/templates/storefront-services/components/providers.tsx +31 -0
- package/templates/storefront-services/components/store-product-card.tsx +83 -0
- package/templates/storefront-services/lib/brand.ts +303 -0
- package/templates/storefront-services/lib/cart.ts +27 -0
- package/templates/storefront-services/next.config.ts +40 -0
- package/templates/storefront-services/package.json +28 -0
- package/templates/storefront-services/postcss.config.mjs +7 -0
- package/templates/storefront-services/tsconfig.json +23 -0
- /package/templates/{storefront-retail → storefront-grocery}/components/product-modal.tsx +0 -0
|
@@ -1,84 +1,51 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
svg
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
];
|
|
4
|
+
const ICONS: Record<string, React.ReactNode> = {
|
|
5
|
+
instagram: (
|
|
6
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden className="w-5 h-5">
|
|
7
|
+
<rect x="3" y="3" width="18" height="18" rx="5" />
|
|
8
|
+
<circle cx="12" cy="12" r="4" />
|
|
9
|
+
<circle cx="17.5" cy="6.5" r="0.75" fill="currentColor" />
|
|
10
|
+
</svg>
|
|
11
|
+
),
|
|
12
|
+
x: (
|
|
13
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
14
|
+
<path d="M18 2h3l-7.5 8.6L22 22h-6.6l-5-6.5L4 22H1l8-9.2L1.4 2H8l4.6 6 5.4-6z" />
|
|
15
|
+
</svg>
|
|
16
|
+
),
|
|
17
|
+
tiktok: (
|
|
18
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
19
|
+
<path d="M16 3v3.5a4.5 4.5 0 0 0 4.5 4.5V14a7.5 7.5 0 0 1-4.5-1.5V16a5 5 0 1 1-5-5v3a2 2 0 1 0 2 2V3z" />
|
|
20
|
+
</svg>
|
|
21
|
+
),
|
|
22
|
+
facebook: (
|
|
23
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
24
|
+
<path d="M14 9V7a1 1 0 0 1 1-1h2V3h-3a4 4 0 0 0-4 4v2H8v3h2v9h3v-9h2.5l.5-3H13z" />
|
|
25
|
+
</svg>
|
|
26
|
+
),
|
|
27
|
+
youtube: (
|
|
28
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
29
|
+
<path d="M22.5 6.5a2.6 2.6 0 0 0-1.8-1.8C19 4.2 12 4.2 12 4.2s-7 0-8.7.5A2.6 2.6 0 0 0 1.5 6.5C1 8.2 1 12 1 12s0 3.8.5 5.5a2.6 2.6 0 0 0 1.8 1.8C5 19.8 12 19.8 12 19.8s7 0 8.7-.5a2.6 2.6 0 0 0 1.8-1.8c.5-1.7.5-5.5.5-5.5s0-3.8-.5-5.5zM10 15.5v-7l6 3.5-6 3.5z" />
|
|
30
|
+
</svg>
|
|
31
|
+
),
|
|
32
|
+
linkedin: (
|
|
33
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
34
|
+
<path d="M4 4h4v16H4zM6 2.5a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM10 8h4v2.5h.1c.6-1.1 2-2.5 4-2.5 4 0 4.9 2.6 4.9 6V20h-4v-5c0-1.5-.5-3-2.3-3-1.7 0-2.5 1.3-2.5 3v5h-4z" />
|
|
35
|
+
</svg>
|
|
36
|
+
),
|
|
37
|
+
whatsapp: (
|
|
38
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
39
|
+
<path d="M12 2a10 10 0 0 0-8.6 15l-1.4 5 5.2-1.4A10 10 0 1 0 12 2zm5 14.2c-.2.6-1.2 1.2-1.7 1.2-.5.1-1.1.1-1.7-.1-.4-.1-.9-.3-1.5-.6a8.4 8.4 0 0 1-3.7-3.4c-.7-1-1-1.8-1-2.5 0-.7.4-1.1.6-1.3.2-.2.4-.2.5-.2h.4c.1 0 .3 0 .4.3l.6 1.4c.1.2 0 .3 0 .4l-.3.4-.3.3c-.1.1-.2.2-.1.4.2.4.7 1.1 1.4 1.8.9.8 1.7 1.1 1.9 1.2.2.1.3.1.5-.1l.6-.7c.2-.2.3-.2.5-.1l1.4.7c.2.1.3.2.4.3.1.2.1.6 0 1z" />
|
|
40
|
+
</svg>
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{ label: "Laptops", href: "/categories/laptops" },
|
|
50
|
-
{ label: "Phones", href: "/categories/phones" },
|
|
51
|
-
{ label: "Audio", href: "/categories/audio" },
|
|
52
|
-
{ label: "Accessories", href: "/categories/accessories" },
|
|
53
|
-
{ label: "Deals", href: "/categories/deals" },
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
title: "Support",
|
|
58
|
-
links: [
|
|
59
|
-
{ label: "Contact", href: "mailto:hello@currentselectronics.test" },
|
|
60
|
-
{ label: "Warranty", href: "/faq#warranty--repairs" },
|
|
61
|
-
{ label: "Returns", href: "/faq#payment--returns" },
|
|
62
|
-
{ label: "Shipping", href: "/faq#ordering--delivery" },
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
title: "Company",
|
|
67
|
-
links: [
|
|
68
|
-
{ label: "About", href: "/about" },
|
|
69
|
-
{ label: "Trade-in", href: "/about" },
|
|
70
|
-
{ label: "Business sales", href: "mailto:business@currentselectronics.test" },
|
|
71
|
-
{ label: "Careers", href: "/about" },
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
title: "Legal",
|
|
76
|
-
links: [
|
|
77
|
-
{ label: "Terms of Service", href: "/terms" },
|
|
78
|
-
{ label: "Privacy Policy", href: "/privacy" },
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
];
|
|
44
|
+
const FALLBACK_ICON = (
|
|
45
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden className="w-5 h-5">
|
|
46
|
+
<circle cx="12" cy="12" r="9" />
|
|
47
|
+
</svg>
|
|
48
|
+
);
|
|
82
49
|
|
|
83
50
|
export async function Footer() {
|
|
84
51
|
"use cache";
|
|
@@ -90,36 +57,35 @@ export async function Footer() {
|
|
|
90
57
|
<div>
|
|
91
58
|
<div className="flex items-center gap-2.5 mb-4">
|
|
92
59
|
<span className="grid place-items-center w-8 h-8 rounded-md bg-primary text-primary-foreground text-[13px] font-bold font-mono">
|
|
93
|
-
|
|
60
|
+
{brand.shortName.charAt(0).toUpperCase()}
|
|
94
61
|
</span>
|
|
95
62
|
<span className="text-background text-lg font-bold -tracking-[0.025em]">
|
|
96
|
-
|
|
63
|
+
{brand.name}
|
|
97
64
|
</span>
|
|
98
65
|
</div>
|
|
99
|
-
<p className="leading-relaxed mb-4 max-w-sm">
|
|
100
|
-
Authorised dealer for Apple, Samsung, Sony, Bose. Same-day
|
|
101
|
-
delivery in Accra; nationwide via partner courier. Two-year
|
|
102
|
-
warranty on every product.
|
|
103
|
-
</p>
|
|
66
|
+
<p className="leading-relaxed mb-4 max-w-sm">{brand.footer.blurb}</p>
|
|
104
67
|
<address className="not-italic space-y-1">
|
|
105
|
-
<p className="m-0">
|
|
68
|
+
<p className="m-0">{brand.contact.address}</p>
|
|
106
69
|
<p className="m-0">
|
|
107
|
-
<a
|
|
108
|
-
|
|
70
|
+
<a
|
|
71
|
+
href={`tel:${brand.contact.phoneTel}`}
|
|
72
|
+
className="hover:text-background transition-colors"
|
|
73
|
+
>
|
|
74
|
+
{brand.contact.phone}
|
|
109
75
|
</a>
|
|
110
76
|
</p>
|
|
111
77
|
<p className="m-0">
|
|
112
78
|
<a
|
|
113
|
-
href=
|
|
79
|
+
href={`mailto:${brand.contact.email}`}
|
|
114
80
|
className="hover:text-background transition-colors"
|
|
115
81
|
>
|
|
116
|
-
|
|
82
|
+
{brand.contact.email}
|
|
117
83
|
</a>
|
|
118
84
|
</p>
|
|
119
|
-
<p className="m-0 text-xs">
|
|
85
|
+
<p className="m-0 text-xs">{brand.contact.hours}</p>
|
|
120
86
|
</address>
|
|
121
87
|
<div className="flex items-center gap-3 mt-5">
|
|
122
|
-
{
|
|
88
|
+
{brand.socials.map((s) => (
|
|
123
89
|
<a
|
|
124
90
|
key={s.label}
|
|
125
91
|
href={s.href}
|
|
@@ -128,12 +94,12 @@ export async function Footer() {
|
|
|
128
94
|
rel="noopener noreferrer"
|
|
129
95
|
className="inline-flex items-center justify-center w-9 h-9 rounded-md border border-background/20 hover:bg-primary hover:border-primary transition-colors"
|
|
130
96
|
>
|
|
131
|
-
{s.
|
|
97
|
+
{(s.icon && ICONS[s.icon]) ?? FALLBACK_ICON}
|
|
132
98
|
</a>
|
|
133
99
|
))}
|
|
134
100
|
</div>
|
|
135
101
|
</div>
|
|
136
|
-
{
|
|
102
|
+
{brand.footer.sitemap.map((section) => (
|
|
137
103
|
<nav key={section.title} aria-labelledby={`footer-${section.title}`}>
|
|
138
104
|
<p
|
|
139
105
|
id={`footer-${section.title}`}
|
|
@@ -144,10 +110,7 @@ export async function Footer() {
|
|
|
144
110
|
<ul className="space-y-2 m-0 p-0 list-none">
|
|
145
111
|
{section.links.map((link) => (
|
|
146
112
|
<li key={link.label}>
|
|
147
|
-
<Link
|
|
148
|
-
href={link.href}
|
|
149
|
-
className="hover:text-background transition-colors"
|
|
150
|
-
>
|
|
113
|
+
<Link href={link.href} className="hover:text-background transition-colors">
|
|
151
114
|
{link.label}
|
|
152
115
|
</Link>
|
|
153
116
|
</li>
|
|
@@ -158,29 +121,31 @@ export async function Footer() {
|
|
|
158
121
|
</div>
|
|
159
122
|
|
|
160
123
|
<div className="mt-12 pt-6 border-t border-background/15 flex flex-col sm:flex-row items-center justify-between gap-3 text-xs">
|
|
161
|
-
<p className="m-0">© {year}
|
|
162
|
-
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
<span className="font-semibold tracking-tight">Cimplify</span>
|
|
172
|
-
<svg
|
|
173
|
-
viewBox="0 0 12 12"
|
|
174
|
-
aria-hidden
|
|
175
|
-
className="w-3 h-3 opacity-70"
|
|
176
|
-
fill="none"
|
|
177
|
-
stroke="currentColor"
|
|
178
|
-
strokeWidth="1.5"
|
|
124
|
+
<p className="m-0">© {year} {brand.name}. All rights reserved.</p>
|
|
125
|
+
{brand.footer.poweredBy && (
|
|
126
|
+
<p className="m-0 inline-flex items-center gap-1.5">
|
|
127
|
+
<span className="opacity-70">Powered by</span>
|
|
128
|
+
<a
|
|
129
|
+
href={brand.footer.poweredBy.href}
|
|
130
|
+
target="_blank"
|
|
131
|
+
rel="noopener noreferrer"
|
|
132
|
+
aria-label={brand.footer.poweredBy.label}
|
|
133
|
+
className="inline-flex items-center gap-1 text-background hover:text-primary transition-colors"
|
|
179
134
|
>
|
|
180
|
-
<
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
135
|
+
<span className="font-semibold tracking-tight">{brand.footer.poweredBy.label}</span>
|
|
136
|
+
<svg
|
|
137
|
+
viewBox="0 0 12 12"
|
|
138
|
+
aria-hidden
|
|
139
|
+
className="w-3 h-3 opacity-70"
|
|
140
|
+
fill="none"
|
|
141
|
+
stroke="currentColor"
|
|
142
|
+
strokeWidth="1.5"
|
|
143
|
+
>
|
|
144
|
+
<path d="M3 9L9 3M9 3H4M9 3v5" strokeLinecap="round" strokeLinejoin="round" />
|
|
145
|
+
</svg>
|
|
146
|
+
</a>
|
|
147
|
+
</p>
|
|
148
|
+
)}
|
|
184
149
|
</div>
|
|
185
150
|
</div>
|
|
186
151
|
</footer>
|
|
@@ -2,6 +2,7 @@ import Link from "next/link";
|
|
|
2
2
|
import { Suspense } from "react";
|
|
3
3
|
import { NavLink } from "./nav-link";
|
|
4
4
|
import { CartPill, CartPillSkeleton } from "./cart-pill";
|
|
5
|
+
import { brand } from "@/lib/brand";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Server-rendered header chrome. Brand mark + nav layout streams from the
|
|
@@ -9,27 +10,24 @@ import { CartPill, CartPillSkeleton } from "./cart-pill";
|
|
|
9
10
|
* mounted in their own Suspense boundaries so the chrome never blocks.
|
|
10
11
|
*/
|
|
11
12
|
export function Header() {
|
|
13
|
+
const initial = brand.shortName.charAt(0).toUpperCase();
|
|
12
14
|
return (
|
|
13
15
|
<header className="sticky top-0 z-30 flex items-center justify-between px-6 sm:px-8 py-3.5 border-b border-border bg-background/90 backdrop-blur-md">
|
|
14
16
|
<Link href="/" className="flex items-center gap-2.5 group">
|
|
15
17
|
<span className="grid place-items-center w-8 h-8 rounded-md bg-foreground text-background text-[13px] font-bold font-mono group-hover:bg-primary transition-colors">
|
|
16
|
-
|
|
18
|
+
{initial}
|
|
17
19
|
</span>
|
|
18
|
-
<span className="text-[18px] font-bold -tracking-[0.025em]">
|
|
20
|
+
<span className="text-[18px] font-bold -tracking-[0.025em]">{brand.shortName}</span>
|
|
19
21
|
<span className="hidden sm:inline text-[10px] font-mono uppercase tracking-[0.16em] text-muted-foreground border border-border rounded px-1.5 py-0.5">
|
|
20
|
-
|
|
22
|
+
{brand.microTag}
|
|
21
23
|
</span>
|
|
22
24
|
</Link>
|
|
23
25
|
<nav className="flex items-center gap-5 sm:gap-6">
|
|
24
|
-
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</Suspense>
|
|
30
|
-
<Suspense fallback={<NavLinkFallback>Support</NavLinkFallback>}>
|
|
31
|
-
<NavLink href="/faq">Support</NavLink>
|
|
32
|
-
</Suspense>
|
|
26
|
+
{brand.header.nav.map((link) => (
|
|
27
|
+
<Suspense key={link.href} fallback={<NavLinkFallback>{link.label}</NavLinkFallback>}>
|
|
28
|
+
<NavLink href={link.href}>{link.label}</NavLink>
|
|
29
|
+
</Suspense>
|
|
30
|
+
))}
|
|
33
31
|
<Suspense fallback={<CartPillSkeleton />}>
|
|
34
32
|
<CartPill />
|
|
35
33
|
</Suspense>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { brand } from "@/lib/brand";
|
|
4
5
|
|
|
5
6
|
export function Newsletter() {
|
|
7
|
+
const n = brand.newsletter;
|
|
6
8
|
const [email, setEmail] = useState("");
|
|
7
9
|
const [submitted, setSubmitted] = useState(false);
|
|
8
10
|
|
|
@@ -11,16 +13,12 @@ export function Newsletter() {
|
|
|
11
13
|
<div className="rounded-3xl border border-border bg-card p-8 sm:p-12 grid grid-cols-1 lg:grid-cols-2 gap-8 items-center">
|
|
12
14
|
<div>
|
|
13
15
|
<p className="text-[11px] font-mono uppercase tracking-[0.16em] text-primary mb-2">
|
|
14
|
-
|
|
16
|
+
{n.eyebrow}
|
|
15
17
|
</p>
|
|
16
18
|
<h2 className="text-[clamp(1.5rem,3vw,2rem)] font-bold m-0 mb-3 -tracking-[0.025em]">
|
|
17
|
-
|
|
19
|
+
{n.title}
|
|
18
20
|
</h2>
|
|
19
|
-
<p className="text-muted-foreground leading-relaxed">
|
|
20
|
-
One email a week. Curated launches, our actual price (not the
|
|
21
|
-
launch price), and the deals worth knowing about. No newsletter
|
|
22
|
-
chaff.
|
|
23
|
-
</p>
|
|
21
|
+
<p className="text-muted-foreground leading-relaxed">{n.body}</p>
|
|
24
22
|
</div>
|
|
25
23
|
<form
|
|
26
24
|
onSubmit={(e) => {
|
|
@@ -34,7 +32,7 @@ export function Newsletter() {
|
|
|
34
32
|
required
|
|
35
33
|
value={email}
|
|
36
34
|
onChange={(e) => setEmail(e.target.value)}
|
|
37
|
-
placeholder=
|
|
35
|
+
placeholder={n.placeholder}
|
|
38
36
|
disabled={submitted}
|
|
39
37
|
className="flex-1 px-4 py-3 rounded-md bg-background border border-border focus:border-primary focus:ring-2 focus:ring-primary/20 outline-none transition-shadow text-sm disabled:opacity-50"
|
|
40
38
|
/>
|
|
@@ -43,7 +41,7 @@ export function Newsletter() {
|
|
|
43
41
|
disabled={submitted}
|
|
44
42
|
className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-md bg-foreground text-background font-semibold text-sm hover:bg-primary transition-colors disabled:opacity-50"
|
|
45
43
|
>
|
|
46
|
-
{submitted ?
|
|
44
|
+
{submitted ? n.successLabel : n.submitLabel}
|
|
47
45
|
</button>
|
|
48
46
|
</form>
|
|
49
47
|
</div>
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
-
|
|
3
|
-
interface PromoBannerProps {
|
|
4
|
-
badge: string;
|
|
5
|
-
title: string;
|
|
6
|
-
body: string;
|
|
7
|
-
cta: { label: string; href: string };
|
|
8
|
-
}
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
9
3
|
|
|
10
4
|
/**
|
|
11
|
-
* Full-width promo banner —
|
|
12
|
-
*
|
|
5
|
+
* Full-width promo banner — reads brand.promo. Renders nothing if the
|
|
6
|
+
* brand doesn't define a promo, so this component is safe to drop in
|
|
7
|
+
* across templates that may or may not run a campaign.
|
|
13
8
|
*/
|
|
14
|
-
export function PromoBanner(
|
|
9
|
+
export function PromoBanner() {
|
|
10
|
+
const promo = brand.promo;
|
|
11
|
+
if (!promo) return null;
|
|
15
12
|
return (
|
|
16
13
|
<section className="max-w-7xl mx-auto px-6 sm:px-8 py-6">
|
|
17
14
|
<div className="relative overflow-hidden rounded-3xl bg-gradient-to-br from-primary via-primary to-foreground text-primary-foreground p-8 sm:p-12 lg:p-16">
|
|
@@ -21,18 +18,18 @@ export function PromoBanner({ badge, title, body, cta }: PromoBannerProps) {
|
|
|
21
18
|
<div className="max-w-2xl">
|
|
22
19
|
<span className="inline-flex items-center gap-2 mb-4 px-3 py-1 rounded-full bg-background/15 border border-background/25 text-[11px] font-mono uppercase tracking-[0.16em]">
|
|
23
20
|
<span className="w-1.5 h-1.5 rounded-full bg-background animate-pulse" />
|
|
24
|
-
{badge}
|
|
21
|
+
{promo.badge}
|
|
25
22
|
</span>
|
|
26
23
|
<h2 className="text-[clamp(1.75rem,3.5vw,2.75rem)] font-bold m-0 mb-3 -tracking-[0.025em] leading-[1.1]">
|
|
27
|
-
{title}
|
|
24
|
+
{promo.title}
|
|
28
25
|
</h2>
|
|
29
|
-
<p className="text-base sm:text-lg opacity-90 leading-relaxed">{body}</p>
|
|
26
|
+
<p className="text-base sm:text-lg opacity-90 leading-relaxed">{promo.body}</p>
|
|
30
27
|
</div>
|
|
31
28
|
<Link
|
|
32
|
-
href={
|
|
29
|
+
href={promo.ctaHref}
|
|
33
30
|
className="inline-flex items-center gap-2 px-5 py-3 rounded-md bg-background text-foreground font-semibold text-sm hover:bg-background/90 transition-colors whitespace-nowrap"
|
|
34
31
|
>
|
|
35
|
-
{
|
|
32
|
+
{promo.ctaLabel}
|
|
36
33
|
<svg viewBox="0 0 12 12" className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden>
|
|
37
34
|
<path d="M3 6h7m0 0L7 3m3 3L7 9" strokeLinecap="round" strokeLinejoin="round" />
|
|
38
35
|
</svg>
|
|
@@ -59,22 +59,22 @@ interface Props {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* Variant-aware product card that
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
62
|
+
* Variant-aware product card that links to the dedicated product page at
|
|
63
|
+
* `/products/<slug>`. Statically pre-renderable (no `useSearchParams`),
|
|
64
|
+
* with `prefetch` enabled so hover → instant nav. Full product page
|
|
65
|
+
* (vs a modal) is the right pattern for retail: spec sheets, multi-image
|
|
66
|
+
* galleries, reviews, comparison rails all need vertical real estate.
|
|
67
67
|
*/
|
|
68
68
|
export function StoreProductCard({ product, variant }: Props) {
|
|
69
69
|
const slug = product.slug || product.id;
|
|
70
70
|
const Card = VARIANT_CARDS[variant ?? resolveVariant(product)];
|
|
71
|
-
const href =
|
|
71
|
+
const href = `/products/${encodeURIComponent(slug)}`;
|
|
72
72
|
|
|
73
73
|
return (
|
|
74
74
|
<Card
|
|
75
75
|
product={product}
|
|
76
76
|
renderLink={({ className, children }) => (
|
|
77
|
-
<Link href={href}
|
|
77
|
+
<Link href={href} className={className}>
|
|
78
78
|
{children}
|
|
79
79
|
</Link>
|
|
80
80
|
)}
|
|
@@ -1,47 +1,41 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
2
3
|
|
|
3
4
|
export function TradeInCta() {
|
|
5
|
+
const t = brand.tradeIn;
|
|
6
|
+
if (!t) return null;
|
|
4
7
|
return (
|
|
5
8
|
<section className="max-w-7xl mx-auto px-6 sm:px-8 py-14 sm:py-20">
|
|
6
9
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 items-center bg-foreground text-background rounded-3xl p-8 sm:p-12 lg:p-14 overflow-hidden relative">
|
|
7
10
|
<div className="absolute top-0 right-0 w-1/2 h-full opacity-[0.04] [background-image:linear-gradient(135deg,white_1px,transparent_1px)] [background-size:24px_24px] pointer-events-none" />
|
|
8
11
|
<div>
|
|
9
12
|
<p className="text-[11px] font-mono uppercase tracking-[0.16em] text-primary-foreground/70 mb-3">
|
|
10
|
-
|
|
13
|
+
{t.eyebrow}
|
|
11
14
|
</p>
|
|
12
15
|
<h2 className="text-[clamp(1.75rem,3.5vw,2.5rem)] font-bold m-0 mb-4 -tracking-[0.025em] leading-[1.1]">
|
|
13
|
-
|
|
16
|
+
{t.title}
|
|
14
17
|
</h2>
|
|
15
|
-
<p className="text-background/75 leading-relaxed mb-6">
|
|
16
|
-
Send us your iPhone, Galaxy, or MacBook. We'll quote within
|
|
17
|
-
48 hours and credit the value toward your next purchase. Devices
|
|
18
|
-
head to certified refurbishers across the continent — yours stays
|
|
19
|
-
in service for years more.
|
|
20
|
-
</p>
|
|
18
|
+
<p className="text-background/75 leading-relaxed mb-6">{t.body}</p>
|
|
21
19
|
<div className="flex flex-wrap items-center gap-3">
|
|
22
20
|
<Link
|
|
23
|
-
href=
|
|
21
|
+
href={t.primaryCtaHref}
|
|
24
22
|
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-md bg-primary text-primary-foreground font-semibold text-sm hover:bg-primary/90 transition-colors"
|
|
25
23
|
>
|
|
26
|
-
|
|
24
|
+
{t.primaryCtaLabel}
|
|
27
25
|
<svg viewBox="0 0 12 12" className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden>
|
|
28
26
|
<path d="M3 6h7m0 0L7 3m3 3L7 9" strokeLinecap="round" strokeLinejoin="round" />
|
|
29
27
|
</svg>
|
|
30
28
|
</Link>
|
|
31
29
|
<Link
|
|
32
|
-
href=
|
|
30
|
+
href={t.secondaryCtaHref}
|
|
33
31
|
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-md border border-background/25 hover:bg-background/10 transition-colors text-sm font-medium"
|
|
34
32
|
>
|
|
35
|
-
|
|
33
|
+
{t.secondaryCtaLabel}
|
|
36
34
|
</Link>
|
|
37
35
|
</div>
|
|
38
36
|
</div>
|
|
39
37
|
<div className="grid grid-cols-3 gap-3">
|
|
40
|
-
{
|
|
41
|
-
{ step: "01", title: "Tell us what you have", body: "Model + condition + photos. 2 minutes." },
|
|
42
|
-
{ step: "02", title: "Ship it free", body: "Drop at our store or book a free pickup." },
|
|
43
|
-
{ step: "03", title: "Get credited", body: "Within 48 hours, in store credit or Mobile Money." },
|
|
44
|
-
].map((s) => (
|
|
38
|
+
{t.steps.map((s) => (
|
|
45
39
|
<div
|
|
46
40
|
key={s.step}
|
|
47
41
|
className="rounded-2xl p-4 sm:p-5 bg-background/5 border border-background/10"
|
|
@@ -1,15 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { brand } from "@/lib/brand";
|
|
2
|
+
|
|
3
|
+
const ICONS: Record<string, React.ReactNode> = {
|
|
4
|
+
delivery: (
|
|
5
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
6
|
+
<path d="M3 7h12v8H3zM15 10h4l3 3v2h-7z" strokeLinejoin="round" />
|
|
7
|
+
<circle cx="7" cy="17" r="1.5" />
|
|
8
|
+
<circle cx="18" cy="17" r="1.5" />
|
|
9
|
+
</svg>
|
|
10
|
+
),
|
|
11
|
+
warranty: (
|
|
12
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
13
|
+
<path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z" strokeLinejoin="round" />
|
|
14
|
+
<path d="M9 12l2 2 4-4" strokeLinecap="round" strokeLinejoin="round" />
|
|
15
|
+
</svg>
|
|
16
|
+
),
|
|
17
|
+
payment: (
|
|
18
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
19
|
+
<rect x="3" y="6" width="18" height="12" rx="2" />
|
|
20
|
+
<line x1="3" y1="10" x2="21" y2="10" />
|
|
21
|
+
</svg>
|
|
22
|
+
),
|
|
23
|
+
verified: (
|
|
24
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
25
|
+
<circle cx="12" cy="12" r="9" />
|
|
26
|
+
<path d="M8 12l3 3 5-6" strokeLinecap="round" strokeLinejoin="round" />
|
|
27
|
+
</svg>
|
|
28
|
+
),
|
|
29
|
+
support: (
|
|
30
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
31
|
+
<path d="M18 18a8 8 0 1 0-12 0" />
|
|
32
|
+
<path d="M3 18h4v3H3zM17 18h4v3h-4z" strokeLinejoin="round" />
|
|
33
|
+
</svg>
|
|
34
|
+
),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const FALLBACK_ICON = (
|
|
38
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5" aria-hidden>
|
|
39
|
+
<circle cx="12" cy="12" r="9" />
|
|
40
|
+
</svg>
|
|
41
|
+
);
|
|
4
42
|
|
|
5
|
-
export function TrustBar(
|
|
43
|
+
export function TrustBar() {
|
|
44
|
+
const items = brand.trustItems;
|
|
45
|
+
if (!items || items.length === 0) return null;
|
|
6
46
|
return (
|
|
7
47
|
<section className="border-y border-border bg-card">
|
|
8
48
|
<div className="max-w-7xl mx-auto px-6 sm:px-8 py-10 grid grid-cols-2 md:grid-cols-4 gap-x-6 gap-y-8">
|
|
9
49
|
{items.map((it) => (
|
|
10
50
|
<div key={it.label} className="flex items-start gap-3">
|
|
11
51
|
<div className="grid place-items-center w-10 h-10 rounded-lg bg-primary/10 text-primary shrink-0">
|
|
12
|
-
{it.
|
|
52
|
+
{ICONS[it.iconKey] ?? FALLBACK_ICON}
|
|
13
53
|
</div>
|
|
14
54
|
<div className="min-w-0">
|
|
15
55
|
<p className="text-[10px] font-mono uppercase tracking-[0.16em] text-muted-foreground mb-0.5">
|