fix: align public customer-facing styles

This commit is contained in:
DMleadgen 2026-03-27 15:31:33 -06:00
parent 726c4877c6
commit e2124cfa66
Signed by: matt
GPG key ID: C2720CF8CD701894
12 changed files with 160 additions and 181 deletions

View file

@ -197,7 +197,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</p>
<div className="grid gap-6 md:grid-cols-2">
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6">
<h3 className="text-xl font-semibold mb-3">Vending Machine Sales</h3>
<p className="text-muted-foreground">
@ -207,7 +207,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</CardContent>
</Card>
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6">
<h3 className="text-xl font-semibold mb-3">Vending Machine Repair</h3>
<p className="text-muted-foreground">
@ -217,7 +217,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</CardContent>
</Card>
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6">
<h3 className="text-xl font-semibold mb-3">Healthy Snack and Beverage Options</h3>
<p className="text-muted-foreground">
@ -227,7 +227,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</CardContent>
</Card>
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6">
<h3 className="text-xl font-semibold mb-3">Maintenance Services</h3>
<p className="text-muted-foreground">
@ -304,7 +304,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</p>
<div className="grid gap-4 md:grid-cols-3 mb-8">
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6 flex items-start gap-4">
<Phone className="h-6 w-6 text-secondary flex-shrink-0 mt-1" />
<div>
@ -316,7 +316,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</CardContent>
</Card>
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6 flex items-start gap-4">
<Mail className="h-6 w-6 text-secondary flex-shrink-0 mt-1" />
<div>
@ -328,7 +328,7 @@ function renderLocationPage(locationData: any, locationSlug: string) {
</CardContent>
</Card>
<Card className="rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<Card className="rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:border-primary/35">
<CardContent className="p-6 flex items-start gap-4">
<Globe className="h-6 w-6 text-secondary flex-shrink-0 mt-1" />
<div>

View file

@ -9,10 +9,12 @@ import { ServiceAreasSection } from '@/components/service-areas-section';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { CheckCircle2, Wrench, Clock, Phone, Shield, MapPin } from 'lucide-react';
import { RepairsImageCarousel } from '@/components/repairs-image-carousel';
import { ContactForm } from '@/components/forms/contact-form';
import { PublicInset, PublicSurface } from '@/components/public-surface';
import Image from 'next/image';
import Script from 'next/script';
import Link from 'next/link';
import { ArrowRight } from 'lucide-react';
import { businessConfig } from '@/lib/seo-config';
import type { Metadata } from 'next';
const WORDPRESS_SLUG = 'vending-machine-repairs';
@ -392,32 +394,28 @@ export default async function RepairsPage() {
Request Service
</h3>
<p className="text-muted-foreground">
Fill out the form below to request vending machine repair or maintenance services
Use the native Rocky intake below for repairs, diagnostics, or virtual support.
</p>
</div>
<Card className="border-border/50">
<CardContent className="p-0">
<div className="w-full h-[600px] overflow-y-auto">
<iframe
src="https://link.sluice-box.io/widget/form/EJSeCs27dWUrveXwAHJE"
style={{ width: '100%', minHeight: '1613px', border: 'none', borderRadius: '4px' }}
id="inline-EJSeCs27dWUrveXwAHJE"
data-layout="{'id':'INLINE'}"
data-trigger-type="alwaysShow"
data-trigger-value=""
data-activation-type="alwaysActivated"
data-activation-value=""
data-deactivation-type="neverDeactivate"
data-deactivation-value=""
data-form-name="Repairs"
data-height="1613"
data-layout-iframe-id="inline-EJSeCs27dWUrveXwAHJE"
data-form-id="EJSeCs27dWUrveXwAHJE"
title="Repairs"
/>
<PublicSurface className="space-y-6 p-5 md:p-7">
<PublicInset className="flex flex-col gap-3 p-5 text-sm text-muted-foreground md:flex-row md:items-center md:justify-between">
<div>
<p className="font-semibold text-foreground">Before you submit</p>
<p className="mt-1 leading-relaxed">
Include the machine model, what it is doing, and whether you need on-site help or virtual support.
</p>
</div>
</CardContent>
</Card>
<div className="flex flex-col gap-2 text-left md:text-right">
<a href={businessConfig.publicCallUrl} className="font-medium text-foreground hover:text-primary">
Call {businessConfig.publicCallNumber}
</a>
<a href={businessConfig.publicSmsUrl} className="font-medium text-foreground hover:text-primary">
Text photos or videos
</a>
</div>
</PublicInset>
<ContactForm defaultIntent="Repairs" />
</PublicSurface>
</div>
</div>
</section>
@ -670,9 +668,6 @@ export default async function RepairsPage() {
{/* Service Areas Section */}
<ServiceAreasSection />
{/* Form Script */}
<Script src="https://link.sluice-box.io/js/form_embed.js" strategy="afterInteractive" />
</>
);
} catch (error) {

View file

@ -1,5 +1,6 @@
import { redirect } from "next/navigation";
import { isAdminUiEnabled } from "@/lib/server/admin-auth";
import { PublicPageHeader, PublicSurface } from "@/components/public-surface";
export default function SignInPage() {
if (!isAdminUiEnabled()) {
@ -7,13 +8,23 @@ export default function SignInPage() {
}
return (
<div className="flex min-h-screen items-center justify-center bg-muted/30 px-6">
<div className="max-w-md rounded-2xl border border-border bg-background p-8 text-center shadow-sm">
<h1 className="text-2xl font-semibold">Admin Sign-In</h1>
<p className="mt-3 text-sm text-muted-foreground">
Admin sign-in is not configured in this deployment. Enable the admin
UI and wire an auth provider before using this area.
</p>
<div className="px-4 py-8 md:py-12">
<div className="mx-auto flex min-h-[calc(100dvh-7rem)] max-w-3xl items-start justify-center md:items-center">
<div className="w-full max-w-xl space-y-8">
<PublicPageHeader
align="center"
eyebrow="Customer Flow"
title="Admin Sign-In"
description="This route keeps the same Rocky shell as the rest of the site. Auth still needs to be wired before this area becomes usable."
/>
<PublicSurface className="p-6 text-center md:p-8">
<h2 className="text-2xl font-semibold">Admin sign-in is not configured</h2>
<p className="mt-3 text-sm text-muted-foreground">
Enable the admin UI and connect an auth provider before using this area.
</p>
</PublicSurface>
</div>
</div>
</div>
);

View file

@ -7,6 +7,8 @@ import { Card, CardContent } from "@/components/ui/card";
import { ReviewsSection } from "@/components/reviews-section";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import { RequestMachineForm } from "@/components/forms/request-machine-form";
import { PublicInset, PublicPageHeader, PublicSurface } from "@/components/public-surface";
interface LocationPageProps {
params: Promise<{ location: string }>;
@ -168,28 +170,23 @@ export default async function LocationPage({ params }: LocationPageProps) {
<article className="container mx-auto px-4 py-8 md:py-12">
{/* Hero Section */}
<header className="mb-12 md:mb-16 text-center">
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-balance mb-4">
Vending Machine Supplier in {locationData.city}, {locationData.state}
</h1>
<p className="text-lg md:text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed text-pretty">
Need a vending machine supplier in {locationData.city}, {locationData.state}? Rocky Mountain Vending has
been helping local businesses and schools since 2019 with quality vending solutions. We bring healthy
snacks, cold drinks, and dependable service right to your doorno hassle, no fuss.
</p>
</header>
<PublicPageHeader
align="center"
className="mb-12 md:mb-16"
eyebrow="Local Service Area"
title={`Vending Machine Supplier in ${locationData.city}, ${locationData.state}`}
description={`Need a vending machine supplier in ${locationData.city}, ${locationData.state}? Rocky Mountain Vending has been helping local businesses and schools since 2019 with quality vending solutions. We bring healthy snacks, cold drinks, and dependable service right to your door—no hassle, no fuss.`}
/>
{/* Local Anecdote */}
<div className="mb-12 max-w-4xl mx-auto">
<Card className="border-secondary/20 bg-secondary/5">
<CardContent className="p-6 md:p-8">
<PublicSurface className="p-6 md:p-8">
<p className="text-base md:text-lg leading-relaxed">
A while back, we worked with a {locationData.anecdote.customer} near {locationData.anecdote.location}.
We set them up with a {locationData.anecdote.solution}. Now {locationData.anecdote.outcome}. That's
what we do bestmake vending simple.
</p>
</CardContent>
</Card>
</PublicSurface>
</div>
{/* Services Section */}
@ -350,33 +347,19 @@ export default async function LocationPage({ params }: LocationPageProps) {
</div>
{/* CRM Form */}
<Card className="border-secondary/20">
<CardContent className="p-8">
<PublicSurface className="p-6 md:p-8">
<div className="text-center mb-6">
<h3 className="text-2xl font-bold mb-2">Get Your Free Vending Machine</h3>
<p className="text-muted-foreground">
Fill out the form below and we'll contact you within 24 hours to discuss your needs.
Tell us about your location and we&apos;ll follow up within one business day to talk through the best machine mix.
</p>
</div>
<iframe
src="https://link.sluice-box.io/widget/form/T76mIdPvC5iBwAI2wFPg"
style={{ width: "100%", height: "650px", border: "none", borderRadius: "4px" }}
id="inline-T76mIdPvC5iBwAI2wFPg"
data-layout="{'id':'INLINE'}"
data-trigger-type="alwaysShow"
data-trigger-value=""
data-activation-type="alwaysActivated"
data-activation-value=""
data-deactivation-type="neverDeactivate"
data-deactivation-value=""
data-form-name="Request Machine Short"
data-height="638"
data-layout-iframe-id="inline-T76mIdPvC5iBwAI2wFPg"
data-form-id="T76mIdPvC5iBwAI2wFPg"
title="Request Free Vending Machine Form"
/>
</CardContent>
</Card>
<PublicInset className="mb-5 p-5 text-sm leading-relaxed text-muted-foreground">
Free placement is for qualifying business locations. Share your foot traffic, preferred machine types,
and any site constraints so our team can recommend the right setup.
</PublicInset>
<RequestMachineForm />
</PublicSurface>
</section>
{/* Payment Options */}

View file

@ -1,82 +1,65 @@
"use client"
import { Card, CardContent } from "@/components/ui/card"
import { Phone, MapPin } from "lucide-react"
import { ContactForm } from "@/components/forms/contact-form"
import { PublicInset, PublicPageHeader, PublicSurface } from "@/components/public-surface"
import { businessConfig } from "@/lib/seo-config"
export function ContactSection() {
return (
<section id="contact" className="py-20 md:py-28 bg-muted/30">
<div className="container mx-auto px-4">
<PublicPageHeader
className="mb-10 max-w-3xl"
eyebrow="Detailed Questions"
title="Need something more specific? We can sort that out here."
description="If you already handled the quick placement request, use this longer form for service details, sales questions, or anything that needs more context."
/>
<div className="grid gap-12 lg:grid-cols-2 items-start">
{/* Left Content */}
<div>
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">
Have Detailed Questions? Let's Talk!
</h2>
<p className="text-lg text-muted-foreground mb-8 text-pretty leading-relaxed">
Already submitted the quick form above? Great! We'll contact you soon. If you have specific requirements or detailed questions, feel free to share more below—we're here to help.
</p>
<PublicSurface className="space-y-6">
<div className="space-y-6">
<Card className="border-border/50 transition-colors">
<CardContent className="p-6">
<div className="flex items-start gap-4">
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-secondary/10 flex-shrink-0">
<Phone className="h-6 w-6 text-secondary" />
</div>
<div>
<div className="font-semibold mb-1">Call or Text Us</div>
<a
href="tel:+14352339668"
className="text-muted-foreground hover:text-foreground transition-colors"
>
(435) 233-9668
</a>
<p className="text-xs text-muted-foreground mt-1">Mon-Fri: 8:00 AM - 5:00 PM</p>
<a
href="sms:+14352339668"
className="text-xs hover:underline mt-2 block"
>
Or send a text message
</a>
</div>
</div>
</CardContent>
</Card>
<PublicInset className="flex items-start gap-4 p-5">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary flex-shrink-0">
<Phone className="h-6 w-6" />
</div>
<div>
<div className="font-semibold mb-1 text-foreground">Call or Text Us</div>
<a href={businessConfig.publicCallUrl} className="text-muted-foreground hover:text-foreground transition-colors">
{businessConfig.publicCallNumber}
</a>
<p className="text-xs text-muted-foreground mt-1">Mon-Fri: 8:00 AM - 5:00 PM</p>
<a href={businessConfig.publicSmsUrl} className="text-xs hover:underline mt-2 block">
Or send a text message
</a>
</div>
</PublicInset>
<Card className="border-border/50 transition-colors">
<CardContent className="p-6">
<div className="flex items-start gap-4">
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-secondary/10 flex-shrink-0">
<MapPin className="h-6 w-6 text-secondary" />
</div>
<div>
<div className="font-semibold mb-1">Service Areas</div>
<p className="text-muted-foreground">Davis, Salt Lake & Utah Counties</p>
<p className="text-xs text-muted-foreground mt-1">Serving 20+ cities across Utah</p>
</div>
</div>
</CardContent>
</Card>
<PublicInset className="flex items-start gap-4 p-5">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary flex-shrink-0">
<MapPin className="h-6 w-6" />
</div>
<div>
<div className="font-semibold mb-1 text-foreground">Service Areas</div>
<p className="text-muted-foreground">Davis, Salt Lake & Utah Counties</p>
<p className="text-xs text-muted-foreground mt-1">Serving 20+ cities across Utah</p>
</div>
</PublicInset>
</div>
</div>
</PublicSurface>
{/* Right Form - Long Form */}
<Card className="border-border/50">
<CardContent className="pt-6">
<div className="mb-4">
<h3 className="text-xl font-semibold mb-2">Contact Form</h3>
<p className="text-sm text-muted-foreground">
Tell us more about your needs and we'll get back to you within 24 hours.
</p>
</div>
<div className="min-h-[738px]">
<ContactForm onSubmit={(data) => console.log('Contact form submitted:', data)} />
</div>
</CardContent>
</Card>
<PublicSurface className="p-5 md:p-7">
<div className="mb-4">
<h3 className="text-xl font-semibold mb-2">Contact Form</h3>
<p className="text-sm text-muted-foreground">
Tell us more about your needs and we'll get back to you within 24 hours.
</p>
</div>
<div className="min-h-[738px]">
<ContactForm onSubmit={(data) => console.log('Contact form submitted:', data)} />
</div>
</PublicSurface>
</div>
</div>
</section>

View file

@ -35,9 +35,10 @@ interface ContactFormData {
interface ContactFormProps {
onSubmit?: (data: ContactFormData) => void
className?: string
defaultIntent?: string
}
export function ContactForm({ onSubmit, className }: ContactFormProps) {
export function ContactForm({ onSubmit, className, defaultIntent = "" }: ContactFormProps) {
const [isSubmitting, setIsSubmitting] = useState(false)
const [isSubmitted, setIsSubmitted] = useState(false)
const [submitError, setSubmitError] = useState<string | null>(null)
@ -58,7 +59,7 @@ export function ContactForm({ onSubmit, className }: ContactFormProps) {
defaultValues: {
source: "website",
page: "",
intent: "",
intent: defaultIntent,
serviceTextConsent: false,
marketingTextConsent: false,
consentVersion: SMS_CONSENT_VERSION,
@ -76,13 +77,16 @@ export function ContactForm({ onSubmit, className }: ContactFormProps) {
setValue("page", pathname)
setValue("consentSourcePage", pathname)
setValue("consentVersion", SMS_CONSENT_VERSION)
if (defaultIntent) {
setValue("intent", defaultIntent)
}
}
}, [setValue])
}, [defaultIntent, setValue])
const buildResetValues = () => ({
source: "website",
page: typeof window !== "undefined" ? window.location.pathname : "",
intent: "",
intent: defaultIntent,
serviceTextConsent: false,
marketingTextConsent: false,
consentVersion: SMS_CONSENT_VERSION,

View file

@ -206,9 +206,9 @@ function ManualCard({
const thumbnailUrl = getThumbnailUrl(manual)
return (
<Card className="overflow-hidden rounded-[1.75rem] border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.9))] shadow-[0_18px_45px_rgba(0,0,0,0.08)] transition-all hover:-translate-y-0.5 hover:shadow-[0_24px_60px_rgba(0,0,0,0.12)]">
<Card className="overflow-hidden rounded-[1.75rem] border border-border/70 bg-background shadow-[0_18px_45px_rgba(15,23,42,0.08)] transition-all hover:-translate-y-0.5 hover:shadow-[0_24px_60px_rgba(15,23,42,0.12)]">
{thumbnailUrl && (
<div className="relative h-48 min-h-[192px] w-full overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(196,154,52,0.16),transparent_55%),linear-gradient(180deg,rgba(247,244,236,0.72),rgba(255,255,255,0.96))]">
<div className="relative h-48 min-h-[192px] w-full overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(196,154,52,0.12),transparent_52%),linear-gradient(180deg,rgba(255,255,255,0.98),rgba(255,255,255,0.98))]">
<Image
src={thumbnailUrl}
alt={manual.filename.replace(/\.pdf$/i, '')}

View file

@ -18,6 +18,7 @@ import {
MapPin,
Calendar
} from 'lucide-react'
import { PublicPageHeader, PublicSurface } from '@/components/public-surface'
interface Order {
id: string
@ -209,17 +210,17 @@ export function OrderTracking() {
}, [order])
return (
<div className="max-w-4xl mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto px-4 py-10 md:py-14">
<div className="space-y-6">
<div className="text-center">
<h1 className="text-3xl font-bold tracking-tight">Track Your Order</h1>
<p className="text-muted-foreground mt-2">
Enter your order ID to track shipment status and delivery information
</p>
</div>
<PublicPageHeader
align="center"
eyebrow="Customer Orders"
title="Track Your Order"
description="Enter your order ID to check shipment status, delivery updates, and the current stage of your order."
/>
{/* Search Form */}
<Card>
<PublicSurface as="section" className="p-5 md:p-7">
<CardHeader>
<CardTitle>Find Your Order</CardTitle>
<CardDescription>
@ -258,10 +259,10 @@ export function OrderTracking() {
<AlertDescription>
Order found successfully! Scroll down for tracking details.
</AlertDescription>
</Alert>
)}
</CardContent>
</Card>
</Alert>
)}
</CardContent>
</PublicSurface>
{/* Order Details */}
{order && (

View file

@ -54,7 +54,7 @@ export function PublicSurface({
return (
<Component
className={cn(
"rounded-[2rem] border border-border/70 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(247,244,236,0.92))] p-5 shadow-[0_24px_60px_rgba(0,0,0,0.08)] md:p-7",
"rounded-[2rem] border border-border/70 bg-background p-5 shadow-[0_24px_60px_rgba(15,23,42,0.08)] md:p-7",
className,
)}
{...props}
@ -72,7 +72,7 @@ export function PublicInset({
return (
<div
className={cn(
"rounded-[1.5rem] border border-border/60 bg-background/85 p-4 shadow-sm",
"rounded-[1.5rem] border border-border/60 bg-background p-4 shadow-sm",
className,
)}
{...props}

View file

@ -4,6 +4,7 @@ import { useEffect } from "react"
import { Star } from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { ReviewSchema } from "@/components/review-schema"
import { PublicPageHeader, PublicSurface } from "@/components/public-surface"
export function ReviewsSection() {
useEffect(() => {
@ -31,28 +32,29 @@ export function ReviewsSection() {
<ReviewSchema aggregateRating={aggregateRating} />
<section className="py-16 md:py-24 bg-card/30">
<div className="container mx-auto px-4">
<div className="text-center mb-12">
<div className="inline-flex items-center justify-center gap-2 mb-4">
<Star className="h-6 w-6 text-secondary fill-secondary" />
<h2 className="text-3xl md:text-4xl font-bold tracking-tight text-balance">What Our Customers Say</h2>
<PublicPageHeader
align="center"
eyebrow="Google Reviews"
title="What Our Customers Say"
description="See what Utah businesses have to say about Rocky Mountain Vending, all in the same clean review shell used across the rest of the site."
>
<div className="mt-4 flex justify-center">
<Badge variant="secondary" className="rounded-full px-4 py-1.5 text-sm">
<Star className="mr-2 h-4 w-4 fill-current text-primary" />
{aggregateRating.ratingValue} / {aggregateRating.bestRating} ({aggregateRating.reviewCount}+ Reviews)
</Badge>
</div>
<Badge variant="secondary" className="mb-4">
{aggregateRating.ratingValue} / {aggregateRating.bestRating} ({aggregateRating.reviewCount}+ Reviews)
</Badge>
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">
Don't just take our word for itsee what Utah businesses have to say about our service
</p>
</div>
</PublicPageHeader>
<div className="max-w-5xl mx-auto">
<PublicSurface className="mx-auto mt-10 max-w-5xl overflow-hidden p-5 md:p-7">
<iframe
className="lc_reviews_widget w-full min-w-full min-h-[400px]"
className="lc_reviews_widget min-h-[400px] w-full rounded-[1.5rem] border border-border/60 bg-background"
src="https://reputationhub.site/reputation/widgets/review_widget/YAoWLgNSid8oG44j9BjG"
frameBorder="0"
scrolling="no"
title="Customer Reviews"
/>
</div>
</PublicSurface>
</div>
</section>
</>

View file

@ -7,7 +7,7 @@ function Card({ className, ...props }: React.ComponentProps<'div'>) {
<div
data-slot="card"
className={cn(
'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm',
'bg-card text-card-foreground flex flex-col gap-6 rounded-[1.75rem] border border-border/70 py-6 shadow-[0_18px_45px_rgba(15,23,42,0.08)]',
className,
)}
{...props}

View file

@ -41,17 +41,17 @@ export function VendingMachinesPage() {
</div>
</PublicSurface>
<PublicSurface className="bg-[linear-gradient(145deg,rgba(78,137,66,0.98),rgba(31,74,32,0.98))] text-white">
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-white/75">Get Started</p>
<PublicSurface>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary/80">Get Started</p>
<h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">Ready to talk through the right machine setup?</h2>
<p className="mt-3 text-base leading-relaxed text-white/82">
<p className="mt-3 text-base leading-relaxed text-muted-foreground">
We can help with free placement, sales questions, feature comparisons, and planning the best layout for your location.
</p>
<div className="mt-6 flex flex-col gap-3 sm:flex-row">
<Button asChild size="lg" className="h-11 rounded-full bg-white px-6 text-primary hover:bg-white/92">
<Button asChild size="lg" className="h-11 rounded-full px-6">
<Link href="/contact-us#contact-form">Contact Us</Link>
</Button>
<Button asChild size="lg" variant="outline" className="h-11 rounded-full border-white/50 bg-transparent px-6 text-white hover:bg-white/10">
<Button asChild size="lg" variant="outline" className="h-11 rounded-full px-6">
<Link href="/#request-machine">Get Free Machine</Link>
</Button>
</div>