From c73da417afe45e8bfc0c5fa372a53620e65ae398 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 2 Jun 2026 04:28:03 +0000 Subject: [PATCH] fix: Apple HIG mobile responsiveness - hero typography, tables, SEO metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile: - HeroSection: scale typography 7xl → 4xl sm:5xl md:6xl lg:7xl, responsive px/py - StorefrontFooter: newsletter input responsive w-full sm:w-52, larger touch targets - AdminTable: add overflow-x-auto + min-w-[600px] for horizontal scroll - AdminOrdersPanel: same table overflow fix - AdminFilterTabs: increase text sizes sm:text-xs, add padding - Tuxedo page: SectionHeader mobile-first sizing, feature grid grid-cols-1 sm:2 - Tuxedo feature labels: show on all screens (remove hidden sm:block) SEO: - Root layout: add viewport export, full OG/Twitter metadata, metadataBase - Tuxedo layout: complete OG + Twitter card + canonical + keywords + robots - Indian River layout: same complete SEO treatment All TypeScript checks pass. --- src/app/indian-river-direct/layout.tsx | 38 ++++++++++++++++- src/app/layout.tsx | 41 ++++++++++++++++-- src/app/tuxedo/layout.tsx | 39 +++++++++++++++-- src/app/tuxedo/page.tsx | 18 ++++---- src/components/admin/AdminOrdersPanel.tsx | 4 +- .../admin/design-system/AdminFilterTabs.tsx | 4 +- .../admin/design-system/AdminTable.tsx | 6 +-- src/components/storefront/HeroSection.tsx | 42 +++++++++---------- .../storefront/StorefrontFooter.tsx | 5 ++- 9 files changed, 150 insertions(+), 47 deletions(-) diff --git a/src/app/indian-river-direct/layout.tsx b/src/app/indian-river-direct/layout.tsx index f3798f4..c588c81 100644 --- a/src/app/indian-river-direct/layout.tsx +++ b/src/app/indian-river-direct/layout.tsx @@ -1,8 +1,44 @@ import type { Metadata } from "next"; +const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://routecommerce.com"; + export const metadata: Metadata = { - title: "Indian River Direct | Peach & Citrus Truckload", + title: { + default: "Indian River Direct | Peach & Citrus Truckload", + template: "%s | Indian River Direct", + }, description: "Fresh peaches and citrus from our Florida groves to truckload sales in your neighborhood. Family-owned since 1985. Pre-order now for 2026 season.", + keywords: ["peaches", "citrus", "Florida produce", "truckload sales", "fresh fruit", "Indian River", "wholesale peaches"], + openGraph: { + title: "Indian River Direct | Fresh Peaches & Citrus", + description: "Fresh peaches and citrus from our Florida groves to truckload sales in your neighborhood. Family-owned since 1985.", + url: `${BASE_URL}/indian-river-direct`, + siteName: "Indian River Direct", + locale: "en_US", + type: "website", + images: [ + { + url: "/og-indian-river.jpg", + width: 1200, + height: 630, + alt: "Indian River Direct - Fresh Peaches & Citrus", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: "Indian River Direct | Peach & Citrus Truckload", + description: "Fresh peaches and citrus from our Florida groves. Family-owned since 1985. Pre-order for 2026 season.", + site: "@IndianRiverDirect", + images: ["/og-indian-river.jpg"], + }, + alternates: { + canonical: `${BASE_URL}/indian-river-direct`, + }, + robots: { + index: true, + follow: true, + }, }; export default function IndianRiverLayout({ children }: { children: React.ReactNode }) { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 95cee96..4de5083 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,10 +1,45 @@ -import type { Metadata } from "next"; +import type { Metadata, Viewport } from "next"; import "./globals.css"; import { Providers } from "@/components/Providers"; +const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://routecommerce.com"; + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + themeColor: "#0a0a0a", +}; + export const metadata: Metadata = { - title: "Route Commerce", - description: "B2B produce wholesale platform", + title: { + default: "Route Commerce | Fresh Produce Wholesale Platform", + template: "%s | Route Commerce", + }, + description: "Multi-tenant B2B e-commerce platform for fresh produce wholesale distribution. Brands sell to customers who pick up at scheduled stops or receive shipments.", + keywords: ["wholesale produce", "farm fresh", "B2B e-commerce", "produce distribution", "pickup stops", "fresh produce"], + metadataBase: new URL(BASE_URL), + openGraph: { + title: "Route Commerce | Fresh Produce Wholesale Platform", + description: "Multi-tenant B2B e-commerce platform for fresh produce wholesale distribution.", + url: BASE_URL, + siteName: "Route Commerce", + locale: "en_US", + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "Route Commerce | Fresh Produce Wholesale Platform", + description: "Multi-tenant B2B e-commerce platform for fresh produce wholesale distribution.", + site: "@RouteCommerce", + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + }, + }, }; export default function RootLayout({ diff --git a/src/app/tuxedo/layout.tsx b/src/app/tuxedo/layout.tsx index 3dbb893..454f418 100644 --- a/src/app/tuxedo/layout.tsx +++ b/src/app/tuxedo/layout.tsx @@ -1,12 +1,43 @@ import type { Metadata } from "next"; +const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://routecommerce.com"; + export const metadata: Metadata = { - title: "Tuxedo Corn | Fresh Produce Wholesale", + title: { + default: "Tuxedo Corn | Fresh Produce Wholesale", + template: "%s | Tuxedo Corn", + }, description: "Premium sweet corn and seasonal produce delivered fresh from the farm to pickup stops near you. Shop wholesale pricing on Tuxedo Corn.", + keywords: ["sweet corn", "Olathe Sweet", "Colorado produce", "wholesale corn", "farm fresh", "pickup stops", "wholesale produce"], openGraph: { - title: "Tuxedo Corn", - description: "Premium sweet corn and seasonal produce, delivered fresh from our farm to your community.", - siteName: "Route Commerce", + title: "Tuxedo Corn | Olathe Sweet Sweet Corn", + description: "Premium sweet corn and seasonal produce, delivered fresh from our Colorado farm to pickup stops near you.", + url: `${BASE_URL}/tuxedo`, + siteName: "Tuxedo Corn", + locale: "en_US", + type: "website", + images: [ + { + url: "/og-tuxedo.jpg", + width: 1200, + height: 630, + alt: "Tuxedo Corn - Olathe Sweet Sweet Corn", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: "Tuxedo Corn | Fresh Produce Wholesale", + description: "Premium sweet corn and seasonal produce delivered fresh from our Colorado farm to pickup stops near you.", + site: "@TuxedoCorn", + images: ["/og-tuxedo.jpg"], + }, + alternates: { + canonical: `${BASE_URL}/tuxedo`, + }, + robots: { + index: true, + follow: true, }, }; diff --git a/src/app/tuxedo/page.tsx b/src/app/tuxedo/page.tsx index add70e8..4849542 100644 --- a/src/app/tuxedo/page.tsx +++ b/src/app/tuxedo/page.tsx @@ -266,7 +266,7 @@ function FeatureCard({ feature, index }: { feature: Feature; index: number }) { {/* Label */} -

