Update default styles and components

This commit is contained in:
Rami Bitar
2026-05-10 15:49:28 -04:00
parent 383a593c42
commit 0a1fbd62bb
13 changed files with 144 additions and 118 deletions

View File

@@ -98,10 +98,10 @@ const CartDrawer: React.FC = () => {
return (
<div
key={item.id}
className="flex items-start space-x-4 pb-6 border-b border-gray-200 last:border-b-0"
className="flex items-start space-x-4 pb-6 border-b border-border last:border-b-0"
>
{/* Product Image */}
<div className="w-20 h-20 bg-gray-100 rounded-lg overflow-hidden flex-shrink-0">
<div className="w-20 h-20 bg-muted rounded-lg overflow-hidden flex-shrink-0">
{image ? (
<img
src={image}
@@ -109,7 +109,7 @@ const CartDrawer: React.FC = () => {
className="w-full h-full object-cover"
/>
) : (
<div className="w-full h-full flex items-center justify-center text-gray-400">
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
<ImageIcon size={24} />
</div>
)}
@@ -117,13 +117,13 @@ const CartDrawer: React.FC = () => {
{/* Product Details */}
<div className="flex-1 min-w-0">
<h4 className="font-semibold text-gray-900 mb-1 line-clamp-2">
<h4 className="font-semibold text-foreground mb-1 line-clamp-2">
{item.merchandise.product.title}
</h4>
{/* Variant Info */}
{selectedOptions.length > 0 && (
<div className="text-sm text-gray-500 mb-2">
<div className="text-sm text-muted-foreground mb-2">
{selectedOptions.map((option, index) => (
<span key={option.name}>
{option.value}
@@ -137,7 +137,7 @@ const CartDrawer: React.FC = () => {
{/* Quantity Controls */}
<div className="flex items-center mt-3">
<div className="flex items-center border border-gray-300 rounded-lg">
<div className="flex items-center border border-border rounded-lg">
<Button
onClick={() =>
updateItemQuantity(item.id, item.quantity - 1)
@@ -169,7 +169,7 @@ const CartDrawer: React.FC = () => {
{/* Price */}
<div className="flex-shrink-0">
<span className="text-sm font-semibold text-gray-900">
<span className="text-sm font-semibold text-foreground">
${parseFloat(item.merchandise.price.amount).toFixed(2)}
</span>
</div>
@@ -181,7 +181,7 @@ const CartDrawer: React.FC = () => {
variant="ghost"
size="icon-sm"
disabled={loading}
className="text-gray-400 hover:text-gray-700"
className="text-muted-foreground hover:text-foreground"
>
<X size={18} />
</Button>
@@ -204,7 +204,7 @@ const CartDrawer: React.FC = () => {
</span>
</div>
<div className="text-sm text-gray-500 mb-4">
<div className="text-sm text-muted-foreground mb-4">
Shipping and taxes calculated at checkout
</div>

View File

@@ -24,7 +24,7 @@ const CollectionCard: React.FC<CollectionCardProps> = ({ collection }) => {
<Link to={`/collections/${collection.handle}`} className="block group">
<Card className="hover:shadow-xl transition-shadow duration-300 overflow-hidden py-0 gap-0">
{/* Collection Image */}
<div className="aspect-video overflow-hidden bg-gray-100">
<div className="aspect-video overflow-hidden bg-muted">
{collection.image ? (
<img
src={collection.image.url}
@@ -32,7 +32,7 @@ const CollectionCard: React.FC<CollectionCardProps> = ({ collection }) => {
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
/>
) : (
<div className="w-full h-full flex items-center justify-center text-gray-400">
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
<i className="ri-folder-line text-6xl"></i>
</div>
)}
@@ -40,18 +40,18 @@ const CollectionCard: React.FC<CollectionCardProps> = ({ collection }) => {
{/* Collection Info */}
<CardContent className="p-6">
<h3 className="text-2xl font-bold text-gray-900 mb-3 group-hover:text-gray-600 transition-colors font-heading">
<h3 className="text-2xl font-bold text-foreground mb-3 group-hover:text-muted-foreground transition-colors font-heading">
{collection.title}
</h3>
{collection.description && (
<p className="text-gray-600">
<p className="text-muted-foreground">
{collection.description.substring(0, 100)}
{collection.description.length > 100 ? '...' : ''}
</p>
)}
<div className="mt-4 text-black font-semibold group-hover:text-gray-600 transition-colors flex items-center">
<div className="mt-4 text-foreground font-semibold group-hover:text-muted-foreground transition-colors flex items-center">
<span>View Collection</span>
<i className="ri-arrow-right-s-line ml-2"></i>
</div>

View File

@@ -64,18 +64,18 @@ const CollectionDetail: React.FC<{ handle?: string }> = ({ handle: handleProp })
return (
<div className="pt-4 pb-16">
<div className="container mx-auto px-4">
<h2 className="text-5xl font-bold text-center mb-16 text-gray-900 font-heading">
<h2 className="text-5xl font-bold text-center mb-16 text-foreground font-heading">
{title}
</h2>
{products.length === 0 ? (
<div className="text-center py-12">
<div className="bg-gray-50 border border-gray-200 rounded-lg p-8 max-w-md mx-auto">
<i className="ri-shopping-bag-line text-4xl text-gray-400 mb-4"></i>
<h3 className="text-lg font-semibold text-gray-600 mb-2">
<div className="bg-muted border border-border rounded-lg p-8 max-w-md mx-auto">
<i className="ri-shopping-bag-line text-4xl text-muted-foreground mb-4"></i>
<h3 className="text-lg font-semibold text-foreground mb-2">
No Products in Collection
</h3>
<p className="text-gray-500">
<p className="text-muted-foreground">
This collection doesn&apos;t have any products yet.
</p>
</div>

View File

@@ -11,19 +11,19 @@ const Collections: React.FC = () => {
return (
<div className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-5xl font-bold text-center mb-16 text-gray-900 font-heading">
<h2 className="text-5xl font-bold text-center mb-16 text-foreground font-heading">
Our Collections
</h2>
{/* Loading Skeleton */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{Array.from({ length: 6 }).map((_, index) => (
<div key={index} className="bg-white rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-video bg-gray-200"></div>
<div key={index} className="bg-card rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-video bg-muted"></div>
<div className="p-6">
<div className="h-8 bg-gray-200 rounded mb-4"></div>
<div className="h-4 bg-gray-200 rounded mb-2"></div>
<div className="h-4 bg-gray-200 rounded w-3/4"></div>
<div className="h-8 bg-muted rounded mb-4"></div>
<div className="h-4 bg-muted rounded mb-2"></div>
<div className="h-4 bg-muted rounded w-3/4"></div>
</div>
</div>
))}
@@ -62,12 +62,12 @@ const Collections: React.FC = () => {
Our Collections
</h2>
<div className="bg-gray-50 border border-gray-200 rounded-lg p-8 max-w-md mx-auto">
<i className="ri-folder-line text-4xl text-gray-400 mb-4"></i>
<h3 className="text-lg font-semibold text-gray-600 mb-2">
<div className="bg-muted border border-border rounded-lg p-8 max-w-md mx-auto">
<i className="ri-folder-line text-4xl text-muted-foreground mb-4"></i>
<h3 className="text-lg font-semibold text-foreground mb-2">
No Collections Found
</h3>
<p className="text-gray-500">
<p className="text-muted-foreground">
Check back later or configure your Shopify store connection.
</p>
</div>
@@ -79,7 +79,7 @@ const Collections: React.FC = () => {
return (
<div className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-5xl font-bold text-center mb-16 text-gray-900 font-heading">
<h2 className="text-5xl font-bold text-center mb-16 text-foreground font-heading">
Our Collections
</h2>

View File

@@ -158,7 +158,7 @@ const ProductDetail: React.FC<ProductDetailProps> = ({ handle: handleProp }) =>
}
return (
<div className="min-h-screen bg-white">
<div className="min-h-screen bg-background">
<div className="container mx-auto px-4 py-8">
<Breadcrumb className="mb-6">
<BreadcrumbList>

View File

@@ -23,7 +23,7 @@ const ProductDetailGallery: React.FC<ProductDetailGalleryProps> = ({
return (
<div>
{/* Main Image */}
<div className="aspect-square bg-gray-100 rounded-lg overflow-hidden mb-4">
<div className="aspect-square bg-muted rounded-lg overflow-hidden mb-4">
{images.length > 0 ? (
<img
src={images[selectedImage].url}
@@ -31,7 +31,7 @@ const ProductDetailGallery: React.FC<ProductDetailGalleryProps> = ({
className="w-full h-full object-cover"
/>
) : (
<div className="w-full h-full flex items-center justify-center text-gray-400">
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
<i className="ri-image-line text-6xl"></i>
</div>
)}
@@ -46,8 +46,8 @@ const ProductDetailGallery: React.FC<ProductDetailGalleryProps> = ({
onClick={() => setSelectedImage(index)}
className={`aspect-square rounded-lg overflow-hidden border-2 transition-colors ${
selectedImage === index
? 'border-black'
: 'border-gray-200 hover:border-gray-300'
? 'border-foreground'
: 'border-border hover:border-muted-foreground'
}`}
>
<img

View File

@@ -38,18 +38,18 @@ const ProductDetailInfo: React.FC<ProductDetailInfoProps> = ({
return (
<div>
<h1 className="text-4xl font-bold text-gray-900 mb-4 font-heading">
<h1 className="text-4xl font-bold text-foreground mb-4 font-heading">
{product.title}
</h1>
{/* Price */}
<div className="flex items-center space-x-4 mb-6">
<span className="text-2xl font-bold text-gray-900">
<span className="text-2xl font-bold text-foreground">
{formatPrice(price)}
</span>
{hasDiscount && compareAtPrice && (
<>
<span className="text-xl text-gray-500 line-through">
<span className="text-xl text-muted-foreground line-through">
{formatPrice(compareAtPrice)}
</span>
<Badge variant="destructive">
@@ -61,7 +61,7 @@ const ProductDetailInfo: React.FC<ProductDetailInfoProps> = ({
{/* Description */}
{product.description && (
<div className="text-gray-600 mb-8 text-lg leading-relaxed">
<div className="text-muted-foreground mb-8 text-lg leading-relaxed">
{product.descriptionHtml ? (
<div dangerouslySetInnerHTML={{ __html: product.descriptionHtml }} />
) : (
@@ -73,7 +73,7 @@ const ProductDetailInfo: React.FC<ProductDetailInfoProps> = ({
{/* Product Options */}
{product.options.map(option => (
<div key={option.id} className="mb-6">
<label className="block text-sm font-semibold text-gray-700 mb-2">
<label className="block text-sm font-semibold text-foreground mb-2">
{option.name}
</label>
<div className="flex flex-wrap gap-2">
@@ -92,10 +92,10 @@ const ProductDetailInfo: React.FC<ProductDetailInfoProps> = ({
{/* Quantity Selector */}
<div className="mb-8">
<label className="block text-sm font-semibold text-gray-700 mb-2">
<label className="block text-sm font-semibold text-foreground mb-2">
Quantity
</label>
<div className="flex items-center border border-gray-300 rounded-lg w-fit">
<div className="flex items-center border border-border rounded-lg w-fit">
<Button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
variant="ghost"
@@ -135,8 +135,8 @@ const ProductDetailInfo: React.FC<ProductDetailInfoProps> = ({
</Button>
{/* Additional Info */}
<div className="mt-8 pt-8 border-t border-gray-200">
<div className="space-y-3 text-sm text-gray-600">
<div className="mt-8 pt-8 border-t border-border">
<div className="space-y-3 text-sm text-muted-foreground">
<div className="flex items-center space-x-2">
<i className="ri-truck-line"></i>
<span>Free shipping on orders over $100</span>

View File

@@ -17,29 +17,29 @@ const ProductRecommendations: React.FC<ProductRecommendationsProps> = ({ product
}
return (
<div className="bg-gray-50 py-16">
<div className="bg-muted py-16">
<div className="container mx-auto px-4">
<h2 className="text-4xl font-bold text-center mb-12 text-gray-900 font-heading">
<h2 className="text-4xl font-bold text-center mb-12 text-foreground font-heading">
You Might Also Like
</h2>
{loading ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
{Array.from({ length: 4 }).map((_, index) => (
<div key={index} className="bg-white rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-square bg-gray-200"></div>
<div key={index} className="bg-card rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-square bg-muted"></div>
<div className="p-6">
<div className="h-6 bg-gray-200 rounded mb-2"></div>
<div className="h-4 bg-gray-200 rounded mb-4"></div>
<div className="h-8 bg-gray-200 rounded mb-4"></div>
<div className="h-12 bg-gray-200 rounded"></div>
<div className="h-6 bg-muted rounded mb-2"></div>
<div className="h-4 bg-muted rounded mb-4"></div>
<div className="h-8 bg-muted rounded mb-4"></div>
<div className="h-12 bg-muted rounded"></div>
</div>
</div>
))}
</div>
) : error ? (
<div className="text-center py-8">
<p className="text-gray-500">Recommendations could not be loaded</p>
<p className="text-muted-foreground">Recommendations could not be loaded</p>
</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">

View File

@@ -127,13 +127,13 @@ const Products: React.FC<ProductsProps> = ({
{/* Loading Skeleton */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
{Array.from({ length: 8 }).map((_, index) => (
<div key={index} className="bg-white rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-square bg-gray-200"></div>
<div key={index} className="bg-card rounded-lg shadow-md overflow-hidden animate-pulse">
<div className="aspect-square bg-muted"></div>
<div className="p-6">
<div className="h-6 bg-gray-200 rounded mb-2"></div>
<div className="h-4 bg-gray-200 rounded mb-4"></div>
<div className="h-8 bg-gray-200 rounded mb-4"></div>
<div className="h-12 bg-gray-200 rounded"></div>
<div className="h-6 bg-muted rounded mb-2"></div>
<div className="h-4 bg-muted rounded mb-4"></div>
<div className="h-8 bg-muted rounded mb-4"></div>
<div className="h-12 bg-muted rounded"></div>
</div>
</div>
))}
@@ -173,12 +173,12 @@ const Products: React.FC<ProductsProps> = ({
{title}
</h2>
<div className="bg-gray-50 border border-gray-200 rounded-lg p-8 max-w-md mx-auto">
<i className="ri-shopping-bag-line text-4xl text-gray-400 mb-4"></i>
<h3 className="text-lg font-semibold text-gray-600 mb-2">
<div className="bg-muted border border-border rounded-lg p-8 max-w-md mx-auto">
<i className="ri-shopping-bag-line text-4xl text-muted-foreground mb-4"></i>
<h3 className="text-lg font-semibold text-foreground mb-2">
No Products Found
</h3>
<p className="text-gray-500">
<p className="text-muted-foreground">
Check back later or configure your Shopify store connection.
</p>
</div>
@@ -190,7 +190,7 @@ const Products: React.FC<ProductsProps> = ({
return (
<div className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-5xl font-bold text-center mb-16 text-gray-900 font-heading">
<h2 className="text-5xl font-bold text-center mb-16 text-foreground font-heading">
{title}
</h2>

View File

@@ -2,7 +2,7 @@ import React from 'react';
const Footer: React.FC = () => {
return (
<footer className="bg-black text-white py-12">
<footer className="bg-foreground text-background py-12">
<div className="container mx-auto px-4 text-center">
<h3
className="text-2xl font-bold mb-4"
@@ -10,10 +10,10 @@ const Footer: React.FC = () => {
>
Store
</h3>
<p className="text-gray-400 mb-6">
<p className="text-background/70 mb-6">
Your premium shopping destination
</p>
<div className="mt-8 pt-8 border-t border-gray-800 text-gray-400">
<div className="mt-8 pt-8 border-t border-background/20 text-background/70">
<p>&copy; 2025 Store. All rights reserved.</p>
</div>
</div>

View File

@@ -11,11 +11,11 @@ const CartIcon: React.FC = () => {
return (
<button
onClick={toggleCart}
className="relative p-1 text-black hover:text-gray-600 transition-colors"
className="relative p-1 text-foreground hover:text-muted-foreground transition-colors"
>
<i className="ri-shopping-cart-line text-xl"></i>
{itemCount > 0 && (
<span className="absolute -top-1 -right-1 bg-black text-white text-[10px] rounded-full w-4 h-4 flex items-center justify-center font-semibold">
<span className="absolute -top-1 -right-1 bg-primary text-primary-foreground text-[10px] rounded-full w-4 h-4 flex items-center justify-center font-semibold">
{itemCount > 99 ? '99+' : itemCount}
</span>
)}
@@ -25,11 +25,11 @@ const CartIcon: React.FC = () => {
const Header: React.FC = () => {
return (
<nav className="bg-white shadow-sm sticky top-0 z-30 h-14">
<nav className="bg-background shadow-sm sticky top-0 z-30 h-14">
<div className="container mx-auto px-4 h-full">
<div className="flex justify-between items-center h-full">
{/* Logo */}
<Link to="/" className="text-lg font-bold text-black font-heading">
<Link to="/" className="text-lg font-bold text-foreground font-heading">
{config.brand.logo.url ? (
<img
src={config.brand.logo.url}
@@ -45,13 +45,13 @@ const Header: React.FC = () => {
<div className="flex items-center space-x-6">
<Link
to="/"
className="text-sm text-black hover:text-gray-600 font-medium transition-colors"
className="text-sm text-foreground hover:text-muted-foreground font-medium transition-colors"
>
Products
</Link>
<Link
to="/collections"
className="text-sm text-black hover:text-gray-600 font-medium transition-colors"
className="text-sm text-foreground hover:text-muted-foreground font-medium transition-colors"
>
Collections
</Link>

View File

@@ -29,50 +29,69 @@ export function Testimonials({ tagline, heading, items }: TestimonialsProps) {
{heading ? <Typography variant="h2">{heading}</Typography> : null}
{item ? (
<figure className="mx-auto mt-12 flex max-w-2xl flex-col items-center">
<blockquote
className="text-balance text-foreground"
style={{ fontSize: "clamp(1.25rem, 2.4vw, 1.75rem)", lineHeight: 1.4 }}
>
{item.quote}
</blockquote>
<figcaption className="mt-8 flex items-center gap-3">
{item.avatar ? (
<img
src={item.avatar}
alt={item.author}
className="h-10 w-10 rounded-full object-cover"
/>
) : null}
<div className="text-left">
<p className="text-sm font-medium">{item.author}</p>
{item.role ? (
<p className="text-xs text-muted-foreground">{item.role}</p>
) : null}
</div>
</figcaption>
</figure>
) : null}
<div className="relative mt-12">
{total > 1 ? (
<button
onClick={() => setI((p) => (p - 1 + total) % total)}
className="absolute left-0 top-1/2 hidden -translate-y-1/2 items-center justify-center rounded-full border h-10 w-10 hover:bg-background md:inline-flex"
aria-label="Previous"
>
<ArrowLeft size={16} />
</button>
) : null}
{total > 1 ? (
<div className="mt-10 flex items-center justify-center gap-3">
<button
onClick={() => setI((p) => (p - 1 + total) % total)}
className="inline-flex h-10 w-10 items-center justify-center rounded-full border border-border hover:bg-background"
aria-label="Previous"
>
<ArrowLeft size={16} />
</button>
<span className="text-xs tabular-nums text-muted-foreground">
{i + 1} / {total}
</span>
<button
onClick={() => setI((p) => (p + 1) % total)}
className="inline-flex h-10 w-10 items-center justify-center rounded-full border border-border hover:bg-background"
aria-label="Next"
>
<ArrowRight size={16} />
</button>
<figure className="mx-auto flex max-w-2xl flex-col items-center px-12 md:px-16">
<blockquote
className="text-balance text-foreground"
style={{ fontSize: "clamp(1.25rem, 2.4vw, 1.75rem)", lineHeight: 1.4 }}
>
{item.quote}
</blockquote>
<figcaption className="mt-8 flex items-center gap-3">
{item.avatar ? (
<img
src={item.avatar}
alt={item.author}
className="h-10 w-10 rounded-full object-cover"
/>
) : null}
<div className="text-left">
<p className="text-sm font-medium">{item.author}</p>
{item.role ? (
<p className="text-xs text-muted-foreground">{item.role}</p>
) : null}
</div>
</figcaption>
</figure>
{total > 1 ? (
<button
onClick={() => setI((p) => (p + 1) % total)}
className="absolute right-0 top-1/2 hidden -translate-y-1/2 items-center justify-center rounded-full border h-10 w-10 hover:bg-background md:inline-flex"
aria-label="Next"
>
<ArrowRight size={16} />
</button>
) : null}
{total > 1 ? (
<div className="mt-8 flex items-center justify-center gap-3 md:hidden">
<button
onClick={() => setI((p) => (p - 1 + total) % total)}
className="inline-flex h-10 w-10 items-center justify-center rounded-full border hover:bg-background"
aria-label="Previous"
>
<ArrowLeft size={16} />
</button>
<button
onClick={() => setI((p) => (p + 1) % total)}
className="inline-flex h-10 w-10 items-center justify-center rounded-full border hover:bg-background"
aria-label="Next"
>
<ArrowRight size={16} />
</button>
</div>
) : null}
</div>
) : null}
</div>

View File

@@ -102,9 +102,16 @@
--sidebar-ring: oklch(0.708 0 0);
}
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--border);
}
@layer base {
* { border-color: var(--border);
@apply border-border outline-ring/50; }
* { @apply outline-ring/50; }
html, body { background-color: var(--background); color: var(--foreground); }
body {
font-family: var(--font-body), "Apple Color Emoji", "Segoe UI Emoji";