Fix
This commit is contained in:
+45
-13
@@ -39,20 +39,26 @@
|
||||
--container-boxed: 1320px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--color-body);
|
||||
font-family: var(--font-fa), Tahoma, sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
/* Base element defaults belong in Tailwind's base layer so utility
|
||||
classes (text-white, font-bold, etc.) can always override them —
|
||||
unlayered CSS beats utilities regardless of specificity, which was
|
||||
silently breaking text-color utilities on every heading. */
|
||||
@layer base {
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--color-body);
|
||||
font-family: var(--font-fa), Tahoma, sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--color-ink);
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--color-ink);
|
||||
}
|
||||
}
|
||||
|
||||
.font-en {
|
||||
@@ -98,6 +104,32 @@ h6 {
|
||||
background: var(--color-gold) !important;
|
||||
}
|
||||
|
||||
/* Fixed height bands on mobile/tablet (predictable layout, no odd
|
||||
cropping); reverts to the slide's real aspect ratio on desktop where a
|
||||
fixed height would look wrong on wide screens. */
|
||||
.hero-slide-media {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
@media (min-width: 376px) {
|
||||
.hero-slide-media {
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 441px) {
|
||||
.hero-slide-media {
|
||||
height: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.hero-slide-media {
|
||||
height: auto;
|
||||
aspect-ratio: var(--hero-aspect);
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimal styling for CMS-authored HTML (product/blog descriptions) */
|
||||
.rich-text p {
|
||||
margin-bottom: 1em;
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export default async function RootLayout({ children }: LayoutProps<"/">) {
|
||||
dir="rtl"
|
||||
className={`${iranYekan.variable} ${rajdhani.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col bg-white text-ink">
|
||||
<body className="min-h-full flex flex-col">
|
||||
<Header categoryColumns={categoryColumns} />
|
||||
{children}
|
||||
<Footer categoryColumns={categoryColumns} />
|
||||
|
||||
@@ -19,18 +19,18 @@ export default function Categories({ categoryColumns }: { categoryColumns: Categ
|
||||
if (items.length === 0) return null;
|
||||
|
||||
return (
|
||||
<section className="py-10 md:py-14">
|
||||
<section className="pt-5 md:pt-7 pb-10 md:pb-14">
|
||||
<div className="boxed">
|
||||
<SectionHeading kicker="Categories" title="دستهبندی محصولات" />
|
||||
|
||||
<div className="bg-gold rounded-2xl md:rounded-3xl py-8 px-4 md:px-8">
|
||||
<Swiper
|
||||
spaceBetween={10}
|
||||
slidesPerView={4}
|
||||
slidesPerView={2}
|
||||
breakpoints={{
|
||||
480: { slidesPerView: 5 },
|
||||
640: { slidesPerView: 6 },
|
||||
1024: { slidesPerView: 9, spaceBetween: 14 },
|
||||
768: { slidesPerView: 3 },
|
||||
1024: { slidesPerView: 6, spaceBetween: 14 },
|
||||
1280: { slidesPerView: 8, spaceBetween: 14 },
|
||||
}}
|
||||
>
|
||||
{items.map((cat, i) => (
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function FullBanner({ slot }: { slot?: StaticImageSlot }) {
|
||||
|
||||
return (
|
||||
<section className="boxed py-2 md:py-4">
|
||||
<a href={href} className="block overflow-hidden rounded-lg border border-line">
|
||||
<a href={href} className="block overflow-hidden rounded-2xl border border-line">
|
||||
<img
|
||||
src={src}
|
||||
alt=""
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Header({ categoryColumns }: { categoryColumns: CategoryN
|
||||
const [mobileCategoriesOpen, setMobileCategoriesOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 bg-surface pt-2 md:pt-3 pb-0">
|
||||
<header className="sticky top-0 z-50 pt-2 md:pt-3 pb-0">
|
||||
<div className="boxed">
|
||||
<div className="rounded-2xl shadow-sm border border-line/60">
|
||||
{/* Row 1: logo / search / actions */}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { Autoplay, Pagination } from "swiper/modules";
|
||||
import "swiper/css";
|
||||
import "swiper/css/pagination";
|
||||
import type { CSSProperties } from "react";
|
||||
import type { StaticImageSlot } from "@/lib/types";
|
||||
import { toCssAspectRatio } from "@/lib/format";
|
||||
|
||||
@@ -13,10 +14,12 @@ const fallbackSlides = [
|
||||
"/images/hero/slide-3.svg",
|
||||
];
|
||||
|
||||
const DEFAULT_ASPECT_RATIO = "32/9";
|
||||
|
||||
export default function HeroSlider({ slot }: { slot?: StaticImageSlot }) {
|
||||
const slides = slot?.images ?? [];
|
||||
const cssAspectRatio = toCssAspectRatio(slot?.aspectRatio);
|
||||
const aspectStyle = cssAspectRatio ? { aspectRatio: cssAspectRatio } : undefined;
|
||||
const cssAspectRatio = toCssAspectRatio(slot?.aspectRatio) ?? DEFAULT_ASPECT_RATIO;
|
||||
const mediaStyle = { "--hero-aspect": cssAspectRatio } as CSSProperties;
|
||||
|
||||
return (
|
||||
<section className="boxed pt-4 md:pt-6">
|
||||
@@ -25,41 +28,20 @@ export default function HeroSlider({ slot }: { slot?: StaticImageSlot }) {
|
||||
autoplay={{ delay: 4500, disableOnInteraction: false }}
|
||||
pagination={{ clickable: true }}
|
||||
loop
|
||||
className="hero-swiper rounded-lg overflow-hidden"
|
||||
className="hero-swiper rounded-2xl overflow-hidden border border-line"
|
||||
>
|
||||
{slides.length > 0
|
||||
? slides.map((img) => (
|
||||
<SwiperSlide key={img.id}>
|
||||
{img.linkUrl ? (
|
||||
<a href={img.linkUrl}>
|
||||
<img
|
||||
src={img.url}
|
||||
alt=""
|
||||
style={aspectStyle}
|
||||
className={`w-full object-cover ${
|
||||
aspectStyle ? "" : "aspect-[16/6] md:aspect-[32/9]"
|
||||
}`}
|
||||
/>
|
||||
</a>
|
||||
) : (
|
||||
<img
|
||||
src={img.url}
|
||||
alt=""
|
||||
style={aspectStyle}
|
||||
className={`w-full object-cover ${
|
||||
aspectStyle ? "" : "aspect-[16/6] md:aspect-[32/9]"
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
</SwiperSlide>
|
||||
))
|
||||
? slides.map((img) => {
|
||||
const media = (
|
||||
<img src={img.url} alt="" style={mediaStyle} className="hero-slide-media w-full object-cover" />
|
||||
);
|
||||
return (
|
||||
<SwiperSlide key={img.id}>{img.linkUrl ? <a href={img.linkUrl}>{media}</a> : media}</SwiperSlide>
|
||||
);
|
||||
})
|
||||
: fallbackSlides.map((src) => (
|
||||
<SwiperSlide key={src}>
|
||||
<img
|
||||
src={src}
|
||||
alt=""
|
||||
className="w-full aspect-[16/6] md:aspect-[32/9] object-cover"
|
||||
/>
|
||||
<img src={src} alt="" style={mediaStyle} className="hero-slide-media w-full object-cover" />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
@@ -2,12 +2,14 @@ import Link from "next/link";
|
||||
import { siteInfo } from "@/data/site";
|
||||
|
||||
export default function Logo({ dark = false }: { dark?: boolean }) {
|
||||
const sizeClasses = dark ? "h-[72px] md:h-20" : "h-9 md:h-10";
|
||||
|
||||
return (
|
||||
<Link href="/" className="flex items-center shrink-0" aria-label={siteInfo.name}>
|
||||
<img
|
||||
src="/images/logo.png"
|
||||
alt={siteInfo.name}
|
||||
className={`h-9 md:h-10 w-auto object-contain ${
|
||||
className={`${sizeClasses} w-auto object-contain ${
|
||||
dark ? "bg-white rounded-md px-2 py-1" : ""
|
||||
}`}
|
||||
/>
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function TwoBanners({ slot }: { slot?: StaticImageSlot }) {
|
||||
<Wrapper
|
||||
key={i}
|
||||
{...(b.href ? { href: b.href } : {})}
|
||||
className="group block overflow-hidden rounded-lg border border-line"
|
||||
className="group block overflow-hidden rounded-2xl border border-line"
|
||||
>
|
||||
<img
|
||||
src={b.image}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function ProductCard({ product }: { product: ApiProduct }) {
|
||||
className="group flex flex-col h-full bg-white border border-line rounded-lg overflow-hidden"
|
||||
>
|
||||
<div className="relative">
|
||||
<img src={image} alt={title} className="w-full aspect-[4/5] object-cover" />
|
||||
<img src={image} alt={title} className="w-full aspect-square object-cover" />
|
||||
|
||||
{store && !store.inStock && (
|
||||
<span className="absolute inset-0 flex items-center justify-center bg-white/70">
|
||||
|
||||
Reference in New Issue
Block a user