Polish header icon alignment and banner hover overlays.

Align cart with search/profile controls and show banner slot text only on hover.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-30 10:58:28 +03:30
co-authored by Cursor
parent 9e2dc2c61d
commit 3576052f9d
5 changed files with 29 additions and 22 deletions
+8 -2
View File
@@ -56,11 +56,17 @@ const categoryFallbacks: SlotMediaItem[] = [
];
const bannerFallbacks: SlotMediaItem[] = [
{ id: "banner-1", image: "/images/banner-1.png", href: "#" },
{
id: "banner-1",
image: "/images/banner-1.png",
href: "/products",
title: "فروش ویژه",
titleEn: "SPECIAL SALE",
},
{
id: "banner-2",
image: "/images/console-cat-4.jpg",
href: "#",
href: "/products",
title: "کلکسیون میز کنسول",
titleEn: "NEW COLLECTION",
},
+13 -12
View File
@@ -10,13 +10,9 @@ export default function BannerRow({ items, aspectRatio }: BannerRowProps) {
return (
<section className="mx-auto grid max-w-6xl grid-cols-1 gap-6 px-4 py-4 sm:px-6 md:grid-cols-2 lg:px-8">
{items.map((banner) => {
const hasOverlay = Boolean(banner.title || banner.titleEn || banner.text);
const hasContent = Boolean(banner.title || banner.titleEn || banner.text);
const media = (
<div
className={`group relative block overflow-hidden rounded-2xl shadow-sm ${
hasOverlay ? "" : "bg-white"
}`}
>
<div className="group relative block overflow-hidden rounded-2xl bg-neutral-100 shadow-sm">
<SlotMedia
src={banner.image}
href={undefined}
@@ -26,16 +22,21 @@ export default function BannerRow({ items, aspectRatio }: BannerRowProps) {
className={!aspectRatio ? "block h-56 w-full sm:h-72" : "block w-full"}
imgClassName="absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
/>
{hasOverlay ? (
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 bg-black/40 text-center text-white">
{hasContent ? (
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 bg-white/0 text-center opacity-0 transition-all duration-300 group-hover:bg-white/80 group-hover:opacity-100">
{banner.titleEn ? (
<p className="text-xs tracking-[0.3em]" style={{ fontFamily: "var(--font-montserrat)" }}>
<p
className="text-xs tracking-[0.3em] text-primary"
style={{ fontFamily: "var(--font-montserrat)" }}
>
{banner.titleEn}
</p>
) : null}
{banner.title ? <h3 className="text-2xl font-bold">{banner.title}</h3> : null}
{banner.text ? <p className="text-sm">{banner.text}</p> : null}
<span className="mt-2 rounded-full border border-white/70 px-5 py-2 text-sm font-medium transition-colors group-hover:bg-white group-hover:text-neutral-900">
{banner.title ? (
<h3 className="text-2xl font-bold text-neutral-800">{banner.title}</h3>
) : null}
{banner.text ? <p className="text-sm text-neutral-600">{banner.text}</p> : null}
<span className="mt-2 rounded-full border border-primary/70 px-5 py-2 text-sm font-medium text-primary transition-colors group-hover:bg-primary group-hover:text-white">
مشاهده محصولات
</span>
</div>
+4 -4
View File
@@ -17,14 +17,14 @@ export default function CartPopover() {
useClickOutside(ref, () => setOpen(false));
return (
<div className="relative" ref={ref}>
<div className="relative flex items-center" ref={ref}>
<button
type="button"
aria-label="سبد خرید"
onClick={() => setOpen((v) => !v)}
className="relative text-neutral-600 transition-colors hover:text-primary"
className="relative inline-flex h-9 w-9 items-center justify-center text-neutral-600 transition-colors hover:text-primary"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" className="h-5 w-5">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" className="h-5 w-5 translate-y-px">
<path
d="M3 4h2l1.4 11.2A2 2 0 0 0 8.4 17H18a2 2 0 0 0 2-1.6L21.5 8H6"
stroke="currentColor"
@@ -36,7 +36,7 @@ export default function CartPopover() {
<circle cx="17.5" cy="20.5" r="1.3" fill="currentColor" />
</svg>
{itemCount > 0 ? (
<span className="absolute -top-2 -left-2 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-bold text-white">
<span className="absolute top-0 left-0 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-bold text-white">
{itemCount}
</span>
) : null}
+1 -1
View File
@@ -52,7 +52,7 @@ export default async function Header() {
<div className="flex items-center gap-5">
<button
aria-label="جستجو"
className="text-neutral-600 transition-colors hover:text-primary"
className="inline-flex h-9 w-9 items-center justify-center text-neutral-600 transition-colors hover:text-primary"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" className="h-5 w-5">
<circle cx="11" cy="11" r="7" stroke="currentColor" strokeWidth="1.8" />
+3 -3
View File
@@ -66,7 +66,7 @@ export default function ProfileMenu() {
return (
<a
href={loginUrl || CUSTOMER_PORTAL_URL}
className="flex items-center gap-1.5 text-sm font-medium text-neutral-700 transition-colors hover:text-primary"
className="inline-flex h-9 items-center gap-1.5 text-sm font-medium text-neutral-700 transition-colors hover:text-primary"
aria-label="ورود"
>
<UserIcon />
@@ -76,11 +76,11 @@ export default function ProfileMenu() {
}
return (
<div className="relative" ref={ref}>
<div className="relative flex items-center" ref={ref}>
<button
type="button"
onClick={() => setOpen((v) => !v)}
className="flex items-center gap-1.5 text-sm font-medium text-neutral-700 transition-colors hover:text-primary"
className="inline-flex h-9 items-center gap-1.5 text-sm font-medium text-neutral-700 transition-colors hover:text-primary"
aria-expanded={open}
aria-haspopup="menu"
>