diff --git a/.claude/skills/ui-ux-pro-max/SKILL.md b/.agents/skills-devre-disi/ui-ux-pro-max/SKILL.md
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/SKILL.md
rename to .agents/skills-devre-disi/ui-ux-pro-max/SKILL.md
diff --git a/.claude/skills/ui-ux-pro-max/data/charts.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/charts.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/charts.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/charts.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/colors.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/colors.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/colors.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/colors.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/icons.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/icons.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/icons.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/icons.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/landing.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/landing.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/landing.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/landing.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/products.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/products.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/products.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/products.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/prompts.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/prompts.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/prompts.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/prompts.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/react-performance.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/react-performance.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/react-performance.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/react-performance.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/stacks/html-tailwind.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/stacks/html-tailwind.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/stacks/nextjs.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/stacks/nextjs.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/stacks/react.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/stacks/react.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/stacks/react.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/stacks/react.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/stacks/shadcn.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/stacks/shadcn.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/styles.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/styles.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/styles.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/styles.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/typography.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/typography.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/typography.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/typography.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/ui-reasoning.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/ui-reasoning.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/ui-reasoning.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/ux-guidelines.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/ux-guidelines.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/ux-guidelines.csv
diff --git a/.claude/skills/ui-ux-pro-max/data/web-interface.csv b/.agents/skills-devre-disi/ui-ux-pro-max/data/web-interface.csv
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/data/web-interface.csv
rename to .agents/skills-devre-disi/ui-ux-pro-max/data/web-interface.csv
diff --git a/.claude/skills/ui-ux-pro-max/scripts/core.py b/.agents/skills-devre-disi/ui-ux-pro-max/scripts/core.py
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/scripts/core.py
rename to .agents/skills-devre-disi/ui-ux-pro-max/scripts/core.py
diff --git a/.claude/skills/ui-ux-pro-max/scripts/design_system.py b/.agents/skills-devre-disi/ui-ux-pro-max/scripts/design_system.py
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/scripts/design_system.py
rename to .agents/skills-devre-disi/ui-ux-pro-max/scripts/design_system.py
diff --git a/.claude/skills/ui-ux-pro-max/scripts/search.py b/.agents/skills-devre-disi/ui-ux-pro-max/scripts/search.py
similarity index 100%
rename from .claude/skills/ui-ux-pro-max/scripts/search.py
rename to .agents/skills-devre-disi/ui-ux-pro-max/scripts/search.py
diff --git a/.agents/skills/kolaytercih-tasarim/SKILL.md b/.agents/skills/kolaytercih-tasarim/SKILL.md
new file mode 100644
index 0000000..2381d32
--- /dev/null
+++ b/.agents/skills/kolaytercih-tasarim/SKILL.md
@@ -0,0 +1,86 @@
+---
+name: kolaytercih-tasarim
+description: KolayTercih'in kendi görsel dili — piksel imzası (SectionEyebrow, PixelDivider, PixelCorner), Cal Sans/Clarity City/Bricolage tipografisi, mavi bilgi + turuncu aksiyon rengi, slate nötrler, sondaki ArrowRight'lı CTA. Yeni ekran, bileşen, kart, modal, buton, form ya da sayfa tasarlarken; mevcut arayüzü değiştirirken; "AI gibi duruyor", "sitenin diline uymuyor", "piksel detayı kaybolmuş" denince kullanılır. docs/tasarim/DESIGN.md'nin giriş kapısıdır.
+---
+
+# KolayTercih tasarım dili
+
+Bu proje için genel tasarım kütüphanesi (stil katalogları, palet listeleri) **kullanılmaz**;
+yön zaten belli. Kaynak tek: `docs/tasarim/DESIGN.md`. Bu dosya onu nasıl uygulayacağını söyler.
+
+## 1. Başlamadan önce (zorunlu)
+
+1. `docs/tasarim/DESIGN.md` dosyasını **tamamını** oku (181 satır). Özellikle §4 tek kaynaklar ve §7 yap/yapma.
+2. Dört satırlık brief'i doldur (DESIGN.md §9): amaç · referans ekran · tek kaynak parçalar · durumlar.
+3. Referans ekranı bul ve aç; kopyalayacağın sınıf dizilerini oradan al:
+
+```bash
+grep -rn "SectionEyebrow" src --include='*.tsx' -l # rozetli başlık bloğu örnekleri
+grep -rn "bg-orange-500" src --include='*.tsx' -l # turuncu CTA örnekleri
+grep -rn "PixelCorner\|PagePixelDivider" src -l --include='*.tsx' # piksel imzası taşıyan ekranlar
+```
+
+Ana sayfa bölüm iskeleti: `src/app/page.tsx` (Problem bölümü, ~satır 268). Alt sayfa başlığı: `src/app/meraklisina/page.tsx`.
+
+## 2. Yazarken
+
+- Kanonik parçaları içe aktar, yeniden çizme: `SectionEyebrow`, `PagePixelDivider`, `PixelCorner`
+ (`@/components/pixel-decor`); `Button` (`@/components/ui/button`); `Card` (`@/components/ui/card`);
+ `DialogContent` varsayılan çarpısı (`@/components/ui/dialog`); `ArrowRight`, `XIcon` (`lucide-react`).
+- Sınıf dizilerini DESIGN.md'den **birebir** kopyala; "yaklaşık aynı" yazma.
+- Her piksel süsüne o sayfaya özgü tek `seed` ver (mevcut seed'ler: `grep -rho "seed={[0-9]*}" src | sort -u`).
+- Risk rengi kullanıyorsan metin etiketini `RISK_ETIKET` / `DILIM_ETIKET`'ten (`src/lib/risk.ts`) al.
+- Türkçe tanımlayıcı, çevredeki kodla aynı yorum yoğunluğu (AGENTS.md).
+
+## 3. Bitirmeden önce
+
+```bash
+pnpm tasarim:denetim # sıfır hata olmadan iş bitmiş sayılmaz
+```
+
+Uyarıları raporda listele; hataları düzelt. Sonra 375 px kontrol notu yaz: taşma, üst üste binme,
+dokunma hedefi < 44 px, uzun üniversite adı. (Tarayıcı açma kuralı AGENTS.md'de; koddan çıkarım yazıyorsan "koddan çıkarım" de.)
+
+## 4. Örnekler
+
+**İstek:** "Bölüm sayfasına 'Bu bölümü okuyanlar ne diyor' başlığı ekle."
+**Çıktı:**
+```tsx
+
+ Öğrenci görüşleri
+
Bu bölümü okuyanlar ne diyor?
+
…
+
+```
+
+**İstek:** "Paket sayfasına satın alma butonu koy."
+**Çıktı:**
+```tsx
+
+```
+(Yanlış: başta ``, `bg-gradient-to-r`, `rounded-xl`, "Hemen Al ✨".)
+
+**İstek:** "Üniversite sayfasına URAP kartı ekle."
+**Çıktı:**
+```tsx
+
+
+
URAP Türkiye
+
18 / 198
+
+```
+
+**İstek:** "Modal ekle, çarpı sağ üstte olsun."
+**Çıktı:** `DialogContent` varsayılanını kullan; hiçbir sınıf verme. Özel yerleşim şartsa `showCloseButton={false}` + DESIGN.md §4.3'teki sınıf dizisi aynen.
+
+## 5. Kısa yasak listesi
+
+`Badge` import'u · elle pill span · CTA'da `Sparkles`/emoji · `indigo/purple/gray/zinc` · gradyan metin ·
+parlama gölgesi · `whileHover scale` · her elemanda fade-up · `dark:` · Inter/Roboto/serif · `text-[#hex]` · renk tek başına anlam.
+
+## 6. Rapor
+
+İş sonunda: kullanılan kanonik parçalar (liste) · `pnpm tasarim:denetim` çıktısı (hata/uyarı sayısı) · 375 px notu · DESIGN.md ile çelişen bir şey bulduysan dosya:satır ile yaz, kendi başına kuralı değiştirme.
diff --git a/.claude/agents/tasarimci.md b/.claude/agents/tasarimci.md
index 8c229a3..16c4ebe 100644
--- a/.claude/agents/tasarimci.md
+++ b/.claude/agents/tasarimci.md
@@ -1,6 +1,8 @@
---
name: tasarimci
description: Ürün tasarımcısı (UX/UI). Yeni ekran ve akışların tasarım tanımını yazar; mevcut arayüzü tutarlılık (tek kaynak bileşenler), mobil kullanım, erişilebilirlik ve arayüz metni açısından koddan denetler. Yeni bir UI işi başlamadan önce ya da bir UI dalı merge edilmeden önce kullan.
+skills:
+ - kolaytercih-tasarim
tools: Read, Grep, Glob, Bash, Write, Edit, Skill, mcp__Claude_Browser__preview_start, mcp__Claude_Browser__preview_stop, mcp__Claude_Browser__navigate, mcp__Claude_Browser__computer, mcp__Claude_Browser__read_page, mcp__Claude_Browser__find, mcp__Claude_Browser__resize_window, mcp__Claude_Browser__tabs_context, mcp__Claude_Browser__tabs_close, mcp__Claude_Browser__browser_batch
---
@@ -14,17 +16,18 @@ Sen KolayTercih ekibinin **ürün tasarımcısısın**. İşe başlamadan önce
- Risk dili: kırmızı/sarı/yeşil **her zaman metin etiketiyle**; renk tek başına anlam taşımaz.
- Bileşen tabanı shadcn (`src/components/ui`), tipografi ve renk token'ları `src/app/globals.css`.
-## Beceriler (işe başlarken yükle)
+## Beceriler
-Projede kurulu tasarım becerileri senin referans kitaplığındır; kendi zevkinle değil bunlarla ve yukarıdaki tek kaynaklarla gerekçelendir. Çakışmada öncelik: `AGENTS.md` / tek kaynak bileşenler > beceri > kendi yorumun.
+Görsel dilin tek kaynağı `docs/tasarim/DESIGN.md`; giriş kapısı olan `kolaytercih-tasarim` becerisi sana başlangıçta yüklü gelir. Genel tasarım katalogları (`ui-ux-pro-max` vb.) **kullanılmaz**: yön zaten belli, katalog "ortalama site" görünümüne iter. Çakışmada öncelik: `AGENTS.md` / DESIGN.md tek kaynakları > beceri > kendi yorumun.
-- **Her işte:** `Skill` aracıyla `shadcn` (bileşen kompozisyonu, form/ikon/overlay kuralları) ve `ui-ux-pro-max` (tipografi, boşluk, erişilebilirlik kontrol listesi) yükle; `.agents/skills/frontend-ui-engineering/SKILL.md` dosyasını `Read` ile oku (Skill listesinde görünmez).
-- **Etkileşim/dokunma/çekmece/sheet işlerinde:** `apple-design` ve `emil-design-eng`.
-- **Hareket denetiminde:** `find-animation-opportunities` (eksik hareket) ve `.agents/skills/review-animations/SKILL.md` + `STANDARDS.md` dosyalarını `Read` ile oku (bu beceri Skill aracıyla çağrılamaz); değerleri STANDARDS.md'den birebir al, yaklaşık yazma.
-- **Bileşen mimarisi sorusu çıkarsa:** `vercel-react-best-practices` ve `nextjs-app-architecture` — yalnızca tasarım tanımının hangi bileşenin client/server olacağını etkilediği yerde.
+Yalnızca ihtiyaç doğduğunda, `Skill` aracıyla:
+- Yeni bir shadcn bileşeni eklenecekse: `shadcn`.
+- Etkileşim/dokunma/çekmece/sheet işinde: `apple-design`, `emil-design-eng`.
+- Hareket denetiminde: `find-animation-opportunities`; `.agents/skills/review-animations/SKILL.md` + `STANDARDS.md`'yi `Read` ile oku, değerleri STANDARDS.md'den birebir al.
+- Bileşen mimarisi sorusu çıkarsa: `vercel-react-best-practices`, `nextjs-app-architecture`.
- `prototype` ve `pick-ui-library` sana kapalı; ihtiyaç görürsen `[BİLAL]` olarak öner.
-Beceri okumak `src/` altına dokunma yetkisi vermez; sınırlar aynen geçerli.
+Her denetimde `pnpm tasarim:denetim` çıktısını rapora koy; makinenin yakaladığını elle tekrar arama, gözünü makinenin göremediğine (hiyerarşi, taşma, metin) ayır.
## Görev
diff --git a/.claude/agents/yazilimci.md b/.claude/agents/yazilimci.md
index 954a953..0626014 100644
--- a/.claude/agents/yazilimci.md
+++ b/.claude/agents/yazilimci.md
@@ -2,6 +2,8 @@
name: yazilimci
description: Yazılım geliştirici. Tanımı net bir işi ya da CTO şartnamesindeki tek bir paketi uygular; yalnızca sahibi olduğu dosyalara dokunur, typegen+tsc+lint ile doğrular, raporunu yazar. Paralel çalıştırılacaksa her kopyaya ayrı worktree + dal ve ayrık dosya kümesi verilmelidir. Push/merge yapmaz.
disallowedTools: mcp__rybbit
+skills:
+ - kolaytercih-tasarim
---
Sen KolayTercih ekibinin **yazılım geliştiricilerinden birisin**. İşe başlamadan önce `docs/ekip/PROTOKOL.md` dosyasını ve repo kökündeki `AGENTS.md`'yi oku; kurallar istisnasız bağlayıcıdır.
@@ -12,8 +14,8 @@ Orkestratör sana şunları verir: iş tanımı ya da paket adı + şartnamenin
1. Şartnamendeki bölümü ve "dosya sahipliği" tablosunu oku. **Listede olmayan dosyaya dokunma.** Başka bir paketin dosyasında değişiklik şart görünüyorsa yapma; raporuna "sapma/engel" olarak yaz. Şartname yoksa: değişikliği en küçük dosya kümesiyle yap ve dokunduğun her dosyayı raporla.
2. Next'e özgü bir API'ye dokunmadan önce `node_modules/next/dist/docs/` içindeki ilgili sayfayı oku — bu sürüm eğitim verindeki Next değil. Kütüphane davranışını varsayma; kaynağını oku.
-3. Kodu çevresindeki kod gibi yaz: aynı adlandırma (Türkçe tanımlayıcılar), aynı yorum yoğunluğu, aynı desenler. AGENTS.md UI kuralları geçerli (SectionEyebrow, CTA'da metin sonunda `ArrowRight`, kanonik kapatma çarpısı). Sihirbaz/listeleme davranışını değiştiriyorsan `/meraklisina` mermaid şemasını ve çevresini aynı commit'te güncelle.
-4. Doğrulama: `pnpm exec next typegen && pnpm exec tsc --noEmit && pnpm lint`. `pnpm build`'i yalnızca iş tanımı senden istiyorsa koş (paralel build RAM'i tüketir). Dev sunucusu/tarayıcı açma.
+3. Kodu çevresindeki kod gibi yaz: aynı adlandırma (Türkçe tanımlayıcılar), aynı yorum yoğunluğu, aynı desenler. UI'a dokunan işte `docs/tasarim/DESIGN.md` tek kaynaktır (başlangıçta yüklü `kolaytercih-tasarim` becerisi oraya götürür); sınıf dizilerini oradan birebir al. Sihirbaz/listeleme davranışını değiştiriyorsan `/meraklisina` mermaid şemasını ve çevresini aynı commit'te güncelle.
+4. Doğrulama: `pnpm exec next typegen && pnpm exec tsc --noEmit && pnpm lint` (`lint` tasarım denetimini de koşar; sıfır hata şart). `pnpm build`'i yalnızca iş tanımı senden istiyorsa koş (paralel build RAM'i tüketir). Dev sunucusu/tarayıcı açma.
5. Commit (istendiyse): küçük, tek amaçlı, repo üslubunda (`feat(alan): …`, `fix(alan): …`). `git add -A` / `git add .` **yasak** — dosyaları yol vererek ekle. Bilal kararına bağlı değişiklikleri ayrı commit yap, mesaja `[Bilal]` koy. Kısmi commit'te bağımlılık kapanışını kontrol et: bir dosyanın kullandığı prop/export başka bir commit'lenmemiş dosyadan geliyorsa aynı commit'e al.
6. `main`'e commit yok, push yok, merge yok, başka worktree'de komut yok.
diff --git a/.claude/skills/kolaytercih-tasarim b/.claude/skills/kolaytercih-tasarim
new file mode 120000
index 0000000..c69f397
--- /dev/null
+++ b/.claude/skills/kolaytercih-tasarim
@@ -0,0 +1 @@
+../../.agents/skills/kolaytercih-tasarim
\ No newline at end of file
diff --git a/AGENTS.md b/AGENTS.md
index 02b6842..47da23b 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -20,9 +20,13 @@ Açtığında geçerli olanlar:
Push emri geldiğinde önce lokalde `pnpm build` başarıyla geçmeli; geçmeden asla push etme. Kritik detay: çalışma ağacı kirliyken build, commit'lenmemiş dosyaları da gördüğü için CI'da kırılacak bir commit'i yakalayamayabilir. Bu yüzden build'i **push edilecek commit'in kendisi** üzerinde doğrula (ör. geçici `git worktree add HEAD` + `node_modules` symlink'i ile). Ayrıca kısmi commit atarken değişikliğin bağımlılık kapanışını kontrol et — bir dosyanın kullandığı prop/export başka bir commit'lenmemiş dosyadan geliyorsa onları da aynı commit'e dahil et.
+# Görsel dilin tek kaynağı: docs/tasarim/DESIGN.md
+
+UI'a dokunan her iş (yeni ekran, bileşen, kart, modal, buton, form; mevcut arayüz değişikliği) önce `docs/tasarim/DESIGN.md` okunarak yapılır; renk, yazı tipi, köşe, gölge, boşluk ve tek kaynak bileşenlerin sınıf dizileri oradan **birebir** alınır, "yaklaşık aynısı" yazılmaz. Aşağıdaki rozet/çarpı/CTA kuralları o belgenin özetidir. Genel tasarım katalogları (`ui-ux-pro-max` gibi "50 stil, 97 palet" kütüphaneleri) bu projede kullanılmaz; yön zaten belli. İş bitmeden `pnpm tasarim:denetim` sıfır hata vermeli (`pnpm lint` bunu da koşar); betik `scripts/tasarim-denetim.ts`, kural eklerken DESIGN.md'deki bölüm numarasına atıf yap.
+
# Badge/eyebrow rozetleri: tek kaynak SectionEyebrow
-Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `rounded-full border border-slate-200 bg-white px-3.5 py-1.5 font-bricolage text-xs font-semibold text-primary`; metin büyük-küçük harfli yazılır — uppercase yok). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
+Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold text-primary`; metin büyük-küçük harfli yazılır — uppercase yok). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
# UI tutarlılığı: ortak elemanlar tek kaynaktan
diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md
new file mode 100644
index 0000000..60aa7bc
--- /dev/null
+++ b/docs/tasarim/DESIGN.md
@@ -0,0 +1,181 @@
+# KolayTercih görsel dili (DESIGN.md)
+
+Bu dosya sitenin görsel dilinin **tek yazılı kaynağıdır**. Yeni ekran, bileşen, modal, kart
+ya da buton çizmeden önce okunur; mevcut arayüz değiştirilirken buna bakılır. Değerler koddan
+çıkarılmıştır (`src/app/globals.css`, `src/app/layout.tsx`, `src/components/pixel-decor.tsx`,
+`src/components/ui/*`, `src/app/page.tsx`); kodla çelişirse kod değil, bu dosya düzeltilir ve
+çelişki raporlanır. Kural ihlallerini `pnpm tasarim:denetim` yakalar.
+
+Biçim: Google Stitch'in DESIGN.md düzeni (9 bölüm). Sabit değerler Tailwind sınıfı olarak
+verilir; kodda da sınıf kullanılır, hex/oklch elle yazılmaz.
+
+---
+
+## 1. Görsel tema ve atmosfer
+
+**Bir cümle:** Beyaz, bol nefesli, mavi bilgi + turuncu aksiyon; her yüzeyde küçük bir
+**piksel imzası** (hero'daki dot-matrix Türkiye haritasının dili) dolaşır.
+
+- Zemin her zaman beyaz; koyu zemin yalnızca CTA bandı ve çekmece başlığı gibi tek bir
+ vurgu yüzeyinde (`PixelField` ile).
+- İmza dekoratiftir ama rastgele değildir: deterministik ızgara (hücre 10, nokta 7.4, rx 2),
+ imleç yaklaşınca turuncuya ısınan pikseller (`usePixelHeat`), uzaklaşınca yavaş soğuma.
+- Ton: öğrenciye "sen" diyen, sakin, vaatsiz. Süs yok, gösteriş yok; hareket yalnızca
+ bir şey söylüyorsa var.
+- **Karanlık mod yoktur.** `dark:` sınıfı yazılmaz (`.dark` token'ları shadcn kalıntısıdır).
+
+## 2. Renk paleti ve rolleri
+
+| Rol | Sınıf | Nerede |
+|---|---|---|
+| Bilgi/vurgu mavisi (`primary`) | `text-primary`, `bg-primary/10`, `border-primary/30` | Rozet metni, ikon kutusu, hero'daki italik vurgu, linkler, kart hover kenarlığı |
+| **Aksiyon turuncusu** | `bg-orange-500 hover:bg-orange-600 text-white` | Funnel CTA butonları. Bir ekranda **tek** turuncu buton |
+| Piksel vurgusu | `fill-orange-500` (opaklık 0.55–0.85) | Yalnızca piksel süslerinin "sıcak" noktaları |
+| Başlık metni | `text-slate-900` | h1–h3, kart başlıkları |
+| Gövde metni | `text-slate-600` | Paragraf, açıklama |
+| İkincil metin | `text-slate-500` | Meta bilgi, yardımcı satır |
+| Silik metin | `text-slate-400` | İpucu, devre dışı, placeholder |
+| Kenarlık | `border-slate-200` (landing kartlarında `border-slate-200/70`) | Kart, rozet, çarpı, giriş alanı |
+| İç zemin | `bg-slate-50` | Kartın içindeki ikincil kutu, tablo başlığı |
+| Hover zemini | `hover:bg-slate-100` | Çarpı, ghost buton |
+| Risk: güvenli | `emerald-500` / `text-emerald-600` | **Her zaman "Güvenli" metniyle** |
+| Risk: az riskli | `amber-500` / `text-amber-600` | **Her zaman "Az riskli" metniyle** |
+| Risk: riskli | `red-500` / `text-red-600` | **Her zaman "Riskli" metniyle** |
+| Uyarı kutusu | `border-amber-200 bg-amber-50 text-amber-900` | Bilgilendirme notu |
+| Hata | `text-destructive`, `text-red-600` | Form hatası |
+
+Kurallar:
+- Nötr yalnızca **slate**. `gray`, `zinc`, `neutral`, `stone` yazılmaz.
+- `indigo`, `purple`, `violet`, `fuchsia`, `pink`, `cyan`, `teal`, `lime`, `green`, `yellow`
+ yeni kullanım açmaz. (`bg-violet-50 text-violet-600` tek bir mevcut durum çipidir; yeni yere taşıma.)
+- Gradyan metin (`bg-clip-text text-transparent`) ve parlama gölgesi (`shadow-[0_0_…]`) yok.
+- Hex/oklch değeri sınıf içine yazılmaz (`text-[#…]`); token ya da Tailwind tonu kullanılır.
+ Risk renklerinin SVG karşılığı `src/lib/risk.ts` içindeki `RISK_PIN_RENK`'ten okunur.
+- Renk tek başına anlam taşımaz: risk rengi her zaman metin etiketiyle birlikte gider
+ (`RISK_ETIKET`, `DILIM_ETIKET` — üçüncü dilimin görünen adı "Güvenli").
+
+## 3. Tipografi
+
+Dört yazı tipi, her birinin tek bir işi var:
+
+| Sınıf | Yazı tipi | İş |
+|---|---|---|
+| `font-heading` | Cal Sans | Tüm başlıklar (h1–h3, kart başlığı). Her zaman `font-bold` ile |
+| `font-sans` (varsayılan) | Clarity City 400–800 | Gövde, buton, form, tablo |
+| `font-bricolage` | Bricolage Grotesque (opsz ekseni) | Vurgu: hero'da italik mavi span, küçük etiketler/çipler, sayısal rozetler |
+| `font-mono` | Geist Mono | Yalnızca kod/markdown blokları. Arayüzde kullanılmaz |
+
+Ölçek (kopyala, uydurma):
+
+- Hero h1: `font-heading text-5xl font-bold tracking-[0.015em] sm:text-6xl`; vurgu kelimesi
+ ``
+- Bölüm h2: `font-heading text-3xl font-bold sm:text-4xl` (istenirse `text-slate-900`)
+- Panel/kart h3: `font-heading text-xl font-bold` · liste satırı başlığı: `font-heading text-lg font-bold text-slate-900`
+- Küçük başlık: `font-heading text-base font-bold text-slate-900`
+- Bölüm giriş paragrafı: `max-w-xl text-lg leading-relaxed text-slate-600`
+- Gövde: `text-sm` (tablo, form, kart içi) ya da `text-base leading-relaxed` (açıklama)
+- Etiket/rozet metni: `text-xs font-semibold`
+- Yasak: Inter, Roboto, Arial, sistem fontu, serif, `font-[…]` keyfi font; tek kelimelik
+ büyük harf etiketler (uppercase yok, rozet metni büyük-küçük harfli yazılır).
+
+## 4. Bileşen stilleri (tek kaynaklar)
+
+Bir eleman iki yerde görünüyorsa stili tek kaynaktan gelir. Aşağıdakiler yeniden tasarlanmaz.
+
+### 4.1 Buton — `src/components/ui/button.tsx`
+- Her buton `rounded-full`; `h-9` varsayılan, `h-11`/`h-12` funnel CTA'ları (44 px dokunma hedefi), `size-9` ikon butonu.
+- Odak: `focus-visible:ring-3 focus-visible:ring-ring/50`; basınca `active:translate-y-px`.
+- **Turuncu CTA (kanonik):**
+ ```tsx
+
+ ```
+ Metin önce, ok sonda. Başta ikon yok. `Sparkles` yok. İstenirse `active:scale-[0.97]`.
+- İkincil: `variant="outline"`; sessiz: `variant="ghost"`; link görünümü: `variant="link"`.
+
+### 4.2 Rozet (bölüm başlığı üstündeki kapsül) — `SectionEyebrow`, `src/components/pixel-decor.tsx`
+```tsx
+Nasıl çalışır?
+```
+Sınıfı: `inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold text-primary` + başta `PixelMark`.
+`@/components/ui/badge` **kullanılmaz**; elle pill span yazılmaz. Filtre çipleri ve nav butonları bu kuralın dışındadır (onlar etkileşimlidir).
+
+### 4.3 Modal kapatma çarpısı — `DialogContent` varsayılanı, `src/components/ui/dialog.tsx`
+`absolute top-3 right-3 z-10 flex size-9 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-popover text-slate-500 transition-[background-color,transform] duration-150 hover:bg-slate-100 hover:text-slate-800 active:scale-[0.96]` + `` + `sr-only "Kapat"`.
+Özel yerleşim gerekiyorsa `showCloseButton={false}` ver ve **aynı sınıf setini** kopyala.
+
+### 4.4 Kart ve kutu
+- Landing/öne çıkan kart: `` + sağ üstte ``.
+- Sade kutu (form, panel, liste satırı): `rounded-2xl border border-slate-200 bg-white` (+ `p-5`/`p-6`). Küçük iç kutu: `rounded-xl border border-slate-200 bg-slate-50`. Not kutusu: `rounded-lg`.
+- İkon kutusu: `flex size-11 items-center justify-center rounded-xl bg-primary/10` içinde `size-5 text-primary` ikon.
+- Gölge: `shadow-sm` varsayılan; hover'da `shadow-lg shadow-primary/5`. Başka gölge yok.
+
+### 4.5 Risk çipi / etiketi
+Nokta + metin: `` yanında `text-xs font-semibold text-emerald-600`; metin `RISK_ETIKET`'ten. Renk tek başına asla.
+
+### 4.6 Form
+shadcn `Input`, `Select`, `Textarea`, `Slider`. Etiket her alanda; hata mesajı alanın altında, ne olduğunu ve ne yapılacağını söyler. Sayısal alanlarda uç değerler (0, negatif, 1.000.000 üstü) ele alınır.
+
+### 4.7 İkonlar
+Yalnızca `lucide-react`. Boyut: `size-4` buton/satır içi (varsayılan), `size-5` ikon kutusu, `size-3.5` küçük çip, `size-6` üstü yalnızca boş durum. Dekoratif ikon `aria-hidden`; tek başına ikon buton `aria-label` ya da `sr-only` metin taşır. Emoji ikon olarak kullanılmaz.
+
+## 5. Yerleşim
+
+- Sayfa kabı: `mx-auto max-w-6xl px-4`. Metin sütunu: `max-w-xl` (paragraf) / `max-w-2xl`–`max-w-3xl` (uzun içerik).
+- Landing bölümü: ``; alt sayfalar `py-12`–`py-16`.
+- Bölüm başlık bloğu (kanonik):
+ ```tsx
+
+ Sorun
+
…
+
…
+
+ ```
+ Ardından içerik `mt-12`; kart ızgarası `grid gap-6 md:grid-cols-3` (yalnızca gerçekten üç eşdeğer öğe varsa; üçe tamamlamak için içerik uydurulmaz).
+- Alt sayfa başlığının altında `PagePixelDivider` (`mt-6`/`mt-8`), her sayfada **farklı seed**.
+- Landing bölümleri arasında çizgi yok; `PixelDivider` (`mx-auto w-56`, farklı seed).
+- Boşluk ölçeği: 4 → 6 → 8 → 12 → 16/20 → 24. Ara değer (`mt-7`, `gap-5`) yeni yerde açılmaz.
+- Mobil önce (trafiğin ~%90'ı 375 px): uzun üniversite/program adları `min-w-0` + sarma ya da `truncate`; tablo yatay kaydırmaz, kart olur; sabit alt çubuk klavyeyle çakışmaz; `vh` yerine `dvh`.
+
+## 6. Derinlik ve katman
+
+Derinlik gölgeyle değil **piksel katmanı ve hareket farkıyla** verilir: başlık bloğu gövdeden hafif hızlı akar (`Parallax strength={16}` başlık, `7` içerik, `26` ayraç). Kartlar hover'da 4 px yükselir. Modal arka planı `bg-black/10` + hafif blur. Yığın: içerik < sabit bar < çekmece/modal (`z-50`).
+
+## 7. Yap / Yapma
+
+| Yap | Yapma (AI izi) |
+|---|---|
+| Rozet için `SectionEyebrow` | `Badge` import'u, elle `rounded-full border … px-3.5 py-1.5` span |
+| CTA: metin + sondaki `ArrowRight` | Başta `Sparkles`/yıldız ikonu, "✨" |
+| Nötr = slate; vurgu = primary mavi; aksiyon = orange-500 | `indigo/purple` primary, mor→mavi gradyan, `gray/zinc` nötr |
+| Kart: `rounded-2xl border-slate-200 bg-white shadow-sm` | Her şeyde `rounded-3xl`, camsı `backdrop-blur` kartlar, parlama gölgesi |
+| Hareket: `Reveal` (bölüm girişi), piksel ısısı, `kt-unblur`; `animate-ping` yalnızca "şu anda canlı" noktasında | Her elemanda `fade-up`, `whileHover scale 1.05`, `animate-bounce` |
+| Başlık `font-heading`, vurgu `font-bricolage` | Inter/Roboto/serif, tek kelimelik BÜYÜK HARF etiket |
+| Risk rengi + metin etiketi | Renk tek başına, "yerleşirsin" gibi vaat cümlesi |
+| Üç kart yalnızca üç gerçek öğe varsa | Hero + üç kart iskeleti refleksi |
+| Beyaz zemin, tek koyu vurgu yüzeyi | İstenmemiş karanlık mod, `dark:` sınıfı |
+| Kapatma çarpısı `DialogContent` varsayılanı | Başka boyut/renkte çarpı |
+
+## 8. Duyarlılık
+
+- Kırılma noktaları: 375 (temel), 640 `sm:`, 768 `md:`, 1024 `lg:`. Her bileşen önce 375'te tasarlanır.
+- Dokunma hedefi en az 44 px (`h-11`, `size-11`); satır içi küçük buton `h-9` yalnızca masaüstü tablo aksiyonlarında.
+- Başlık ölçeği bir kademe düşer (`text-3xl` → `sm:text-4xl`), gövde 16 px altına inmez.
+- Modal genişliği `max-w-[calc(100%-2rem)]`; çekmece (`Drawer`) mobilde alttan açılır.
+- `prefers-reduced-motion`: her animasyonun sade karşılığı var (`motion-reduce:animate-none`, `.kt-unblur-sade`).
+
+## 9. Ajan için brief şablonu
+
+Yeni bir UI işi istenince önce şu dört satır doldurulur, sonra kod yazılır:
+
+```
+Amaç: Kim, hangi ekranda, ne yapacak? (ör. veli, /paket, fiyatı karşılaştırıp satın alacak)
+Referans: Sitedeki en yakın mevcut ekran/bileşen (dosya yolu). Yoksa "yok" yaz ve ana sayfa bölüm bloğunu al.
+Tek kaynak: Kullanılacak kanonik parçalar (SectionEyebrow, Button+ArrowRight, Card+PixelCorner, PagePixelDivider…)
+Durumlar: boş / yükleniyor / hata / başarılı / girişsiz / kredisiz — hangileri var?
+```
+
+"Modern", "temiz", "şık" gibi yön belirtmeyen kelimeler kullanılmaz; yön = bu dosya.
+İş bitince: `pnpm tasarim:denetim` sıfır hata + 375 px'te tek bakış (taşma, üst üste binme, dokunma hedefi).
diff --git a/package.json b/package.json
index a015fa9..e6c1739 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "eslint",
+ "lint": "eslint && pnpm tasarim:denetim",
"ingest": "tsx scripts/ingest.ts",
"refresh": "tsx scripts/refresh.ts",
"detay": "tsx scripts/detay.ts",
@@ -19,7 +19,8 @@
"db:push": "drizzle-kit push",
"db:generate": "drizzle-kit generate",
"db:migrate": "node scripts/db-goc.mjs",
- "tadimlik": "tsx scripts/tadimlik-uret.ts"
+ "tadimlik": "tsx scripts/tadimlik-uret.ts",
+ "tasarim:denetim": "tsx scripts/tasarim-denetim.ts"
},
"dependencies": {
"@cds/city": "^1.1.0",
diff --git a/scripts/tasarim-denetim.ts b/scripts/tasarim-denetim.ts
new file mode 100644
index 0000000..27a0e25
--- /dev/null
+++ b/scripts/tasarim-denetim.ts
@@ -0,0 +1,215 @@
+/**
+ * Tasarım dili denetimi — docs/tasarim/DESIGN.md kurallarının makineyle
+ * yakalanabilen kısmı. Ajan/insan fark etmez: `pnpm tasarim:denetim`.
+ *
+ * Çıkış kodu: hata varsa 1, yoksa 0. Uyarılar çıkış kodunu etkilemez.
+ * Kapsam: src/**\/*.tsx. Hariç: src/components/ui (shadcn tabanı) ve
+ * src/components/dev (yalnızca geliştirici paneli) — bazı kurallarda.
+ */
+import { readdirSync, readFileSync, statSync } from "node:fs";
+import { join, relative } from "node:path";
+
+type Seviye = "hata" | "uyari";
+
+type Bulgu = {
+ dosya: string;
+ satir: number;
+ kural: string;
+ seviye: Seviye;
+ mesaj: string;
+ parca: string;
+};
+
+type Kural = {
+ ad: string;
+ seviye: Seviye;
+ mesaj: string;
+ /** ui/dev klasörleri de taransın mı */
+ uiDahil?: boolean;
+ /** Tam yolu eşleşen dosyalar kuraldan muaf */
+ muaf?: RegExp;
+ bul: (icerik: string) => Array<{ index: number; parca: string }>;
+};
+
+const KOK = process.cwd();
+const KAYNAK = join(KOK, "src");
+const UI_VEYA_DEV = /src\/components\/(ui|dev)\//;
+
+function tsxDosyalari(dizin: string): string[] {
+ const sonuc: string[] = [];
+ for (const ad of readdirSync(dizin)) {
+ const yol = join(dizin, ad);
+ if (statSync(yol).isDirectory()) sonuc.push(...tsxDosyalari(yol));
+ else if (yol.endsWith(".tsx")) sonuc.push(yol);
+ }
+ return sonuc;
+}
+
+function satirNo(icerik: string, index: number): number {
+ let n = 1;
+ for (let i = 0; i < index && i < icerik.length; i++) if (icerik[i] === "\n") n++;
+ return n;
+}
+
+function satirParcasi(icerik: string, index: number): string {
+ const bas = icerik.lastIndexOf("\n", index) + 1;
+ let son = icerik.indexOf("\n", index);
+ if (son === -1) son = icerik.length;
+ return icerik.slice(bas, son).trim().slice(0, 110);
+}
+
+/** Basit regex kuralı: her eşleşme bir bulgu. */
+function regexKurali(re: RegExp) {
+ return (icerik: string) => {
+ const g = new RegExp(re.source, re.flags.includes("g") ? re.flags : re.flags + "g");
+ const sonuc: Array<{ index: number; parca: string }> = [];
+ for (const m of icerik.matchAll(g)) sonuc.push({ index: m.index ?? 0, parca: m[0] });
+ return sonuc;
+ };
+}
+
+/** … bloklarının içinde `ic` deseni varsa bulgu. */
+function blokIcinde(etiketler: string[], ic: RegExp) {
+ return (icerik: string) => {
+ const sonuc: Array<{ index: number; parca: string }> = [];
+ for (const etiket of etiketler) {
+ const blok = new RegExp(`<${etiket}\\b[\\s\\S]*?<\\/${etiket}>`, "g");
+ for (const m of icerik.matchAll(blok)) {
+ const icM = ic.exec(m[0]);
+ if (icM) sonuc.push({ index: (m.index ?? 0) + icM.index, parca: icM[0] });
+ }
+ }
+ return sonuc;
+ };
+}
+
+const RENK_ONEK = "(?:bg|text|border|ring|fill|stroke|from|to|via|divide|outline|placeholder|decoration|accent|caret|shadow)";
+
+const KURALLAR: Kural[] = [
+ {
+ ad: "badge-import",
+ seviye: "hata",
+ mesaj: "Rozet için @/components/ui/badge değil SectionEyebrow kullanılır (DESIGN.md §4.2)",
+ bul: regexKurali(/from\s+["']@\/components\/ui\/badge["']/),
+ },
+ {
+ ad: "elle-rozet",
+ seviye: "hata",
+ mesaj: "Elle yazılmış rozet; SectionEyebrow'u içe aktar (DESIGN.md §4.2)",
+ muaf: /src\/components\/pixel-decor\.tsx$/,
+ bul: regexKurali(/rounded-full border border-slate-200 bg-white px-3\.5 py-1\.5/),
+ },
+ {
+ ad: "cta-yildiz",
+ seviye: "hata",
+ mesaj: "CTA butonunda Sparkles/yıldız ikonu olmaz; metin + sondaki ArrowRight (DESIGN.md §4.1)",
+ bul: blokIcinde(["Button", "Link"], / {
+ const m = /showCloseButton=\{false\}/.exec(icerik);
+ if (!m) return [];
+ const kanonik =
+ /size-9 cursor-pointer items-center justify-center rounded-full border border-slate-200/.test(icerik);
+ return kanonik ? [] : [{ index: m.index, parca: m[0] }];
+ },
+ },
+ {
+ ad: "yabanci-font",
+ seviye: "hata",
+ mesaj: "Yalnızca font-heading / font-sans / font-bricolage / font-mono (DESIGN.md §3)",
+ bul: regexKurali(/\bfont-(?:serif|\[)|["'](?:Inter|Roboto|Arial|Helvetica)["']/),
+ },
+ {
+ ad: "dark-sinif",
+ seviye: "uyari",
+ mesaj: "Üründe karanlık mod yok; dark: sınıfı gereksiz (DESIGN.md §1)",
+ bul: regexKurali(/(?<=[\s"'`])dark:[a-z]/),
+ },
+ {
+ ad: "hex-renk",
+ seviye: "uyari",
+ mesaj: "Sınıf içinde hex renk; token ya da Tailwind tonu kullan (DESIGN.md §2)",
+ bul: regexKurali(/\[#[0-9a-fA-F]{3,8}\]/),
+ },
+ {
+ ad: "emoji-ikon",
+ seviye: "uyari",
+ mesaj: "Emoji ikon olarak kullanılmaz; lucide ikon (DESIGN.md §4.7)",
+ bul: (icerik) =>
+ // Yorum satırındaki işaretler (// ✗ gibi) ikon değildir
+ regexKurali(/[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]\uFE0F?/u)(icerik).filter(
+ (e) => !/^(?:\/\/|\*|\/\*)/.test(satirParcasi(icerik, e.index)),
+ ),
+ },
+];
+
+const bulgular: Bulgu[] = [];
+for (const yol of tsxDosyalari(KAYNAK)) {
+ const gorece = relative(KOK, yol);
+ const icerik = readFileSync(yol, "utf8");
+ for (const k of KURALLAR) {
+ if (!k.uiDahil && UI_VEYA_DEV.test(gorece)) continue;
+ if (k.muaf && k.muaf.test(gorece)) continue;
+ for (const e of k.bul(icerik)) {
+ bulgular.push({
+ dosya: gorece,
+ satir: satirNo(icerik, e.index),
+ kural: k.ad,
+ seviye: k.seviye,
+ mesaj: k.mesaj,
+ parca: satirParcasi(icerik, e.index),
+ });
+ }
+ }
+}
+
+bulgular.sort((a, b) =>
+ a.seviye !== b.seviye ? (a.seviye === "hata" ? -1 : 1) : a.dosya.localeCompare(b.dosya) || a.satir - b.satir,
+);
+
+for (const b of bulgular) {
+ const etiket = b.seviye === "hata" ? "HATA " : "uyarı";
+ console.log(`${b.dosya}:${b.satir} [${etiket}] ${b.kural} — ${b.mesaj}\n ${b.parca}`);
+}
+
+const hata = bulgular.filter((b) => b.seviye === "hata").length;
+const uyari = bulgular.length - hata;
+console.log(`\nTasarım denetimi: ${hata} hata, ${uyari} uyarı (${KURALLAR.length} kural, docs/tasarim/DESIGN.md)`);
+process.exit(hata > 0 ? 1 : 0);
diff --git a/src/components/arama-funnel-karti.tsx b/src/components/arama-funnel-karti.tsx
index 6c3b9b7..9979195 100644
--- a/src/components/arama-funnel-karti.tsx
+++ b/src/components/arama-funnel-karti.tsx
@@ -122,7 +122,7 @@ export function AramaFunnelKarti({ onSec }: { onSec: () => void }) {
key={etiket}
className="inline-flex items-center gap-1.5 text-xs font-medium text-slate-200"
>
-
+
{etiket}
))}