# 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).