"use client";
import { useMemo, useRef, type ReactNode } from "react";
import { cn } from "@/lib/utils";
import { usePixelHeat } from "@/components/use-pixel-heat";
/**
* Hero'daki dot-matrix dilini (TurkeyPixelMap) bölüm ayraçlarına ve
* dekorlara taşıyan piksel süsleri. Rastgelelik yerine deterministik
* hash kullanılır ki sunucu ve istemci aynı deseni üretsin.
*
* Hepsi hero'daki imleç ısı fırçasına katılır (usePixelHeat): imleç
* yaklaşınca pikseller turuncuya ısınır, uzaklaşınca yavaşça soğur.
* Turuncu vurgu (accent) pikselleri hero'daki şehirler gibi fırçaya
* katılmaz.
*/
// Hero ile aynı ızgara ölçüleri
const CELL = 10;
const DOT = 7.4;
const INSET = (CELL - DOT) / 2;
// Hero ile aynı doku paleti
const OPACITIES = [0.3, 0.16, 0.24, 0.12, 0.27, 0.19];
const opacityFor = (x: number, y: number) =>
OPACITIES[(x * 7 + y * 11) % OPACITIES.length];
// Deterministik sözde-rastgele: aynı girdi her ortamda aynı deseni verir
const hash = (x: number, y: number, seed: number) => {
const n = Math.sin(x * 127.1 + y * 311.7 + seed * 74.7) * 43758.5453;
return n - Math.floor(n);
};
function pixelRect(
x: number,
y: number,
extra: { key: string; accent?: boolean; accentDelay?: number },
) {
const shared = {
x: x * CELL + INSET,
y: y * CELL + INSET,
width: DOT,
height: DOT,
rx: 2,
};
if (extra.accent) {
return (
);
}
const op = opacityFor(x, y);
return (
);
}
/**
* Geniş alanlar için seyrek piksel zemini (ör. koyu CTA bandı).
* İçeriğin oturduğu orta bölge tamamen boş bırakılır; pikseller
* kenarlara doğru yoğunlaşır.
*/
export function PixelField({
seed = 7,
className,
}: {
seed?: number;
className?: string;
}) {
const svgRef = useRef(null);
usePixelHeat(svgRef);
const COLS = 42;
const ROWS = 12;
// Çıktı seed'e göre deterministik; 504 iterasyon + ~150 element üretimini
// her render'da (ör. çekmece reorder'ında) tekrarlama (rendering-hoist-jsx)
const pixels = useMemo(() => {
const cx = (COLS - 1) / 2;
const cy = (ROWS - 1) / 2;
const maxD = Math.sqrt(cx * cx + cy * cy);
const sonuc: ReactNode[] = [];
let accentIdx = 0;
// Hero serpintisiyle aynı kural: içeriğin oturduğu orta kolon
// (genişliğin %22–78 bandı) tüm yükseklik boyunca tamamen boş kalır
const BAND_MIN = COLS * 0.22;
const BAND_MAX = COLS * 0.78;
for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
if (x > BAND_MIN && x < BAND_MAX) continue;
// Kenarlara doğru artan doluluk
const d = Math.sqrt((x - cx) ** 2 + (y - cy) ** 2) / maxD;
const density = 0.1 + 0.42 * d * d;
if (hash(x, y, seed) > density) continue;
const accent = hash(x, y, seed + 99) > 0.96;
sonuc.push(
pixelRect(x, y, {
key: `${x}-${y}`,
accent,
accentDelay: accent ? (accentIdx++ % 8) * 0.45 : 0,
}),
);
}
}
return sonuc;
}, [seed]);
return (
);
}
/**
* Bölümler arasında sert border çizgileri yerine kullanılan, ortada
* yoğunlaşıp kenarlara doğru dağılan piksel ayraç. Hero'nun dot-matrix
* dilini bölüm geçişlerine taşır.
*/
export function PixelDivider({
seed = 5,
className,
}: {
seed?: number;
className?: string;
}) {
const svgRef = useRef(null);
usePixelHeat(svgRef);
const COLS = 12;
const ROWS = 2;
// Deterministik çıktı — render başına yeniden üretme (PixelField ile aynı)
const pixels = useMemo(() => {
const cx = (COLS - 1) / 2;
const sonuc: ReactNode[] = [];
let accentPlaced = false;
for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
// Az sayıda, iri piksel: ortada yoğun, kenara doğru seyrelen küçük küme
const dx = Math.abs(x - cx) / cx;
const rowFalloff = y === 0 ? 0.9 : 0.35;
const density = (1 - dx) ** 1.1 * rowFalloff;
if (hash(x, y, seed) > density) continue;
const accent = !accentPlaced && hash(x, y, seed + 99) > 0.8;
if (accent) accentPlaced = true;
sonuc.push(
pixelRect(x, y, {
key: `${x}-${y}`,
accent,
}),
);
}
}
return sonuc;
}, [seed]);
return (
);
}
/** Alt sayfa başlıklarını içerikten ayıran kompakt piksel imzası. */
export function PagePixelDivider({
seed = 5,
className,
}: {
seed?: number;
className?: string;
}) {
return (
);
}
/** Küçük sabit süslerde (mark/korner) data-px öznitelikli rect. */
function fixedPixel(x: number, y: number, opacity: number) {
return (
);
}
/** Eyebrow rozetlerinde kullanılan 2×2'lik minik piksel imzası. */
export function PixelMark({ className }: { className?: string }) {
const svgRef = useRef(null);
usePixelHeat(svgRef, { radius: 24 });
return (
);
}
/** Kart köşelerine iliştirilen sessiz piksel kümesi. */
export function PixelCorner({ className }: { className?: string }) {
const svgRef = useRef(null);
usePixelHeat(svgRef, { radius: 28 });
return (
);
}
/** Bölüm başlıklarının üstünde duran piksel imzalı eyebrow rozeti. */
export function SectionEyebrow({
children,
className,
}: {
children: ReactNode;
className?: string;
}) {
return (
{children}
);
}