Bilal (24 Eyl 2026): ana sayfa CTA'sında doku hiç görünmüyordu, bazı kartlarda çok azdı; sonra "çok fazla piksel, küçük olanlar hiç olmasın" ve "/sonuc'taki kartın arkasına da piksel koymuşsun; pikseller CTA'larda olacak sadece". - Kök neden: PixelMasonry sabit 420×120 çizimi kaplayacak şekilde ölçekleniyordu; yüksek kartlarda görünen kısım boş banda düşüyordu. Artık kabın gerçek ölçüsüne göre üretiliyor (ResizeObserver), yalnız kenar çerçevesinde, orta boş; `haric` verilen öğenin (24'lük piksel tablosu) çevresi her genişlikte boş. Sunucuda boş, ölçülünce belirir. - Küçük (tek hücre) kare yok: 4×4 makro hücrede 2–4 hücrelik kareler, iri olan seyrek ve silik. Ölçüm: kapanış kartı 1280 px'te 58 kare (tabloya binen 0), 375 px'te 27 kare. - Beyaz içerik kartlarından zemin geri alındı (tadımlık, /listem üretim ve kilit kartları, boş durum, sıralama-yok, meraklısına, paket kartları, kaydet bandı, katalog üstü kompakt satır, /sonuc "listen hazır"). Kalanlar: CtaBandi, PikselCtaYuzeyi, arama penceresi kartı. PikselZemin'in açık tonu kaldırıldı. DESIGN.md §10.8 güncellendi. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
"use client";
|
||
|
||
import { useRef, useState, type ReactNode } from "react";
|
||
import { cn } from "@/lib/utils";
|
||
import { PikselZemin } from "@/components/piksel-zemin";
|
||
import { PikselListe, PikselListeAciklama } from "@/components/piksel-liste";
|
||
|
||
/**
|
||
* Kapanış yüzeyi (DESIGN.md §10.8) — arama penceresindeki kartın dili:
|
||
* koyu slate-950 zemin, ince mavi kenar, turuncu CTA. Arka planda büyüklü
|
||
* küçüklü, masonry gibi kaymış piksel dokusu (PixelMasonry); yüzeyin
|
||
* kreatifi 24'lük listenin kendisidir (PikselListe). Kartın içindeki bir
|
||
* düğmeye ya da linke imleç/odak gelince 24 kare birden dolar — "listen
|
||
* böyle hazır olur". Yazılıp silinen satır yok (Bilal, 24 Eyl 2026).
|
||
*/
|
||
export function PikselCtaYuzeyi({
|
||
children,
|
||
className,
|
||
seed = 7,
|
||
}: {
|
||
children: ReactNode;
|
||
className?: string;
|
||
/** Piksel dokusunun deseni; aynı sayfadaki iki yüzey farklı olsun */
|
||
seed?: number;
|
||
}) {
|
||
const [tamamla, setTamamla] = useState(false);
|
||
// Piksel tablosunun çevresi dokuda boş kalır (Bilal, 24 Eyl 2026:
|
||
// "tablonun arkasına çok piksel yığılmış"); ölçü gerçek yerleşimden.
|
||
const listeRef = useRef<HTMLDivElement>(null);
|
||
|
||
const hedefMi = (t: EventTarget | null) =>
|
||
t instanceof Element && t.closest("a, button") != null;
|
||
|
||
return (
|
||
<section
|
||
onPointerOver={(e) => setTamamla(hedefMi(e.target))}
|
||
onPointerLeave={() => setTamamla(false)}
|
||
onFocusCapture={(e) => setTamamla(hedefMi(e.target))}
|
||
onBlurCapture={() => setTamamla(false)}
|
||
className={cn(
|
||
"relative isolate overflow-hidden rounded-3xl border border-blue-400/20 bg-slate-950 text-white shadow-xl shadow-slate-900/10",
|
||
className,
|
||
)}
|
||
>
|
||
<PikselZemin seed={seed} haric={listeRef} className="-inset-y-10" />
|
||
<div className="grid items-center gap-8 px-5 py-10 sm:px-10 sm:py-12 lg:grid-cols-[minmax(0,1fr)_16rem] lg:gap-12">
|
||
<div className="flex min-w-0 flex-col items-center text-center lg:items-start lg:text-left">
|
||
{children}
|
||
</div>
|
||
<div
|
||
ref={listeRef}
|
||
className="order-first flex flex-col items-center lg:order-none"
|
||
>
|
||
<PikselListe
|
||
tamamla={tamamla}
|
||
className="w-full max-w-[9rem] sm:max-w-[11rem] lg:max-w-[14rem]"
|
||
/>
|
||
<PikselListeAciklama className="mt-4 justify-center" />
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}
|