Some checks failed
Deploy / deploy (push) Has been cancelled
Şehir/Türkiye piksel haritası görünüme girince oynar; animasyonlu-mark, console-asr, use-pixel-heat ve cta-sira-form güncellendi. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
142 lines
4.9 KiB
TypeScript
142 lines
4.9 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect } from "react";
|
||
|
||
/**
|
||
* Konsol sürprizi: DevTools'u açan meraklıya sitenin piksel dilinde bir kum
|
||
* saati, Asr Sûresi (Arapça + meal) ve tasavvuftan bir vakit sözü. "Asr"
|
||
* zaman demek; kum saati de onu anlatır. Görünür arayüzde iz bırakmaz; kök
|
||
* layout'ta bir kez çalışır, sayfa geçişlerinde tekrar basmaz.
|
||
*
|
||
* DevTools açık ya da koyu temada olabilir: düz metne renk verilmez
|
||
* (konsolun kendi rengi kalır), yalnız iki zeminde de okunan marka renkleri
|
||
* kullanılır.
|
||
*
|
||
* Arapça metin Diyanet'in Kur'an-ı Kerim mushafından, meal Diyanet İşleri
|
||
* mealinden harfi harfine alındı (kuran.diyanet.gov.tr, âyet gruplaması
|
||
* aynen). Elle düzeltme yapılmaz; değişecekse kaynaktan yeniden kopyalanır.
|
||
*/
|
||
|
||
let basildi = false;
|
||
|
||
// Logodaki üç kare (public/kolay-tercih-mark.svg)
|
||
const MAVI = "#3b82f6";
|
||
const SEFTALI = "#fdc7a7";
|
||
const TURUNCU = "#ff5a00";
|
||
// slate-400: açık ve koyu konsolda okunan silik metin
|
||
const SILIK = "#94a3b8";
|
||
|
||
// Hero'daki dot-matrix ızgarasıyla kum saati: # çerçeve, g boş cam,
|
||
// o yığılmış kum, p akan kum. Üst hazne boşalıyor, alt hazne doluyor.
|
||
const KUM_SAATI = [
|
||
"###########",
|
||
" #ggggggg# ",
|
||
" #ooooooo# ",
|
||
" #ooooo# ",
|
||
" #ooo# ",
|
||
" #p# ",
|
||
" #p# ",
|
||
" #gpg# ",
|
||
" #ggpgg# ",
|
||
" #ggooogg# ",
|
||
" #ooooooo# ",
|
||
"###########",
|
||
];
|
||
|
||
const PIKSEL_RENK: Record<string, string> = {
|
||
"#": MAVI,
|
||
g: "rgba(59,130,246,0.16)",
|
||
o: TURUNCU,
|
||
p: SEFTALI,
|
||
};
|
||
|
||
// Piksel = arka planı boyanmış iki boşluk; satır aralığı ve sağ boşluk
|
||
// hero'daki gibi kareler arasında eşit nefes bırakır.
|
||
const HUCRE = "font-size:8px;line-height:14px;margin-right:4px;border-radius:2px";
|
||
|
||
// Kum saatinin sağında, boğaz hizasında duran satırlar
|
||
const YAN_YAZI: Record<number, [string, string]> = {
|
||
5: ["KolayTercih", `font-size:13px;font-weight:700;color:${MAVI}`],
|
||
6: ["Asr Sûresi", `font-size:12px;color:${SILIK}`],
|
||
};
|
||
|
||
const BESMELE = "بِسْمِ اللّٰهِ الرَّحْمٰنِ الرَّح۪يمِ";
|
||
|
||
const ASR = [
|
||
"وَالْعَصْرِۙ",
|
||
"اِنَّ الْاِنْسَانَ لَفٖي خُسْرٍۙ",
|
||
"اِلَّا الَّذٖينَ اٰمَنُوا وَعَمِلُوا الصَّالِحَاتِ وَتَوَاصَوْا بِالْحَقِّ وَتَوَاصَوْا بِالصَّبْرِ",
|
||
];
|
||
|
||
const MEAL = [
|
||
"Rahmân ve Rahîm olan Allah’ın adıyla.",
|
||
"",
|
||
"1-2. Andolsun zamana ki, insan gerçekten ziyan içindedir.",
|
||
"3. Ancak, iman edip de sâlih ameller işleyenler, birbirlerine hakkı tavsiye edenler, birbirlerine sabrı tavsiye edenler başka (Onlar ziyanda değillerdir).",
|
||
];
|
||
|
||
// Konsol sayfanın web fontlarını görmez; sistemde ne varsa o seçilir.
|
||
const ARAPCA_YAZI_TIPI =
|
||
"'Amiri Quran','Amiri','Scheherazade New','Noto Naskh Arabic','Geeza Pro','Traditional Arabic',serif";
|
||
|
||
function mesaj(): string[] {
|
||
let bicim = "";
|
||
const stiller: string[] = [];
|
||
const ekle = (metin: string, stil: string) => {
|
||
bicim += `%c${metin}`;
|
||
stiller.push(stil);
|
||
};
|
||
|
||
KUM_SAATI.forEach((satir, i) => {
|
||
for (const k of satir) {
|
||
const renk = PIKSEL_RENK[k];
|
||
ekle(" ", renk ? `${HUCRE};background:${renk}` : HUCRE);
|
||
}
|
||
const yan = YAN_YAZI[i];
|
||
if (yan) ekle(` ${yan[0]}`, `line-height:14px;${yan[1]}`);
|
||
bicim += "\n";
|
||
});
|
||
|
||
// Bloklar arasında birer boş satır; her blokta tek punto, tek renk.
|
||
const arapca = `font-size:18px;line-height:2.1;font-family:${ARAPCA_YAZI_TIPI}`;
|
||
ekle(`\n${BESMELE}\n`, `${arapca};color:${SILIK}`);
|
||
ekle(`${ASR.join("\n")}\n`, arapca);
|
||
ekle(`\n${MEAL[0]}\n`, `font-size:12px;line-height:1.8;color:${SILIK}`);
|
||
ekle(`${MEAL.slice(2).join("\n")}\n`, "font-size:12px;line-height:1.8");
|
||
ekle("Asr Sûresi (103) · Diyanet İşleri meali\n", `font-size:11px;line-height:2.2;color:${SILIK}`);
|
||
ekle(
|
||
"\n«Vakit bir kılıçtır; sen onu kesmezsen o seni keser.»\n",
|
||
`font-size:12px;font-style:italic;line-height:1.8;color:${TURUNCU}`,
|
||
);
|
||
ekle(
|
||
"İmam Şâfiî’nin sûfîlerden öğrendiğini söylediği söz\n",
|
||
`font-size:11px;line-height:2.2;color:${SILIK}`,
|
||
);
|
||
ekle(`\n${window.location.origin}/meraklisina`, `font-size:11px;color:${SILIK}`);
|
||
|
||
return [bicim, ...stiller];
|
||
}
|
||
|
||
export function ConsoleAsr() {
|
||
useEffect(() => {
|
||
if (basildi) return;
|
||
basildi = true;
|
||
|
||
// Hidrasyon ve ilk etkileşimle yarışmasın: tarayıcı boşa çıkınca bas.
|
||
// Safari'de requestIdleCallback yok, orada kısa bir gecikme yeter.
|
||
// Önce konsolu temizle: eklenti uyarıları ve çerçeve satırları sürprizi
|
||
// aşağı itmesin, konsolu açan yalnız bunu görsün.
|
||
const bas = () => {
|
||
console.clear();
|
||
console.log(...mesaj());
|
||
};
|
||
if (typeof window.requestIdleCallback === "function") {
|
||
window.requestIdleCallback(bas, { timeout: 3000 });
|
||
} else {
|
||
window.setTimeout(bas, 1000);
|
||
}
|
||
}, []);
|
||
|
||
return null;
|
||
}
|