- Why Choose
Tuxedo Corn + Why Choose
Tuxedo Corn {/* Asymmetric masonry grid with staggered offsets */} -

+
{/* Row 1: tall, normal, tall, normal — with vertical offset stagger */}
@@ -397,15 +397,15 @@ function SectionHeader({ accent?: "emerald" | "stone"; }) { return ( -
-

+

+

{eyebrow}

-

+

{headline}

-
-

+

+

{subtext}

diff --git a/src/components/admin/AdminOrdersPanel.tsx b/src/components/admin/AdminOrdersPanel.tsx index 07fec12..e598c3d 100644 --- a/src/components/admin/AdminOrdersPanel.tsx +++ b/src/components/admin/AdminOrdersPanel.tsx @@ -306,8 +306,8 @@ export default function AdminOrdersPanel({

Try adjusting your filters

) : ( -
- +
+
diff --git a/src/components/admin/design-system/AdminFilterTabs.tsx b/src/components/admin/design-system/AdminFilterTabs.tsx index 5854df0..7b54b0b 100644 --- a/src/components/admin/design-system/AdminFilterTabs.tsx +++ b/src/components/admin/design-system/AdminFilterTabs.tsx @@ -31,11 +31,11 @@ type AdminFilterTabsProps = { const sizeClasses = { sm: { container: "p-0.5 gap-0.5", - tab: "px-2.5 py-1.5 text-[10px]", + tab: "px-2.5 sm:px-3 py-2 sm:py-1.5 text-xs sm:text-[10px]", }, md: { container: "p-1 gap-0.5", - tab: "px-3 py-1.5 text-xs", + tab: "px-3 sm:px-4 py-2.5 sm:py-1.5 text-sm sm:text-xs", }, }; diff --git a/src/components/admin/design-system/AdminTable.tsx b/src/components/admin/design-system/AdminTable.tsx index cea0eb2..7680daa 100644 --- a/src/components/admin/design-system/AdminTable.tsx +++ b/src/components/admin/design-system/AdminTable.tsx @@ -27,12 +27,12 @@ export default function AdminTable>({ className = "", }: AdminTableProps) { return ( -
-
Order
+
+
{columns.map((col) => ( - ))} diff --git a/src/components/storefront/HeroSection.tsx b/src/components/storefront/HeroSection.tsx index 2714dd1..a8992d7 100644 --- a/src/components/storefront/HeroSection.tsx +++ b/src/components/storefront/HeroSection.tsx @@ -47,25 +47,25 @@ export default function HeroSection({ : "linear-gradient(135deg, rgba(0,0,0,0.20) 0%, transparent 45%), linear-gradient(to top, rgba(0,0,0,0.70) 0%, rgba(0,0,0,0.15) 55%, transparent 100%)" }} /> -
+
{eyebrow && ( -

+

{eyebrow}

)} -

+

{title}

-

+

{description}

{(primaryButton || secondaryButton) && ( -
+
{primaryButton && ( @@ -73,7 +73,7 @@ export default function HeroSection({ {secondaryButton && ( @@ -100,25 +100,25 @@ export default function HeroSection({ background: "linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,0.6) 72%, rgba(0,0,0,0.88) 100%)" }} /> -
+
{eyebrow && ( -

+

{eyebrow}

)} -

+

{title}

-

+

{description}

{(primaryButton || secondaryButton) && ( -
+
{primaryButton && ( @@ -126,7 +126,7 @@ export default function HeroSection({ {secondaryButton && ( @@ -139,26 +139,26 @@ export default function HeroSection({ } return ( -
+
{eyebrow && ( -

+

{eyebrow}

)} -

+

{title}

-

+

{description}

{(primaryButton || secondaryButton) && ( -
+
{primaryButton && ( @@ -166,7 +166,7 @@ export default function HeroSection({ {secondaryButton && ( diff --git a/src/components/storefront/StorefrontFooter.tsx b/src/components/storefront/StorefrontFooter.tsx index d0c4af4..a85a2d6 100644 --- a/src/components/storefront/StorefrontFooter.tsx +++ b/src/components/storefront/StorefrontFooter.tsx @@ -57,11 +57,12 @@ export default function StorefrontFooter({
+ {col.header}