# 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`, `src/features/katalog/components/universite-icerik.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. **Canlı referans ekran:** `/universite/ankara-universitesi` (23 Eyl 2026'da Bilal'le birlikte bu belgedeki "şişko ve sade" dile göre baştan tasarlandı). Bir kural belirsiz kalırsa o sayfanın kodu (`universite-icerik.tsx`, `universite-program-tablosu.tsx`, `akademik-ayrinti.tsx`, `nav-baslik.tsx`) ölçüdür. Site genelinde dönüşüm bu ekranı örnek alır. --- ## 1. Görsel tema ve atmosfer **Bir cümle:** Beyaz, bol nefesli, **şişko ve sade** — kullanıcıya "basit bir şey kullanıyorum" hissi veren, Apple uygulamaları kadar kolay anlaşılır bir arayüz; mavi bilgi + turuncu aksiyon; her yüzeyde küçük bir **piksel imzası** (hero'daki dot-matrix Türkiye haritasının ve logodaki üç karenin dili) dolaşır. ### 1.1 Temel his: şişko ve sade Referans: header (`src/components/site-header.tsx` ve içindeki arama/kullanıcı hapları), hero ve üniversite sayfası. Bu hissi veren şeyler, ekrandan bağımsız: - **İri dokunma alanı.** Butonlar ve haplar 44–48 px (`h-11`/`h-12`), tam yuvarlak. - **İri yazı, az eleman.** Bir ekranda az şey var ve her biri büyük. Küçük gri yazı yığını yok. - **Sayı kahramandır.** Bir veri gösteriliyorsa sayı kartın en büyük öğesidir; etiket ve açıklama onun altında ikinci planda. - **Sık bakılan önde, ayrıntı bir dokunuş derinde** (Apple'ın "önce ortak yol, gelişmiş seçenekler bir seviye aşağıda" ilkesi). Sayfada en çok dört özet sayı; fazlası ayrıntı satırının açtığı alt sayfaya (§4.10). - **Nefes alanı korunur.** Harita gibi görsel dinlenme alanları küçültülmez, sıkıştırılmaz, bilgiyle doldurulmaz. Sadeleştirmek = bu alanları silmek değil, etraflarındaki kalabalığı azaltmaktır. - **Verimli ama havadar.** Alt sayfa ve paneller dikine uzamaz; ilişkili öğeler yan yana dizilir, aralarında boşluk kalır (§5.3). - **Doğal duruş.** Eşit, hizalı ızgaralar yerine logodaki üç kare gibi hafif kaymış yerleşim (§4.11). Her şey birbirine cetvelle hizalıysa ekran "tablo" gibi durur. - **Basınca tepki.** Her tıklanabilir öğe basınca hafifçe küçülür (`active:scale-[0.97]`, geniş satırlarda `[0.99]`), üzerine gelince turuncuya döner (§2.1). ### 1.2 Genel kurallar - Açık temada zemin beyaz (koyu temada karşılığı, §2.3); koyu zemin yalnızca CTA bandı ve çekmece başlığı gibi tek bir vurgu yüzeyinde (`PixelMasonry` ile: büyüklü küçüklü, hafif kaymış kareler). - İ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. Piksel **veri taşıyorsa** (ör. `PixelSira`) kalır; iki bölüm arasına **süs olarak** konmuş piksel ayraç alt sayfalarda ve kompakt panellerde kullanılmaz. - Ton: öğrenciye "sen" diyen, sakin, vaatsiz. Süs yok, gösteriş yok; hareket yalnızca bir şey söylüyorsa var. - **Karanlık mod token'la çalışır, `dark:` sınıfı yazılmaz** (§2.3). Bileşen tek bir sınıf dizisiyle yazılır; iki temada doğru görünmesi palet token'larının işidir. ## 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, linklerin durağan rengi | | **Aksiyon turuncusu** | `bg-orange-500 hover:bg-orange-600 text-white` | Funnel CTA butonları. Bir ekranda **tek** turuncu buton | | **Hover turuncusu** | `hover:text-orange-500`, `hover:border-orange-500`, `hover:bg-orange-50/60`, `group-hover:text-orange-500` | Link, kart, satır ve ikincil butonların üzerine gelme hâli (§2.1); liste satırı adı hariç (mavi kalır) | | 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ı, iri sayılar | | Gövde metni | `text-slate-600` | Paragraf, açıklama | | İkincil metin | `text-slate-500` | Meta bilgi, yardımcı satır, kart açıklaması | | Silik metin | `text-slate-400` | İpucu, devre dışı, placeholder, sayının yanındaki birim (`/ 198`) | | 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ığı | | Nötr hover zemini | `hover:bg-slate-100` | Yalnız kapatma çarpısı ve 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 | | Gösterge karesi | Dolu zemin + beyaz yazı: `bg-orange-500`, `bg-primary`, `bg-indigo-500`, `bg-green-600`; `rounded-3xl` | Yalnız sayı gösterge kareleri (§4.11). Renk sempati katar, anlam taşımaz: etiket her karede yazılı | | Hata | `text-destructive`, `text-red-600` | Form hatası | ### 2.1 Hover: tek turuncu Bilal'in kararı (23 Eyl 2026): üzerine gelme hâlinde **sitenin turuncusu** kullanılır ve bu turuncu **tek tondur: `orange-500`** — CTA butonunun turuncusuyla birebir aynı değer. - Link / metin: `transition-colors hover:text-orange-500` (altı çizili linklerde `hover:underline` kalır). - Tıklanabilir kart / satır: `hover:border-orange-500 hover:bg-orange-50/60`; içindeki iri sayı ya da başlık `group-hover:text-orange-500`; sağdaki ok `group-hover:translate-x-0.5 group-hover:text-orange-500`. - İkincil (outline) buton: `hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500`. - **İstisna — liste satırındaki adlar mavi kalır:** program/üniversite listelerinde satırın adı (bölüm ya da üniversite sayfasına giden link) `hover:text-primary hover:underline`. Bilal'in kararı (23 Eyl 2026): uzun bir listede imleç satırdan satıra geçerken yanıp sönen turuncu adlar yorucu; mavi sakin kalır. Satırın butonları ve listedeki diğer linkler §2.1'e uyar. - **Yapılmaz:** hover'da `text-primary`/`border-primary` (eski mavi hover — yukarıdaki istisna dışında), `orange-600` yazı, `orange-300` kenarlık — aynı ekranda iki turuncu tonu göze "farklı turuncu" diye batar. Tek istisna: turuncu CTA'nın kendi zemininin hover'ı (`hover:bg-orange-600`), kanonik. - Geçiş notu: kodda hâlâ `hover:text-primary` / `hover:border-primary/30` kullanan yerler var (landing kartı dahil); tarama sırasında bu kurala çevrilir. Denetim bunları `mavi-hover` uyarısıyla listeler; liste satırı adındaki uyarı istisnadır, dokunulmaz. ### 2.2 Palet 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. Tek istisna "Gösterge karesi" satırındaki dolu `bg-indigo-500` ve `bg-green-600` zeminleri (Bilal'in kararı, 23 Eyl 2026); yazı, kenarlık ya da başka ton/opaklıkta bu renkler yine yasak. (`bg-violet-50 text-violet-600` tek bir mevcut durum çipidir; yeni yere taşıma — üniversite sayfasında "Vakıf" çipi bu yüzden hap + ikonla değiştirildi, §4.12.) - 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"). Tür ayrımı (devlet / vakıf) da renkle değil ikon + metinle yapılır. - Renkli dolu zeminde beyaz yazı: turuncu ve yeşil zeminde küçük beyaz yazı WCAG AA'nın altında kalır (sitenin turuncu CTA'sı da aynı ikiliyi kullanır). Bu zeminlerde etiket `font-bold`, sayı en az `text-3xl`; uzun metin konmaz. ### 2.3 Karanlık mod Bilal'in kararı (4 Eki 2026): sitede açık / koyu / sistem teması var; varsayılan açık. Seçici `src/components/tema-secici.tsx` (footer'da), sağlayıcı `src/components/tema-saglayici.tsx` (`next-themes`, ``). Renklerin tek kaynağı `src/app/globals.css` içindeki `.dark` bloğu. **Nasıl çalışır:** bileşenlere `dark:` yazılmaz; palet token'ları çevrilir. | Açık temadaki sınıf | Koyu temada ne olur | |---|---| | `bg-card` (yüzey: kart, hap, form alanı, modal, çekmece) | Koyu yüzey (`#111826`) | | `bg-slate-50` (gövde zemini, kart içi ikincil kutu) | En koyu zemin (`#080e19`) | | `slate-100…900` (metin, kenarlık, hover zemini) | Ölçek ters döner: `text-slate-900` açık başlık, `border-slate-200` koyu çizgi | | `bg-orange-50/60`, `bg-amber-50`, `bg-emerald-50`, `bg-red-50`, `border-*-200` | Aynı rengin koyu tonu | | `text-amber-900`, `text-emerald-800`, `text-red-600` gibi koyu renkli metin | Aynı rengin açık tonu | | `text-white`, `bg-orange-500`, `bg-primary`, `bg-emerald-500`, `bg-red-500` | **Değişmez** | **Kurallar:** - **Yüzey `bg-card`'dır, `bg-white` değil.** `bg-white` koyu temada da beyaz kalır; yalnız gerçekten beyaz kalması gereken yerde yazılır: üniversite logosu karosu (`uni-logo.tsx`), kaydırıcı topuzu, rehber kapak görseli, renkli dolu zemin üstündeki `bg-white/15` ikon kutusu. - **Koyu hap** (`bg-slate-900`: "Giriş yap", "Ara", sekme göstergesi, toast düğmesi) yazısını `text-slate-50` ile alır, `text-white` ile değil: koyu temada hap açığa, yazı koyuya döner. - **Koyu vurgu yüzeyi** (`bg-slate-950`: `PikselCtaYuzeyi`, `AramaFunnelKarti`) `kt-koyu-yuzey` sınıfını taşır; iki temada koyu kalır, içindeki açık slate metinler çevrilmez. `slate-950` metin rengi olarak kullanılmaz. - **SVG ve satır içi stilde** sabit renk yerine değişken: `var(--card)`, `var(--color-slate-200)`, `var(--kt-harita-dolu)`. Risk renkleri (`RISK_RENK`) ve logo renkleri iki temada aynıdır. - **Açık kalan adalar:** el çizimi şemalar (`kt-sema-kagit`) ve iyzico logo bandı (`kt-acik-logo`; footer, paket ve ödeme sayfası) koyu temada beyaz kâğıt/hap üstünde durur; tek renk koyu logo (URAP) `kt-koyu-cevir` ile açığa çevrilir; yazdırma çıktısı her zaman açıktır (`.dark` bloğu `@media screen` içinde). - Yeni bir renk tonu ilk kez kullanılıyorsa (`bg-sky-50` gibi) `.dark` bloğuna karşılığı eklenir; eklenmezse koyu temada açık renkli bir leke olarak kalır. ## 3. Tipografi Dört arayüz yazı tipi (+ yalnız Kur'an metni için bir Arapça 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ığı) ve **iri sayılar**. 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, logo yazısı, üst çubuktaki sayfa adı (§4.14), küçük etiketler/çipler | | `font-mono` | Geist Mono | Yalnızca kod/markdown blokları. Arayüzde kullanılmaz | | `amiriQuran.className` (`site-footer.tsx`) | Amiri Quran | Yalnızca Kur'an metni: footer'daki âyet (`lang="ar" dir="rtl"`). Arayüz metninde kullanılmaz; önceden yüklenmez, Arapça alt kümesi âyet çizilirken iner. Aşağıdaki "serif yasak" kuralı Latin arayüz metni içindir | Ölçek (kopyala, uydurma): - Hero h1: `font-heading text-5xl font-bold tracking-[0.015em] sm:text-6xl`; vurgu kelimesi `` - Alt sayfa h1 (katalog, rehber): `font-heading text-3xl font-bold leading-tight text-slate-900 sm:text-5xl` - Bölüm h2: `font-heading text-3xl font-bold sm:text-4xl` (istenirse `text-slate-900`); alt sayfada liste bölümü başlığı `font-heading text-2xl font-bold text-slate-900 sm:text-3xl` - Panel/kart h3: `font-heading text-xl font-bold` · grup başlığı (fakülte vb.): `font-heading text-xl font-bold text-slate-900 sm:text-2xl` - 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` - Sayfa özet paragrafı: `text-base leading-relaxed text-slate-600 sm:text-lg` - Gövde: `text-base leading-relaxed` (açıklama, liste satırı adı) ya da `text-sm` (kart açıklaması, tablo hücresi, meta) - Etiket/rozet metni: `text-xs font-semibold` **İri sayı ölçeği** (§1.1 "sayı kahramandır"): | Yer | Sınıf | |---|---| | Özet kartı sayısı | `font-heading text-4xl font-bold leading-none tracking-tight text-slate-900 sm:text-5xl` | | Gösterge karesi, büyük | `font-heading text-5xl font-bold leading-none tracking-tight` | | Gösterge karesi, orta | `font-heading text-3xl font-bold leading-none` | | Sayının birimi (`/ 198`, `kişi`) | `text-base font-semibold text-slate-400` (renkli zeminde `text-white/80`) | **Alt sınırlar:** - Gövde metni telefonda 16 px'in (`text-base`) altına inmez; `text-sm` yalnız ikincil bilgide, `text-xs` yalnız ince yazıda (kaynak satırı, eksen etiketi, çip). - **12 px altı yok:** `text-[10px]`, `text-[11px]` yazılmaz (denetim uyarır). - **Büyük harfli minik etiket yok:** `uppercase tracking-wide text-xs` kalıbı ("PROGRAM", "TOPLAM KONTENJAN") yazılmaz; etiket büyük-küçük harfli, `text-sm font-semibold`. - **İri sayıda `tabular-nums` yok:** Cal Sans'ta sabit genişlikli rakam "daktilo" gibi aralıklı durur ("13.88 9"). `tabular-nums` yalnız `font-sans` tablo sütunlarında. - Yasak: Inter, Roboto, Arial, sistem fontu, serif, `font-[…]` keyfi font. ## 4. Bileşen stilleri (tek kaynaklar) Bir eleman iki yerde görünüyorsa stili tek kaynaktan gelir. Aşağıdakiler yeniden tasarlanmaz. §4.8–§4.15 üniversite sayfasında doğdu; ikinci bir ekranda gerektiğinde **kopyalanmaz**, ortak bir dosyaya (`src/components/…`) çıkarılıp iki yer de oradan kullanır. ### 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 gezinme butonu** ("Tüm sıralamayı gör →"): ```tsx ``` - 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-card 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, nav butonları ve kimlik hapları (§4.12) bu kuralın dışındadır. Rozet **sayfa** bölüm başlıklarının üstündedir; çekmece ve modal başlıklarında kullanılmaz (§4.10, Bilal 24 Eyl 2026). ### 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. Alt sayfada (`AltSayfa`) aynı sınıf seti `AltSayfaKapat` üstünde kullanılır (§4.10). ### 4.4 Kart ve kutu - Landing/öne çıkan kart = **sahne kartı** (§4.31): `flex h-full flex-col overflow-hidden rounded-2xl border border-slate-200/70 bg-card shadow-sm transition-[translate,border-color,box-shadow] duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5`; üstte piksel sahne, altında başlık + metin. Eski hâli (ikon kutusu + başlık + metin + köşede `PixelCorner`) 7 Eki 2026'da kaldırıldı (Bilal: "sıkıcı kart tasarımları"); yeni yerde yazılmaz. `PixelCorner` giriş/doğrulama kartlarının köşe süsü olarak kalır. - Sade kutu (form, panel, liste satırı): `rounded-2xl border border-slate-200 bg-card` (+ `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. Kart içinde sayının yanında küçük hâli: `size-8 … sm:size-10` + `size-4 sm:size-5` ikon (§4.8). - Gölge: `shadow-sm` varsayılan; hover'da `shadow-lg shadow-orange-500/5`. Başka gölge yok. ### 4.5 Risk çipi / etiketi — `RiskEtiketi`, `src/components/risk-etiketi.tsx` Tablolar, çekmece ve rapor listesi `` kullanır; elle yazılmaz. Nokta + metin: `` yanında `text-xs font-semibold text-emerald-600`; metin `RISK_ETIKET`'ten. Renk tek başına asla. ### 4.6 Form alanı — `Input`, `Select`, `Textarea` (`src/components/ui/`) Form alanı da bir **hap**tır: üst çubuktaki arama/kullanıcı haplarıyla aynı kalıp (48 px, tam yuvarlak, slate-200 kenarlık, 16 px yazı). shadcn'in ince varsayılanı (`h-8 rounded-lg border-input md:text-sm`) bu projede yoktur; temel bileşenler 24 Eyl 2026'da bu dile çevrildi. - **Metin alanı (`Input`)**: `h-12 w-full rounded-full border border-slate-200 bg-card px-5 text-base text-slate-900 placeholder:text-slate-400`; hover `border-slate-300`; odak `border-primary ring-3 ring-ring/50`; hata (`aria-invalid`) `border-red-500 ring-3 ring-red-500/20`; devre dışı `bg-slate-50 opacity-50`. `md:text-sm` yok — gövde 16 px altına inmez (§3) ve iOS odakta yakınlaştırmaz. Kullanım yerinde yükseklik/köşe/zemin **yazılmaz** (`className` yalnız yerleşim için: `sm:flex-1`, `pl-12`). Tek istisna hero: telefonda bir kademe iri, `h-14 text-lg sm:h-12 sm:text-base`. - **Başta ikon** (sıralama alanındaki kupa): kapsayıcı `relative`, ikon `pointer-events-none absolute left-5 top-1/2 size-4 -translate-y-1/2 text-slate-400`, alan `pl-12`. - **Seçim (`SelectTrigger`)**: aynı hap — `h-12 pl-5 pr-4 text-base`, ok `text-slate-400`; `size="sm"` → `h-9 px-4 text-sm` (yalnız masaüstü tablo aksiyonu, §8). Açılan liste `rounded-2xl border border-slate-200 bg-card p-1.5 shadow-lg`; satır `rounded-full py-2 pl-4 pr-9 text-base`, klavye/odak `bg-slate-100`, seçili işareti `text-primary`. - **Çok satır (`Textarea`)**: hap değil sade kutu (§4.4): `min-h-24 rounded-2xl border border-slate-200 bg-card px-5 py-3 text-base`; hover/odak/hata metin alanıyla aynı. Sohbet kutusu (`prompt-input.tsx`) kenarlıksız ve şeffaf üstüne yazar; tek istisna. - **Kenarlıksız ham ``** yalnız kendi hap kabının içinde: il arama (`sihirbaz-adimlar.tsx`, `h-11 rounded-full border-slate-200` kap) ve katalog arama modalı (üst şeritte `h-16`). Kenarlıklı ham input yazılmaz; `Input` kullanılır. - Etiket her alanda: görünür `text-sm font-semibold text-slate-700` ya da `sr-only`. Hata mesajı alanın altında `role="alert"` + `text-sm font-medium text-red-600`; ne olduğunu ve ne yapılacağını söyler (§10.4). Sayısal alanlarda uç değerler (0, negatif, 1.000.000 üstü) ele alınır. - Alan + buton yan yana: `flex flex-col gap-3 sm:flex-row`; buton `h-12` (§4.1 `size="lg"`), alan `sm:flex-1`. Telefonda alt alta, ikisi de tam genişlik. - Denetim: `ince-form-alani` (hata) — `Input`/`SelectTrigger`/`Textarea` üstüne `h-7`–`h-10`, `rounded-sm/md/lg/xl`, `bg-background`/`border-input` yazılmış; `ham-input` (uyarı) — kenarlıklı ham ``. ### 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. ### 4.8 Özet kartı — `OzetKart`, `src/components/ozet-kart.tsx` Apple Fitness özet kartının sitenin ölçüleriyle hâli. Sayfada **en çok dört** tane (harita yanındaki 2×2). ``` ┌──────────────────────┐ │ 13.889 [👥] │ ← sayı solda, iri; ikon kutusu sağda, küçük │ Kontenjan │ ← başlık text-base font-semibold text-slate-900 │ 2026 toplamı │ ← açıklama text-sm text-slate-500, tek satır └──────────────────────┘ ``` - Kap: `flex flex-col rounded-2xl border border-slate-200 bg-card p-4 sm:p-5`. - Sayı satırı: `flex items-start justify-between gap-1.5`; sayı §3 "Özet kartı sayısı"; ikon kutusu `flex size-8 shrink-0 items-center justify-center rounded-xl bg-primary/10 sm:size-10`. - `dl` anlamı için `dt` (başlık) DOM'da önce gelir, görsel sıra `order-*` ile kurulur. - Telefonda kart iç genişliği ~131 px: en uzun sayı ("13.889", 36 px'te ~90 px) + 32 px ikon sığar. Daha uzun sayı gelecekse önce ölç (§9.2), sonra yaz. Ölçülen sınır: 36 px'te "1.618.988" 123 px — ikonun altına girer. 6–7 haneli sayı birimle kısalır: 245.300 → `245` + birim `bin`, 1.618.988 → `1,62` + birim `milyon` (bölüm sayfasındaki `kartSayisi`). - Kullanıldığı yerler: üniversite ve bölüm sayfası. **Kartlar sayım değil cevaptır** (Bilal, 6 Eki 2026: "program/kontenjan/devlet/vakıf adedi ilgi çekmiyor, öğrencinin işine yaramıyor"): öğrencinin sorusu "girmesi ne kadar zor, yıllar içinde nereye gidiyor, boş kalıyor mu". Adetler özet paragrafta kalır, karta çıkmaz. Hesap `src/lib/taban-ozeti.ts` (KKTC uyruklu, açıköğretim ve uzaktan satırları yelpazeye girmez; doluluk bütün satırlar. KKTC üniversitesinin kendi sayfasında kıyas evreni kurumun kendisidir: il/kampüs dışlaması kalkar, ad kuralı kalır — yoksa DAÜ gibi kurumlarda kartlar "henüz taban oluşmadı" der, 6 Eki 2026 QA). Doluluk yüzdesi boş kontenjan varken 100'e yuvarlanmaz, en çok 99 yazar. - **Bölüm** (`grid grid-cols-2 gap-4 lg:grid-cols-3`, telefonda tek kalan üçüncü kart `col-span-2`; haritası yok): En yüksek taban (sıra + üniversite adı linkli) · En düşük taban (ücretsiz devlet örgün programı ≥3 ise devlet kümesinde, açıklama "Devlet · Bingöl Üni. · 2026 taban sırası"; etiket "Devlette en düşük" 131 px'te iki satıra kırıldığı için kısa tutulur) · Boş kontenjan. Orta taban kartı 6 Eki 2026'da kaldırıldı (Bilal: fazla geldi); hesabı `taban-ozeti.ts`'te duruyor. Etiketlerde "en seçici" ve "en geniş kapı" denmez ("En yüksek / En düşük taban" öğrencinin kendi dili); kullanıcıya dönük metinde "koltuk" değil **kontenjan** yazılır. Kartın içinde piksel çizgi/seri **yok** (Bilal, 6 Eki 2026: "çok boğdu"); yön kelimesi yeter. - **Üniversite** (harita yanındaki 2×2): En yüksek taban (sıra + bölüm adı linkli) · En düşük taban (aynı biçim) · Doluluk (`%97`) · Türkiye sırası (URAP; listede olmayan kurumda Kontenjan). - Sayının yanındaki ad (`KartBaglantisi`, `taban-karti.tsx`) karşı sayfaya gider: bölümde üniversiteye, üniversitede bölüme; stil kaynak linkiyle aynı (`font-medium text-primary hover:text-orange-500 hover:underline`). Üniversite adı kısaltılır ("Koç Üni.", "… MYO"). - Yıl yıl ayrıntı çekmecesi ("Yıllara göre taban ›": tablo + kayıtlı sıraya göre "senin sıran nereye yetti") 6 Eki 2026'da Bilal'in isteğiyle **şimdilik kaldırıldı**; kartların altında yalnız eski ayrıntı satırı (Akademik göstergeler / Mezun istihdamı) durur. Geri gelirse sayı dili konuşma Türkçesi olur: "sıranın yettiği program" — "yerleşirsin" denmez. - Tıklanabilir kart (ör. Türkiye sırası → sıralama sayfası): kartın tamamı link olur (`after:absolute after:inset-0` gerilmiş link), iç kaynak linki `relative z-10` ile üstte kalır; hover §2.1. - Açıklama altında veri görseli gerekiyorsa (ör. `PixelSira`) `ek` yuvasına konur. ### 4.9 Ayrıntı satırı — `AkademikAyrinti`, `akademik-ayrinti.tsx` Özet kartlarının altında "fazlası burada" satırı (Apple Sağlık'taki "Tüm verileri göster"). - `mt-4 flex w-full items-center gap-4 rounded-2xl border border-slate-200 bg-card p-4 sm:p-5` + hover §2.1 + `active:scale-[0.99]`. - Solda ikon kutusu (`size-11`), ortada iki satır: başlık `font-heading text-lg font-bold`, altında **önizleme** `truncate text-sm text-slate-500` — içeride ne olduğunu söyler ("Hoca başına 25 öğrenci"), boş "Daha fazla" yazmaz. Sağda `ChevronRight size-5 text-slate-400`. - Dokununca alt sayfa açılır (§4.10). - Bir sayfada birden çok satır alt alta durabilir; her biri `mt-4`, kartlara en yakın konu en üstte. Bugün her sayfada tek satır var (üniversite: "Akademik göstergeler"; bölüm: "Mezun istihdamı"). ### 4.10 Alt sayfa — `AltSayfa`, `src/components/ui/alt-sayfa.tsx` **Kabuk tek kaynak** (Bilal, 7 Eki 2026: "bottom drawer yerine bottom sheet"): eski vaul çekmecesi kaldırıldı; yerinde Arc UI "Bottom sheet"ten taşınan `AltSayfa` var. Sayfa parmağı birebir izler: tutamaçtan, başlık alanından (`AltSayfaSurukle`) ya da içerik en üstteyken gövdeden aşağı çekince kapanır; yukarı çekince lastik gibi direnir; bırakınca hızını taşıyarak durağına oturur; kapanırken yakalanıp geri açılabilir. Perde zamanlayıcıyla değil sayfanın konumuyla koyulaşır. Parçalar: `AltSayfa` (kök) · `AltSayfaTetik` · `AltSayfaIcerik` (perde + yüzey + tutamaç) · `AltSayfaGovde` (**kaydırılan alan mutlaka budur**; sayfa onun kaydırmasıyla el sıkışır) · `AltSayfaSurukle` (kaydırmayan başlık alanı) · `AltSayfaBaslik` / `AltSayfaAciklama` · `AltSayfaKapat`. Yüzey sınıfı bileşenin içindedir (`rounded-t-3xl border border-b-0 border-slate-200 bg-card shadow-2xl sm:max-w-2xl`, tavan `92dvh`); kullanım yerinde kap sınıfı **yazılmaz**. Boy içeriğe göredir. `duraklar` (ekran yüksekliğinin oranı) yalnız uzun, kaydırılan içerikte verilir: program ayrıntısı `[0.6, 0.92]` ile %60'ta açılır, yukarı çekince ya da kaydırınca tam boya çıkar (§4.19). İçinde kendi sürüklemesi olan öğe (sıralama tutamağı) `data-alt-sayfa-yoksay` alır. Bildirimdeki düğmeye basmak sayfayı kapatmaz. Hareketi azalt: kayma yok, yalnız opaklık. Ayrıntı her zaman **alttan açılan sayfada** (`AltSayfa`, tutamaçlı); ekranın ortasında açılan modal değil. Çekmece kabı ve çarpı `cta-sira-form.tsx`'teki çekmeceyle birebir: `` + §4.3 çarpısı + ``. İçerik kuralları (Apple ayrıntı sayfası): - **Her ekranda ortalı:** başlık `px-10 text-center font-heading text-2xl font-bold`, altında bağlam (`text-sm text-slate-500`, ör. üniversite adı). - **Kart yok.** Çekmece zaten bir yüzey; içine çerçeveli kart koymak "pencere içinde pencere" olur. Gösterge kareleri (§4.11) bu kuralın istisnası değildir — onlar çerçevesiz, dolu renk. - **Süs ayraç yok.** Bölümler arasına piksel ayraç ya da çizgi konmaz; ayrım boşlukla ve yan yana dizilişle yapılır. Yalnız en alttaki kaynak satırı `border-t border-slate-100`. - **Tek ekrana sığar:** 375×812'de kaydırmasız. Dikine uzuyorsa öğeler yan yana dizilir, kareler kısaltılır, not kısaltılır — içerik silinmez (§9.2 ölçüm). - Sıra: gösterge kareleri → tek cümlelik not (`text-sm text-slate-500`) → ikincil buton (§4.1) → kaynaklar (logo solda, `text-xs` iki satır). - **Liste çekmecesi** (`liste-cekmecesi.tsx`, 24 Eyl 2026): başlık aynı düzende (temizle düğmesi çarpıyla aynı sınıf setinde solda). Satırlar çerçeveli kart değil, düz liste satırı (`border-b border-slate-100`); ad §4.15 gibi sarar, risk + taban sıra adın altında, çıkar düğmesi `size-11` **çerçevesiz `CircleMinus`** — çarpı yalnız çekmeceyi kapatır (Bilal, 25 Eyl 2026: "2 çarpı var"). Listeler uzun olduğu için bu çekmece kaydırılır (tek ekran kuralının tek istisnası); alt bandı telefonda alt alta dizilir ki listeye en az ~280 px kalsın. - **Rozet yok, ek liste yok** (Bilal, 24 Eyl 2026: "buralarda badge kullanma"): çekmece ve sihirbaz modallarının başlığı üstünde `SectionEyebrow` durmaz; başlık + tek cümle bağlam yeter. "Saniyede gör" çekmecesi (`cta-sira-form.tsx`) bu düzene çevrildi: `AltSayfaBaslik` ortalı, `AltSayfaAciklama` bağlam, altında form; "neler alacaksın" çizgili ikon listesi kaldırıldı (bağlam cümlesi zaten söylüyor). Sihirbaz adımlarında çekmece başlığı `sr-only`, görünür başlık adımın kendisinde. Denetim: `modal-rozet` (hata). - **Arama motoru uyarısı:** çekmece içeriği sayfa açılırken HTML'de yoktur (kapalıyken çizilmez). Google'ın görmesi gereken metin ve **zorunlu atıflar** (ör. URAP sırası + payda + dönem + aktif bağlantı) çekmeceye taşınmaz, sayfada da görünür kalır. ### 4.11 Gösterge kareleri (masonry) Birden çok sayıyı alt sayfada göstermenin yolu. Logodaki üç kare gibi: **iki sütun, sağdaki aşağı kaymış, kare boyları farklı — ne tepeler ne bitişler hizalı.** ``` ┌────────┐ │ Türkiye│ ┌────────┐ │ sırası │ │ Hoca │ │ 5. │ │ başına │ │ İlk %3 │ │ 25 │ └────────┘ └────────┘ ┌────────┐ ┌────────┐ │ 56.128 │ │ 2.225 │ └────────┘ │ │ └────────┘ ``` - Kap: `flex w-full max-w-md items-start gap-3`; iki sütun `flex flex-1 flex-col gap-3`, sağdaki `mt-12`. - Kare: `flex flex-col items-center justify-center rounded-3xl px-3 text-white` + zemin (§2 "Gösterge karesi") + `min-h-*` ile farklı boy (ör. 40 / 24 / 32 / doğal). - **Ölçüyle doğrula:** komşu kareler arasında tepe ve bitiş farkı **en az 24 px**. 8 px fark "yanlışlıkla hizalanmış" görünür (§9.2). - Etiket `text-sm font-bold text-white/90`; sayı §3 gösterge ölçeği; vurgu satırı `text-base font-bold`. - Renk sırası: en önemli gösterge turuncu, ikincisi mavi, sonra indigo, yeşil. ### 4.12 Kimlik hapları (tür, il) Başlığın altında kurumun kimliği; navbar haplarının ölçüsünde: `inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-card px-4 text-sm font-semibold text-slate-800` + başta `size-4 text-primary` ikon (`Landmark` devlet, `Building2` vakıf, `MapPin` il). Tür renkle değil ikonla ayrılır. Rozet (§4.2) değildir. **Devlet/vakıf hapı tür sayfasına** (§4.18), **il hapı şehir sayfasına link**tir (Bilal, 24 Eyl 2026: "şehirlerin geçtiği her yer tıklanabilir") — aynı sınıf + `hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 active:scale-[0.97]`. Kural genel: bir şehir adı nerede geçerse geçsin (`/universiteler` listesi, bölüm/sonuç/listem/ tadımlık satırlarındaki tür-il-süre metası) `ilSayfaHref(il)` ile `/universiteler/[il]`'e gider; satır metasında `SATIR_IKINCIL_LINK`. İstisna: satırın tamamı zaten link olan yerler (URAP sıralaması, arama sonucu) — iç içe `` olmaz, orada düz metin kalır. ### 4.13 Piksel sıra şeridi — `PixelSira`, `src/components/pixel-decor.tsx` Bir sıranın (ör. 198 içinde 5.) yerini tek satır piksel şeridinde gösterir; sıranın düştüğü dilim turuncu yanar, geri kalanı hero dokusunda. **Veri taşıyan** piksel olduğu için süs ayraç yasağına girmez. - Açık zeminde: `` (8 hücre varsayılan). - Renkli dolu zeminde: `zemin="koyu"` — işaret beyaz yanar, ısı fırçası kapanır. - Anlamı her zaman yanındaki metin taşır ("5. / 198", "İlk %3"); şerit `aria-hidden`. ### 4.14 Üst çubuk başlık geçişi — `NavBaslik`, `nav-baslik.tsx` iOS'taki büyük başlık davranışı: sayfa h1'i üst çubuğun altına girince üst çubuktaki "KolayTercih" yazısı yukarı kayıp söner, yerine sayfanın logosu + adı gelir; dokununca sayfa başına döner. Katalog detay sayfalarında (üniversite, bölüm) zorunlu; yeni detay sayfası eklenince aynısı yapılır: ```tsx } />

…

``` Logosu olmayan sayfada `logo` verilmez; üst çubukta **yalnız ad** görünür (bölüm sayfası — Bilal'in kararı: yerine ikon konmaz, üst çubukta süs ikona gerek yok). Logo sunucuda üretilip verilir (logo listesi istemciye inmez). Hareket: yay `bounce: 0, duration: 0.35`, giriş ve çıkış aynı yoldan; "hareketi azalt"ta yalnız opaklık. ### 4.15 Liste satırı (program/üniversite listeleri) — `src/components/liste-satiri.ts` Sınıf dizileri tek dosyada (`SATIR_AD`, `SATIR_META`, `SATIR_CIP`, `SATIR_MOBIL_SAYI`, `SATIR_BUTON_KABI`…); üniversite, bölüm ve `/sonuc` tabloları oradan okur. Yeni bir liste tablosu bu sabitleri kullanır, sınıfı elle yazmaz. - Risk sütunu (`/sonuc`) sm'den itibaren ayrı sütun; telefonda adın altındaki sayı satırına iner. Etiket §4.5: `size-2` nokta + `text-xs font-semibold text-{renk}-600` + `RISK_ETIKET`. - Veride BÜYÜK HARF gelen üniversite adı ekranda `trBaslikDuzeni` ile yazılır. - **Ad kesilmez, sarar:** `whitespace-normal` + `block text-base font-semibold leading-snug`. `truncate` ile "İngiliz Dili ve E…" yazılmaz. - Ad linkinin hover'ı **mavi**: `transition-colors hover:text-primary hover:underline` (§2.1 istisnası). - Telefonda yalnız ad + satır butonları sütun olarak kalır; sayısal sütunlar (taban sıra vb.) adın altındaki satıra iner: `mt-1.5 flex items-center gap-1.5 text-sm text-slate-500 sm:hidden` içinde değer `font-semibold text-slate-900`. - **Üniversite alt satırı tek akan satır, telefonda bir kademe küçük** (Bilal, 24 Eyl 2026: "mobilde çok şişko, her şey iç içe; üni adını daha küçük yazabiliriz"): adın altında üniversite adı (`SATIR_ALT_AD`) ile tür çipi/il/süre (`SATIR_META`) `SATIR_ALT_GRUP` içinde her genişlikte yan yana akar, sığmazsa sarar; telefonda `text-xs`, sm'den `text-sm`. `/sonuc`, rapor listesi, tadımlık satırı ve çekmece satırı (`liste-cekmecesi.tsx`) böyledir. Bu, §3 "text-xs yalnız ince yazıda" kuralının bilinçli istisnasıdır (12 px tabanının üstünde). Katalog listelerinde (ad zaten üniversite/bölüm) `SATIR_GRUP`: telefonda ad kendi satırında, çipler 8 px altında; sm'den aynı satırda. Ölçüm 375 px, bölüm sayfası: satır 129 px ve yüksekliği metin değil, alt alta iki 44 px düğme belirliyor — metin küçültmek orayı kısaltmaz. - Tür çipi: `rounded-full bg-slate-100 px-2.5 py-0.5 text-xs font-semibold text-slate-700`. - Satır butonları varsayılan `size-11` (44 px); `size-8` gibi küçültme verilmez. Telefonda iki buton alt alta durur (`inline-flex flex-col items-center gap-2 sm:flex-row`, sütun `w-14 sm:w-28`): yan yana 96 px yiyip adı 157 px'e sıkıştırıyordu, alt alta 273 px kalıyor (24 Eyl 2026 ölçümü). - Rapor listesinde (`rapor-listesi.tsx`) telefonda logo gizlenir (`hidden sm:block`): solda sıra numarası zaten satırı çapalıyor, logo adı üç satıra sıkıştırıyordu (satır 214 → 152 px). Açılan ayrıntı iç kutuları `rounded-xl`, etiket `text-sm font-semibold text-slate-900`, metin `text-base`. - **Geniş ekranda ince satır** (Bilal, 25 Eyl 2026: "geniş ekranda listeler çok kalın"): sm'den itibaren tür/il/süre satırı adla aynı satıra çıkar (`SATIR_GRUP`); lg'de hücre dolgusu `py-3` ve satır düğmeleri 36 px (`SATIR_DUGME_BOYU`, §8 masaüstü tablo istisnası). Ölçüm 1280 px, bölüm listesi: 83 → 61 px. Telefonda değişmez (44 px düğme). - Satırda logo varsa (bölüm sayfası, `/sonuc`, rapor listesi) `UniLogo boy="sm"` adın solunda, `items-start`. `sm` = **48 px** (`size-12 rounded-xl`; 36 px'ten büyütüldü — Bilal, 24 Eyl 2026: "listelerde üni logoları çok küçük kalmış"). Çekmecede üniversite satırının içindeki `xs` (28 px) metin içi kalır. - Program varyantı ("… (İngilizce) (Burslu)") adın altında ayrı satır `mt-0.5 block text-sm leading-snug text-slate-600`; tür çipine yapıştırılıp kesilmez. - Tür çipi devlet/vakıf için de aynı slate çip; vakıf violet değildir (§2.2). - Tablo başlığı `h-12 text-sm font-semibold text-slate-500`; hücre dolgusu `py-4 pl-4 sm:pl-5`. ### 4.16 Bildirim yığını (toast) — `src/components/ui/bildirim.tsx` Bilal (7 Eki 2026): "toastlarımız için Toast stack kullanalım." `sonner` kaldırıldı; yerinde Arc UI "Toast stack"ten taşınan `BildirimYigini` (layout'ta bir kez) ve aynı çağrı biçimli `toast` var (`toast.success(başlık, { description, action, id, duration })` — yalnız import yolu değişti). Bildirimler **üst ortada** birikir (altta çekmecenin çağrı bandı ve telefonda klavye var): yenisi yukarıdan iner, eskiler arkasına saklanıp altından 12 px şerit gösterir, en çok üçü görünür; üzerine gelince ya da dokununca yığın listeye açılır ve süre durur; sağa kaydırınca kapanır. Aynı `id` yeni bildirim açmaz, olanı yerinde günceller (metin dönüşür). Renkler palet token'ı olduğundan tema kendiliğinden doğru (eski sorun: sonner sistem temasına bakıp açıklamayı okunmaz ediyordu — Bilal, 24 Eyl 2026). Tür ikonu: başarı `emerald-600`, bilgi `primary`, uyarı `amber-600`, hata `red-600`, sürüyor dönen `Loader2 text-primary`; tür adı ekran okuyucuya yazıyla söylenir. Kutu `rounded-2xl border-slate-200`; başlık `font-semibold text-slate-900`; açıklama `text-slate-600`; aksiyon düğmesi üst çubuktaki koyu hap (`h-9 rounded-full bg-slate-900`, yazı `slate-50`, hover `slate-700`). Metin §10.4: ne oldu + ne yapılacak; kilometre taşı toast'ları (`program-ekle-butonu.tsx`) tek cümle açıklama + tek aksiyon taşır. **İç düzen — tek hiza (Arc'ın düzeni; Bilal, 7 Eki 2026: "Arc'taki gibi hizalı görünüm olmuyor").** İkon, başlığın ilk satırı, aksiyon hapı ve çarpı aynı 36 px'lik şeridin ortasına oturur: içerik `flex items-start gap-3 py-1.5 pr-1.5 pl-4`; ikon kutusu `h-9 w-5` (ikon `size-5`); metin `py-2 text-sm leading-5`; aksiyon hapı ve çarpı `h-9` / `size-9`, sağda `gap-1` tek grup. Tek satırlık bildirim 48 px'tir ve her şey kutunun tam ortasındadır; çok satırlıda ikon ve çarpı ilk satırla hizalı kalır. **Aksiyonun yeri içeriğe göre:** açıklama yoksa hap başlığın yanında, sağda ("Çıkarıldı · Geri al" tek satır); açıklama varsa metnin altında, metinle aynı sol hizada (`mt-2.5`) — yanında durursa Türkçe açıklamayı üç-dört satıra sıkıştırır. Eksi kenar boşluğuyla hizalama yapılmaz (eski hâlde çarpı ilk satırdan 4 px aşağıdaydı); yeni bir öğe eklenirse o da 36 px'lik şeride oturtulur. ### 4.17 Şehir çipleri — `SehirCipleri`, `src/features/katalog/components/sehir-cipleri.tsx` Şehre göre üniversite gezinmesi (`/universiteler` üstü ve `/universiteler/[il]` altı). Sihirbazın il çipiyle aynı kalıp; etkileşimli çip olduğu için rozet (§4.2) değildir: `inline-flex h-10 cursor-pointer items-center gap-1.5 rounded-full border px-3.5 text-sm font-semibold transition-[background-color,border-color,color,transform] duration-150 active:scale-[0.97]` + pasif `border-slate-200 bg-card text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500`, bulunulan şehir `border-primary bg-primary text-white` + `aria-current="page"`. Ad yanında üniversite sayısı `font-normal tabular-nums text-slate-400` (aktifte `text-white/80`). - Çip satırında yalnız **2+ üniversiteli** şehirler (≈28) durur; 90'ı aşkın şehrin tamamı `/universiteler#tum-sehirler` altındaki A–Z üç sütunlu metin listesindedir (§1.1 "sık bakılan önde, ayrıntı bir dokunuş derinde"). Satırın sonunda "Tüm şehirler (N)" çipi. - Şehir sayfası (`il-icerik.tsx`) katalog detay düzenindedir (§5.2): yol satırı, **başlık yüzeyi** (`SehirYuzeyi`: `relative isolate overflow-hidden rounded-3xl border border-slate-200 bg-card p-6 sm:p-8`, `PikselZemin ton="acik"` seed 31, harita kabı `haric`), içinde h1 "İstanbul Üniversiteleri Taban Puanları 2026", kimlik hapları (`MapPin` il + üniversite sayısı), özet paragraf; sağda (lg, 24rem sütun) ya da altta (telefon) **şehri temsil eden piksel harita** `SehirPikselHaritasi`. Sonra kompakt `CtaSiraForm`, `PagePixelDivider` (seed 71), devlet / vakıf / KKTC-yurt dışı öbekleri — her biri §4.15 **liste satırı** (`UniSatirlari`: kenarlıklı `rounded-xl` liste, 48 px logo, `SATIR_AD_DUZ` ad, `SATIR_META` içinde tür çipi + program sayısı, satırın tamamı link, sağda kayan ok; Bilal, 24 Eyl 2026: "il kısmında üniler küçük gözüküyor" — `/universiteler` dizinindeki iki sütunlu kompakt `UniLinkleri` burada kullanılmaz), "Diğer şehirler" çipleri ve mavi CTA bandı. Şehir adı `trBaslikDuzeni` + tire sonrası baş harf (Bakü-Azerbaycan). Bir üniversite programı olan her ilde sayılır (ODTÜ Ankara + KKTC). - **Şehir piksel haritası** — `sehir-piksel-haritasi.tsx`: **hero'daki dot-matrix Türkiye'nin kendisi** (Bilal, 24 Eyl 2026: ince taramalı ilk sürüm "oyunsu Apple/Duolingo hissine uymuyor" diye geri alındı; seçenekler A/B/C arasından "A, pikseller C'deki gibi iri" seçildi). Izgara 56 sütun × 24 satır (`scripts/il-izgara-uret.ts` → `src/lib/il-izgara-verisi.ts`; her il en az 2×2 kare; Bilal: "piksel detaylarını azalt"), kare hücrenin %74'ü, altı farklı opaklık, serpinti yok, `text-primary` zemin, imleç yaklaşınca turuncuya ısınma (`usePixelHeat`, meet/slice ve canlı viewBox ile). Bulunulan ilin kareleri `fill-orange-500`, hücrenin %88'i kadar iri, 35 ms arayla belirir (`kt-piksel-belir`) ve grup hâlinde nabız atar (`animate-pulse` 3.6 s); hareketi azalt açıkken dolu ve durağan. KKTC/yurt dışı: ülke kontürü mavi doku, şehir merkezinde 2×2 hücrelik tek iri turuncu kare; şehri bilinmeyen "KIBRIS" için ülkenin tamamı turuncu. Markup hero'daki gibi deterministik string (`dangerouslySetInnerHTML`). `role="img"` + "İstanbul Türkiye haritasında". Üniversite sayfasının konum kartı (`universite-konum-haritasi.tsx`) aynı bileşeni kullanır. Veri taşıyan pikseldir (§1.2), süs ayraç yasağına girmez. - **Harita arka plandır, kesilmez** (Bilal, 24 Eyl 2026: "canvas net bir şekilde kesiliyor, çok kötü"; "harita bulunduğu yerin tamamını kaplasın"). Şehir sayfasında `SehirYuzeyi` kartını `doldur` (slice) ile kaplar, metin üstünde; kenarlar `mask-image` ile erir — telefonda yukarıdan (metnin altında belirir), lg'de soldan (sağ yarıda belirir). Metin sütunu lg'de %58, kart en az 26rem; telefonda altta 12–14rem harita payı. Üniversite sayfasında harita **dört özet kartın arkasına sarkar** (Bilal, 24 Eyl 2026): ızgara `relative isolate`, üçüncü sütun yalnız yer tutar, harita `absolute -inset-x-4 -inset-y-8 -z-10` katmanda; lg'de sağdan sola, telefonda üst satırdan aşağı doğru uzun rampalı mask. Mask rampaları uzun tutulur (şeffaf → %6 → %30 → siyah); kısa rampa "kanvas" gibi okunur. Sert kenarlı, kırpılmış bir SVG asla görünmez. - **Yakınlaşma** (Bilal, 24 Eyl 2026: "ilin bulunduğu yere doğru harita büyüsün, sayfa yüklendikten sonra delay ile motion ile"): SSR tüm ülke; yüklenince 0,6 s sonra viewBox sıçramasız yayla (`spring`, bounce 0, 1,6 s; Apple'ın damping 1'i — ease-out "sert" duruyordu) ilin çevresindeki kutuya kayar — en çok 2,4 kat (ülke haritasında şehir işaretine 1,8 kat). Kutu kabın o anki oranında kurulur ve il `odakHiza` ile kabın istenen noktasına gelir (şehir sayfası: lg'de x 0,74 / y 0,5, telefonda x 0,5 / y 0,78; üniversite sayfası: lg'de x 0,82 / y 0,5 — üçüncü sütun, telefonda y 0,17 — üst satır). Kareler büyür, il kadraja gelir; ısı fırçası viewBox'ı canlı okur. Hareketi azalt açıkken kutuya doğrudan atlanır. Sayfa başına tek yakınlaşma. ### 4.18 Tür sayfaları — `/universiteler/devlet`, `/universiteler/vakif` (`tur-icerik.tsx`) Bilal (24 Eyl 2026): "vakıf ve devlet de tıklanabilir olmalı, özel sayfalar yapabilirsin, kreatif". Şehir sayfasının iskeleti (§4.17) ile: yol satırı, `SehirYuzeyi` başlık yüzeyi, kimlik hapları (tür + öteki türe geçiş hapı), özet paragraf, kompakt `CtaSiraForm`, üç `OzetKart` (üniversite / program / şehir; `grid grid-cols-2 gap-4 lg:grid-cols-3`, üçüncü telefonda tam genişlik), "Şehre göre" çipleri (sayfa içi `#sehir-…` çapaları), şehir şehir §4.15 `UniSatirlari`, altta mavi CTA bandı. - **Kreatif:** başlık yüzeyindeki dot-matrix Türkiye'de bu türden üniversitesi olan **her il** turuncu yanar (`TurkiyePikselHaritasi iller=[…]`), yakınlaşma yok — "devlet üniversiteleri Türkiye'nin neresinde" tek bakışta. Vakıfta harita seyrek yanar; bu bilginin kendisidir. - Tür çipi tek kaynak `TurCipi` (`src/components/tur-cipi.tsx`): devlet/vakıf (ve Vakıf MYO) tür sayfasına link, KKTC/yurt dışı düz çip; `/sonuc`, `/listem`, tadımlık, bölüm sayfası ve şehir/tür satırları bunu kullanır. Satırın tamamı link olan yerde kullanılmaz. - `/universiteler` dizinindeki "Devlet Üniversiteleri" / "Vakıf Üniversiteleri" başlıkları da tür sayfasına link. ### 4.19 Program ayrıntı çekmecesi — `program-ayrinti.tsx` (eski adı "Netler paneli") Bilal (24 Eyl 2026): "bu kısımlar design md'ye uygun yap, belirt ki bir daha bu hata olmasın". Panel ortada açılan `Dialog` ve `text-xs` hücreli bir tabloydu; iki kural birden çiğnenmişti. **Kural:** program satırından açılan her ayrıntı (netler, akademik göstergeler, kontenjan geçmişi) §4.10 **alt sayfadır** — `AltSayfa`, kap ve çarpı `cta-sira-form.tsx` çekmecesiyle birebir, başlık `px-10 text-center font-heading text-2xl font-bold`, altında tek cümle bağlam `text-sm text-slate-500`. İçindeki tablo §4.15'tir: başlık `SATIR_BASLIK`, hücre `text-sm` (gövde `text-xs`'e inmez, §3), sayılar `font-sans tabular-nums`, **en yeni yıl** koyu (`font-semibold text-slate-800/900`), eski yıllar `text-slate-500`; toplam satırı ("Yerleşme puanı") `border-t border-slate-200` + `font-semibold text-slate-900`; ilk sütun `pl-0`. Boş ve hata durumu `text-base text-slate-500`. Denetim: `tablo-minik-yazi` (hata) — `TableCell`/ `TableHead` içinde `text-xs` yazılamaz. `Dialog` yalnız arama penceresi (`katalog-arama`) ve sihirbaz modalı içindir; yeni bir ayrıntı için `Dialog` açılmaz. - **6 Eki 2026 — netlerden tüm ayrıntıya:** satırın yuvarlak düğmesi (`Info` ikonu, "ayrıntı") tek çekmece açar; veri `/api/program-ayrinti`. Sıra: başlık = program adı, bağlam = üniversite · il · fakülte; **künye hapları** (§4.12 ölçüsü, link değil: süre + tür, dil, öğretim türü (örgün değilse), burs/ücret, akreditasyon, baraj, öğretim üyesi sayısı, yalnız kız/erkek koşulu, kampüs ilçesi — yalnız verisi olanlar); "Yıllara göre" tablosu (yıl, taban sıra, puan, kontenjan, yerleşen); "Kontenjan türleri (yıl)" `dl` satırları (yalnız >0 olanlar; özel kontenjanın ayrı taban sırasının elimizde olmadığı notu); "Son yerleşenin netleri" (eski tablo + OBP katsayısı satırı; 0,18 = meslek lisesi ek puanı notu); "Yerleşme koşulları (N)" yerel `details` ile kapalı başlar; "Mezun istihdamı" ve "Üniversite" tek paragraf; en altta kaynak satırı `border-t border-slate-100 text-xs`. Bölüm başlıkları `font-heading text-base font-bold`, notlar `text-sm text-slate-500`; süs ayraç yok, kart yok. İçerik uzun olduğu için çekmece **kaydırılır** (liste çekmecesi gibi; §4.10 tek ekran kuralının ikinci istisnası). Açık listem satırında aynı çekmece `varyant="metin"` ile "Program ayrıntısı" metin düğmesinden açılır ("Haritada gör" kalıbı). ### 4.20 Danışman sohbeti — `sohbet-client.tsx`, `arac-pilleri.tsx` Sohbet kabuğu **prompt-kit** bileşenleridir (`src/components/ui/`: `prompt-input`, `message`, `chat-container` + `scroll-button`, `prompt-suggestion`, `loader`, `markdown`); yeni bir sohbet parçası gerekince önce prompt-kit'e bakılır (`shadcn add https://prompt-kit.com/c/.json`). Bilal (6 Eki 2026): "tool use durumunda pill'li bir UI; danışmanla konuş alanı motion ile genişletilebilir olmalı; UI için prompt-kit kullan." - **Araç hapları** (`AracPilleri`): danışman veriye bakarken cevabın **üstünde** hap satırı — §4.17 kompakt çip (`inline-flex h-8 items-center gap-1.5 rounded-full border border-slate-200 bg-card pl-2.5 pr-3 text-xs font-semibold text-slate-700`), başta durum ikonu `size-3.5`: sürüyor `Loader2 animate-spin text-primary`, bitti `Check text-emerald-600`, hata `CircleAlert text-red-600`. Metin öğrenci dilinde ve zamanı söyler ("Programlara bakıyorum…" → "Programlara baktım"); hata **sözle** ("… (veri gelmedi)"), renk tek başına değil (§2.2). Aynı araç birden çok kez çağrıldıysa tek hap + "×2". Haplar cevap bitince **kalır** (danışmanın neye baktığı güven verir); kayıtlı geçmişte araç parçası olmadığından yalnız canlı cevapta görünür. Hap aşağıdan 4 px gelir, ikon durumla çapraz söner (yay, bounce 0, 0,3/0,2 s); hareketi azalt'ta yalnız opaklık. `role="status" aria-live="polite"`. prompt-kit'in `Tool` bileşeni **kullanılmaz**: ham araç adı (`program_ara`), İngilizce rozet, JSON girdi/çıktı ve `dark:` sınıfı taşır — öğrenciye araç adı ve iç kimlik gösterilmez (`danisman-prompt.ts`); yalnız durum modeli (input-streaming → output-available | output-error) ortaktır. - **Genişletme — yerinde büyür, komşular yeniden akar** (Bilal, 6 Eki 2026: tam ekran/perde denemesi "çok kötü"; "div'in smooth genişlemesi, diğer alanların kendini yeniden boyutlandırması"). Başlıktaki `Maximize2` düğmesi (`size-7`, öteki başlık düğmeleriyle aynı sınıf) iki şeyi aynı yayla (§6, `SOHBET_GENISLEME_GECISI`) sürer: sayfa önce panelin üstü sticky hizasına (`top-28`, 7rem) gelecek kadar yayla kayar, panelin **boyu** oradan alt progressive blur'un (`.kt-sayfa-blur-alt`, 7rem) üstüne kadar uzar — yani ekran − 14rem; sayfa o kadar kaymıyorsa kalan fark boydan düşülür, panel bulanık şeride girmez (Bilal, 6 Eki 2026: "aşağı kısmı progressive blura takılıyor") (ölçülen px'ten hedefe `animate(el, { height })`, bitince satır içi değer bırakılır) ve `/listem` ızgarasında sohbet **sütunu** genişler — sütun genişliği CSS değişkeni `--sohbet-kolon` (lg 380 px, xl 440 px; `lg:grid-cols-[minmax(0,1fr)_var(--sohbet-kolon)]`), `animate(izgara, { "--sohbet-kolon": "" })` ile ızgara genişliğinin %60'ına (en çok 760 px) büyür; liste ve harita daralan sol sütunda kendini yeniden akıtır. Telefonda (lg altı) yalnız boy uzar. `Minimize2` geri alır; sohbet durumu (useChat, kaydırma) korunur. Hareketi azalt: geçişsiz. Perde, sabit konum, ayrı `Dialog`/`AltSayfa` **yok** — sohbet yeniden kurulmaz, sayfa zıplamaz. - **Dar hâlin boyu — sayfa en üstteyken de bulanık şeridin üstünde biter** (Bilal, 7 Eki 2026: "yüksekliğini alttan kısalım, progressive blur üzerine geliyor, sığmıyor"). Sınıf tek yerde: `SOHBET_DAR_BOY` (`sohbet-client.tsx`) = `h-[calc(100dvh-23.75rem)] min-h-[340px] sm:h-[calc(100dvh-24.75rem)] lg:h-[calc(100dvh-21.5rem)]`. Düşülen pay = panelin sayfa en üstteykenki üst boşluğu (sezon bandı + site başlığı + `main` py-12 + ızgara mt-8; **ölçüldü**: telefonda 251, 768 px'te 267, 1280 px'te 217 px) + 7rem şerit + 1rem nefes. Eski `18rem` sezon bandını saymıyordu. Paketsizdeki 480 px'lik panel aynı sayıları `max-h` olarak taşır. Sezon bandı ya da başlık boyu değişirse bu üç sayı yeniden ölçülür (§9.2). - **Elle boyutlandırma ve telefonda sıra** (Bilal, 7 Eki 2026): geniş ekranda liste ile sohbet arasındaki boşlukta `BolmeTutamaci` durur (§4.25); sürükleyince aynı `--sohbet-kolon` değişkeni değişir (sohbet 320–820 px, liste en az 420 px), çift tık varsayılana döner. "Genişlet" düğmesi elle verilen genişlikten devam eder; "Daralt" varsayılana döner. **Telefonda (lg altı) danışman en üsttedir**: sütun kabı `max-lg:contents`, sohbet `max-lg:order-first`, paketsizdeki paket kartı `max-lg:order-last` — harita ve liste sohbetin altında akar. - **Bağlantı hapları** (`sohbet-baglanti.tsx`, Bilal 6 Eki 2026: "chat link verdiğinde kod gibi veriyor"): danışman cevabındaki site içi adres (`/rehber/…`, `/universite/…`, `/bolum/…`, `/universiteler/`, `/paket`, `/listem`) prompt-kit `Source` kalıbında **küçük satır içi hap** (ilk sürüm h-7 "çok yer kaplıyordu"): `inline-flex h-6 items-center gap-1 rounded-full border border-slate-200 bg-card pl-1.5 pr-2 text-xs font-medium text-primary` + türü söyleyen `size-3.5` ikon (`BookOpen` rehber, `Landmark` üniversite, `GraduationCap` bölüm, `MapPin` şehir, `Coins` paket, `ListChecks` listem), hover §2.1, `sr-only` tür etiketi. Metin markdown bağlantısının başlığıdır (prompt kuralı: `[Yazının başlığı](/rehber/slug)`); model adresi çıplak ya da backtick içinde yazarsa aynı hap slug'dan türetilen adla çizilir (`baglantilariIsaretle`, `InlineKod`). Dış bağlantı (`https://`) yeni sekmede açılan altı çizili düz link. prompt-kit `Source`'un Google favicon'u ve `muted` paleti dış siteler içindir, alınmadı. Sohbet balonu `prose` sınıfı taşır ama typography eklentisi yok — bağlantı/kod görünümü bu bileşenlerden gelir. - **Bağlantı önizlemesi — imleci izleyen mini pencere** (Bilal, 6 Eki 2026: motion-primitives `Cursor` örneği + "aramada yaptığın gibi MacBook penceresi gibi bir kanvas"): rehber, üniversite, bölüm ve şehir haplarının üzerine gelince (yalnız `(hover: hover) and (pointer: fine)`; dokunmatikte yok) body'ye portal'lanan 288 px'lik pencere imleci yayla izler (`useSpring` stiffness 450 / damping 40, imlecin 18 px sağ altı; kenara sığmazsa sol/üst) ve `height 0 → auto, opacity, scale 0,3 → 1` ile açılır, aynı yoldan kapanır (`spring`, 0,3 s, bounce 0 — §6; örnekteki 0,1 bilinçli alınmadı). Pencere dili aramadaki mini tarayıcıyla aynı (`katalog-arama.tsx` KESFET_TONLARI slate): `rounded-xl border border-slate-200/80 bg-card shadow-lg shadow-slate-900/5`, çubuk `h-6 bg-slate-50/90` + üç `size-2 bg-slate-300` nokta (1 / 0,65 / 0,35) + adres hapı (`kolaytercih.com/rehber/…`, `text-xs text-slate-500`). Rehberde gövde **yalnız kapak**: tam `RehberKapak` (compact yok) 1200×630 çizilip `scale(288/1200)` ile pencereye oturur — yazı, logo ve piksel süs kesilmez; başlık/özet/iskelet yok. Üniversite/bölüm/şehir gövdesi `p-3`: `UniLogo md` ya da §4.4 ikon kutusu, başlık `font-heading text-sm font-bold line-clamp-2`, özet `text-xs leading-5 text-slate-500 line-clamp-3`, künye `text-xs font-medium text-slate-500` ("URAP 18/198"). Veri `/api/onizleme?yol=` (bir gün cache, hap başına bir kez; iskelet yok, başlık hap metninden hemen çizilir). `pointer-events-none`, `aria-hidden` — bilgi hapın kendisinde. Hareketi azalt: izleme yok, yalnız opaklık. - **Araç adımları — prompt-kit `Steps`** (`src/components/ui/steps.tsx` + `collapsible.tsx`; Bilal: "Steps de olsun duruma göre"): bir cevapta **iki ve daha çok** araç varsa haplar yerine Steps: başlık `text-xs font-semibold text-slate-500` sürerken "Veriye bakıyorum · 2/3", bitince "3 adımda baktım", solunda durum ikonu (hover'da prompt-kit'in ok değişimi); açılır gövdede solda `w-0.5 bg-slate-200` çubuk, sağda her adım `text-xs font-medium text-slate-700` + durum ikonu. Açık başlar, kullanıcı kapatabilir; açılma `animate-collapsible-down/up` (tw-animate-css), hareketi azalt'ta geçişsiz. Tek araçta hap kalır. Palet slate'e çevrildi (`muted`/`popover` yok). - **Liste uyarıları sohbette, danışmanın ağzından** (Bilal, 6 Eki 2026: "bu tarz uyarıları danışmanın turuncu danışmanla konuş logosu ile chatte vermesi daha uygun"). Listenin kendisinden çıkan uyarılar (dağılım havuza uyarlandı, tüm tercihler tek şehirde — `liste-uyarilari.ts`) listenin üstünde sarı kutu olarak **çizilmez**; sohbetin açılışında, "Danışman özeti"nin hemen altında "Danışman uyarısı" mesajı olur: avatar `DanismanAvatar renk="turuncu"` (panel başlığındaki işaretin rengi, durağan — avatarda hareket yalnız "düşünüyor" demektir), etiket özetle aynı (`text-xs font-semibold text-slate-500`), balon işaretin turuncusunda dolu zemin (`bg-orange-500 font-medium text-white` — Bilal, 6 Eki 2026: "uyarı bubble'ı danışmanın logosu backgroundında olmalı"); birden çok uyarı tek avatarın altında ayrı balonlardır. Bu, §2.2'deki "turuncu dolu zeminde uzun metin konmaz" kuralının bilinen **tek istisnasıdır**: uyarı en çok iki kısa cümledir, daha uzun metin bu balona konmaz; öteki danışman balonları gri kalır (`bg-slate-100 text-slate-800`). Renk tek başına anlam taşımaz: "Danışman uyarısı" etiketi her zaman yazılıdır (§2.2). Sohbet ilerlese de kalır. Yeni bir liste uyarısı gerekince `listeUyarilari`'na eklenir, sayfaya yeni kutu açılmaz. - **Liste revizyonu sohbette** (Bilal, 7 Eki 2026: "revize sistemi tamamen chate taşınsın"; geri bildirim: eski kutudan "ilk 5 X ilinden olsun" denince liste değişmiyordu — not modele serbest metin gidiyor, sıra ve havuz koddan belirleniyordu). `/listem`deki revizyon kutusu kaldırıldı; başlıktaki "Revize et" düğmesi sohbet kutusunu odaklar (`sohbetiOdakla`). Danışman belirsiz isteği **soru formuyla** netleştirir (`soru_sor` → §4.33 `SohbetAnketi`, balonun altında sade kutu), sonra `liste_revize` aracıyla **yapısal kural** verir (il/alan/tip farkı, "ilk N" ölçütü, çıkar/ekle, iskelet; `lib/revizyon-kurali.ts`); liste koddan yeniden kurulur, sayfa `router.refresh()` ile yenilenir, hap "Listeni yeniden kurdum" olarak kalır. Form cevabı kredi harcamaz. Kayıtlı geçmişte form ve revizyon sonucu `chat_messages.meta`dan geri kurulur. ### 4.21 Sayı rulosu — `SayiRulo`, `src/components/ui/sayi-rulo.tsx` Ekranda **değişen** sayı (üst çubuk rozeti ve kredi hapı, "Listende 5/24", çekmece sayacı, danışman kredi rozeti, "40 / 312 program", üst şeridin sezon geri sayımı, giriş formunun "Yeniden gönder (59)" sayacı, kaydet bildirimindeki seçim sayısı) rulo gibi döner: eklemede yukarı, çıkarmada aşağı; basamak artınca yeni sütun yayla açılır. Yazı boyu/rengi kapsayıcıdan gelir. Yay §6 varsayılanı; hareketi azalt'ta düz metin; ekran okuyucu düz metni okur. Kaynak Arc UI "Number field" (uiarc.dev, 6 Eki 2026); oradaki −/+ adım butonları ve sürükleme alınmadı — sıralama girişi `Input` hapı olarak kalır (§4.6), rulo yalnız gösterime takılır. Durağan sayıya (taban sıralaması, kontenjan) takılmaz. Geri sayım gibi basamak dolgusu isteyen sayaçta `enAzBasamak={2}` ("05") ve sabit `yon={-1}` (00 → 59 sarması da aşağı döner) verilir; sitede ikinci bir rakam kütüphanesi yoktur (`@number-flow/react` 6 Eki 2026'da kaldırıldı, üst şerit de bu ruloyu kullanır). ### 4.22 Kayan vurgulu seçim hapları — `SecimHaplari`, `src/components/ui/secim-haplari.tsx` Tek seçimli hap grubunda seçili vurgu yeniden boyanmaz, tek yüzey olarak seçenekten seçeneğe **kayar** (`layoutId`). `ayrik`: kenarlıklı ayrı haplar + mavi dolu vurgu (puan türü çipleri — hero ve CTA formu). `kapsul`: tek kapsülde koyu hap, yazı `text-slate-50` (tema seçici). Yay §6; hareketi azalt'ta vurgu yerinde belirir. Kaynak Arc UI "Chip group" (6 Eki 2026). Çok seçimli çipler (sihirbaz alan/il) bu desene girmez — onlar §4.24 `SecimCipi`'dir (seçilince tik büyür). ### 4.23 Kaydırma eylemi — `KaydirmaGrubu` + `KaydirmaSatiri`, `src/components/ui/kaydirma-eylemi.tsx` Bilal (7 Eki 2026): "Arc'taki swipe action'ı bizdeki listeye getir." "Kendi Listem" satırı **sola kaydırılınca** altından "Çıkar" eylemi açılır (80 px, `bg-red-500 text-white`, ikon + yazı); sonuna kadar çekilince eylem satırın tamamını kaplar ve bırakınca uygulanır, dokunmatikte eşikte kısa titreşim verir. Aynı anda tek satır açık kalır; başka yere dokunmak ya da Escape kapatır. Çıkarma §10.5 gibi geri alınabilir bildirimle biter. **Eylem, satırda görünen bir düğmeyle de yapılabilmelidir** (listede `CircleMinus`): klavye ve ekran okuyucu yolu odur, kaydırılan kopya `aria-hidden`. Dikey sıralama tutamağı ayrı kalır. Tonlar: `tehlike` (kırmızı; etiket sonucu söyler), `vurgu` (mavi), `notr` (slate). Kaynak Arc UI "Swipe actions"; "Diğer eylemler" menüsü alınmadı. Yeni bir listede kaydırma gerekirse bu bileşen kullanılır, elle `drag="x"` yazılmaz. ### 4.24 Seçim çipi ve çip grubu — `SecimCipi` + `CipGrubu`, `src/components/ui/cip-grubu.tsx` Bilal (7 Eki 2026): "chip group'u pills seçimi olan yerlerde kullanalım." Çok seçimli hap seçimlerinin tek kaynağı (sihirbazın alan, şehir, üniversite tipi, öncelik ve özel kontenjan çipleri). Sınıf §4.17 çipi (44 px; `kucuk` 40 px; seçili `border-primary bg-primary text-white`; `ton="bilgi"` pasifte mavi ton). Seçilince başta **tik kendini çizerek büyür**, yazı yana kayar, çipin kenarı yayla izler, komşular akışla yer açar — seçili hâl renk + tik'tir (§2.2). `CipGrubu` gruba ad verir (`etiket`) ve ok tuşlarıyla çipten çipe geçirir. Kaynak Arc UI "Chip group"; komşuları layout projeksiyonuyla kaydırma alınmadı (kayan alt sayfa ve ölçülen sihirbaz paneli içinde erken ölçüm satırları kaydırıyordu), "+N daha" katlaması da yok. Tek seçimde kayan vurgu §4.22. ### 4.25 Bölme tutamacı — `BolmeTutamaci`, `src/components/ui/bolme-tutamaci.tsx` Bilal (7 Eki 2026): "Resizable panels ile danışmanın bulunduğu sayfada ölçeklendirme yapılabilsin." Yan yana iki alanın arasındaki 24 px'lik boşlukta duran ayırıcı: dinlenirken silik bir tutamaç (`h-10 w-1.5 bg-slate-300`), üzerine gelince / odakta / sürüklerken turuncu ve uzun (§2.1), yanında ince turuncu çizgi. İşaretçiyi birebir izler, sınırın ötesinde lastik gibi direnir ve bırakınca sınıra döner. `role="separator"`: ok tuşları 16 px (Shift 64 px), Home / End sınırlar, çift tık varsayılan. Genişliği çağıran tutar (`oku` / `yaz` / `sinirlar`); `/listem`'de ızgaranın `--sohbet-kolon` değişkeni (§4.20). Yalnız `lg` ve üstünde görünür. Kaynak Arc UI "Resizable panels"; sabit boylu kap ve bölmeyi tamamen kapatma alınmadı (sayfa kayıyor, sohbet yapışkan). ### 4.26 Yazı dönüşümü — `YaziDonusumu`, `src/components/ui/yazi-donusumu.tsx` Kısa bir ifade yerinde bir sonrakine dönüşür: ortak harfler yeni yerine süzülür, yeniler netleşerek gelir, gidenler bulanıp söner, genişlik yayla izler. **Şu an sayfada kullanılmıyor:** ana sayfa başlığındaki dönen vurgu ("gerçek veriyle" → "risk hesabıyla" → "gerekçesiyle") 7 Eki 2026'da geri alındı (Bilal: "diğer ana sayfa bileşenleri eski hâline gelsin"); başlık yine sabit "gerçek veriyle" yazar. Bileşen dosyası duruyor. Kaynak Arc UI "Text morph". Yeni kullanım: yalnız **birkaç harfi değişen kısa durum yazısı**; paragraf ya da uzunluğu çok değişen metin dönüştürülmez (Bilal'in 24 Eyl 2026'da kaldırdığı "yazılıp silinen satır" geri gelmez). ### 4.27 Kart destesi — `KartDestesi`, `src/components/ui/kart-destesi.tsx` Kartlar tek tek sorulur: üstteki kart sağa/sola sürüklenip fırlatılır (parmağın hızını taşır), arkadakiler o uzaklaştıkça kalkar; aynı karar düğmelerle ve ok tuşlarıyla verilir, "Geri al" kartı çıktığı yerden getirir. Kart `rounded-3xl border border-slate-200 bg-card`, boyu `--kart-boyu` (19rem); düğmeler 44 px hap — sol ikincil (hover §2.1), orta sessiz, sağ **mavi dolu** (turuncu yalnız funnel CTA'sı). Sürüklerken beliren damgalar hap; onay damgası mavi tonda (yeşil risk dilindedir, burada kullanılmaz). Kaynak Arc UI "Card stack". - **"Bu program listene girer mi?" demosu** (`deste-demosu.tsx`, veri `landing-verisi.ts` `ornekProgramlar`): örnek sıralamaya (Sayısal 85.000) göre **gerçek** yedi devlet programı. Kartta künye şeridi (il · Devlet), ad, üniversite, iri taban sıralaması (§1.1) ve `RiskEtiketi`. Uydurma sayı yok; veri okunamazsa çizilmez. Bitince tek turuncu CTA forma götürür. **Ana sayfadan çıkarıldı (7 Eki 2026)** — Bilal: "bunu oyunlaştırmada ilerde kullanacağız". Dosyalar duruyor; şu an hiçbir sayfada çizilmiyor. ### 4.28 Veri akışı — `VeriAkisi`, `src/features/pazarlama/components/veri-akisi.tsx` Ana sayfa "Nasıl çalışır" bölümünde, üç adımın (§4.32) altında: ortada KolayTercih işareti, çevresinde altı girdi; her girdiden merkeze **düz çizgi** iner, üzerinde piksel kare akar. **Solda öğrencinin üç seçimi** (turuncu ikon ve kare), **sağda YÖK Atlas'ın üç verisi** (mavi ikon ve kare); ayrımı etiket ve yan taşır, renk eşlik eder (§2.2). Akış CSS'tir (`kt-akis`, globals.css), yalnız ekrandayken oynar; hareketi azalt'ta kareler durur. Esin React Bits "Center Flow"; kod bizim — parlama ve bulanıklık yok, akış içeri doğru. Yeni bir girdi eklenirse sihirbaz/havuz kurallarıyla aynı olmalı (`/meraklisina` şemasıyla çelişmez). - **Çizgi düz, karolar beyaz** (Bilal, 7 Eki 2026: "aradaki yerler solid çizgi olsun, etrafındaki kartların bg'si ve görünümü daha iyi olabilir"). Çizgi `var(--color-slate-300)`, 1,5 px (`vectorEffect="non-scaling-stroke"`), karonun merkezinden işaretin merkezine çekilir ve karoların **altında** kalır; kesik/noktalı çizgi yazılmaz. Girdi karosu `size-14 rounded-2xl border border-slate-200 bg-card` + `size-6` ikon; ortadaki karo `size-24 rounded-3xl border border-slate-200 bg-card`. Renkli soluk zemin (`bg-orange-50/60`, `bg-primary/10`) kaldırıldı: karo dolu olmalı ki çizgi içinden görünmesin. Gölge yok (§6). - **Kartsız, zeminsiz; bilgiler iki yanında, onlar da kartsız** (Bilal, 7 Eki 2026: "kartın dışında, arka plansız, sağında solunda da alttaki bilgiler olacak şekilde"; aynı gün: "hero'daki gibi ferah"). Geniş ekranda (lg+) üç sütun (`lg:grid-cols-[minmax(0,1fr)_22rem_minmax(0,1fr)]`, xl'de orta 24rem, dikeyde ortalı): **solda dürüstlük notu** — `SectionEyebrow` + `h3` (`font-heading text-2xl font-bold text-balance`, ikinci yarısı hero başlığındaki vurgu: `font-bricolage font-bold tracking-tighter text-primary italic`) + `text-base` paragraf, sola yaslı, `max-w-xs`; **ortada animasyon**; **sağda üç sayı** alt alta, sağa yaslı (YÖK Atlas girdilerinin yanında — sayılar o verinin sayılarıdır). Sayı §1.1: `font-heading text-4xl font-bold leading-none tracking-tight text-primary sm:text-5xl`, birim ("yıl") §3'teki gibi `font-sans text-base font-semibold text-slate-400`, etiket `text-sm font-semibold text-slate-500`. Çerçeve, zemin, ayırıcı çizgi ve sayının yanında piksel süs **yok**. lg altında tek sütun, her şey ortalı: animasyon → sayılar (sm'de üçü yan yana) → dürüstlük notu. - **İşaret site başlığındaki logonun animasyonunu oynar** (`AnimasyonluMark`, varsayılan "rota": kareler sırayla birbirinin yerine süzülür). Başlıkta üzerine gelince, burada ekrandayken sürekli (`oynat`); ekrandan çıkınca kareler yerine oturur. Nabız + tüm karoyu döndüren eski hâl (`kt-akis-donus`) yanlıştı ve kaldırıldı (Bilal, 7 Eki 2026). Hareketi azalt'ta durağan. ### 4.29 Program duvarı — `ProgramDuvari`, `src/features/pazarlama/components/program-duvari.tsx` **Şu an sayfada kullanılmıyor:** ana sayfa "Sorun" bölümünden 7 Eki 2026'da çıkarıldı (Bilal: "diğer ana sayfa bileşenleri eski hâline gelsin"); bölüm yine yalnız üç kartla açılır. Dosya duruyor. Tarif: "Binlerce ihtimal"in resmi: aramadaki mini pencere dilinde (`rounded-2xl`, üç noktalı `h-9` çubuk, §4.20) bir tuvalde piksel kareler satır satır akar — her kare bir program; aralarında **tam 24 turuncu kare** sırayla belirir ve yerinde kalır (senin listen). İmleç yaklaştığı satırları hızlandırır. Izgara hero'nun ölçüsü (hücre 10, nokta 7.4, köşe 2), mavi doku opaklıkları aynı; renk CSS'ten okunur, tema değişince yeniden çizilir. Tek ``, ekrandayken ~30 fps; hareketi azalt'ta durağan. Anlamı altındaki cümle söyler. Esin React Bits "Squares Terminal"; koyu CRT ekranı, parlama ve tüp eğimi **alınmadı** (koyu yüzey yalnız kapanışta, §1.2; parlama gölgesi yok, §2.2). ### 4.30 Süzülen haplar — `SuzulenHaplar`, `src/features/pazarlama/components/suzulen-haplar.tsx` Ana sayfa "Katalog ücretsiz" bölümü: en çok aranan bölüm ve şehir sayfalarına giden haplar (§4.12 kimlik hapı, `GraduationCap` / `MapPin`, hover §2.1; her üçüncü hap bir kademe iri). Bölüm ekrana girince haplar yukarıdan hafif eğik düşüp oturur (tek, hafif sekme — düşen nesne, §6); imleç gezdikçe her hap kendi derinliğinde en çok 18 px süzülür, arkadaki piksel kareler ters yöne kayar. Haplar akışla dizilir (375 px'te üst üste binmez) ve SSR'da görünür linktir; yalnız katalogda sayfası olan adlar çizilir. Dokunmatikte süzülme yok; hareketi azalt'ta yalnız belirir. Esin React Bits "Parallax Pills"; kod bizim. ### 4.31 Piksel sahne ve sahne kartı — `PixelSahne`, `src/components/pixel-decor.tsx` Bilal (7 Eki 2026): "landing'de en beğendiğim yer hero'daki Türkiye kısmı; buradaki gibi ferah ve marka kimliğimizi yansıtacak şekilde sıkıcı kart tasarımlarını da güncelle." Hero haritasının dili (hücre 10, nokta 7.4, köşe 2, altı opaklık, imleçle turuncuya ısınma, nabız atan turuncu vurgu) küçük resimlere taşınır. Sahne, harita gibi satır satır bir ızgaradan çizilir: `#` doku pikseli, `-` silik piksel, `o` turuncu vurgu. - **Sahne süs değildir, kartın söylediğini çizer.** Ana sayfa "Sorun" kartları: "24 tercih, binlerce ihtimal" → yoğun piksel alanı, içinde **tam 24** turuncu kare; "Geçen yılın puanı yetmiyor" → her yıl başka boyda altı çubuk, yalnız sonuncusunun tepesi turuncu; "Danışman lüks haline geldi" → basamak basamak tırmanan merdiven, tepesi turuncu. Ne çizeceğini bilmediğin karta sahne koyma; rastgele doku sahne değildir. Sayı söyleyen sahnede (24) kare sayısı tutar. - **Sahne kartı** (§4.4 sınıfı): üstte sahne yuvası `border-b border-slate-100 bg-slate-50 px-6 py-8` (hero'yla aynı zemin), altında `p-6` içinde `h3` (`font-heading text-xl font-bold text-balance`) + `mt-2 text-base leading-relaxed text-slate-600`. Kartta ikon kutusu ve köşe pikseli yok — sahne ikisinin yerini tutar. Izgaralar 24×8; üç kart aynı boyda sahne taşır. - **Zemin değildir.** §10.8'deki "piksel zemin yalnız CTA yüzeylerinde" kuralı sürer: sahne yazının arkasına serilmez, kendi yuvasında durur ve üstüne metin gelmez. Çekmece, modal ve katalog kartlarına sahne konmaz (§4.8: özet kartının içinde piksel seri "çok boğdu"). - `ton="dolgun"` aynı dokunun koyu hâlidir (opaklık 0,64–1); okunması gereken şekiller (rakam) için. Sahne `aria-hidden`'dır; anlamı başlık taşır. ### 4.32 Adım rakamları — `PixelRakam`, `src/components/pixel-decor.tsx` Ana sayfa "Nasıl çalışır"ın üç adımı **kartsızdır** (Bilal, 7 Eki 2026, §4.31'deki istek): adım numarası hero'nun piksel diliyle yazılmış iri rakamdır (5×7 ızgara, `h-24`, `ton="dolgun"`), altında `h3` (`mt-6 font-heading text-xl font-bold text-balance`) ve `mt-2 max-w-sm text-base leading-relaxed text-slate-600`; her şey ortalı. `md`'den itibaren rakamlar düz bir çizgiyle birbirine bağlanır (`h-0.5 rounded-full bg-slate-200`, rakamın ortasında; veri akışındaki düz çizgiyle aynı dil). Telefonda adımlar alt alta, çizgisiz. Yapı `ol > li`; rakam `aria-hidden`, başlığın başında `sr-only` "1. adım:". Turuncu numara rozeti, ikon ve kart çerçevesi kaldırıldı. Yeni bir rakam gerekirse ızgarası `RAKAMLAR`'a eklenir (bugün 1–3). ### 4.33 Soru formu — `questionnaire.tsx` (shadcn Questionnaire) + `SohbetAnketi`, `sohbet-anketi.tsx` shadcn'in `questionnaire` kayıt öğesi (ilkel `@shadcn/react/questionnaire`) sitenin diline çevrildi: `muted / input / foreground` token'ları yok. Sorular **tek tek** gösterilir; sağ üstte ilerleme `1 / 3` (`text-xs font-semibold text-slate-500 tabular-nums`). Seçenek satırı §4.4 sade kutu + §4.17 çip dili: `min-h-11 rounded-2xl border border-slate-200 bg-card px-3.5 py-2.5 text-sm font-semibold text-slate-700`, hover tek turuncu, seçili `border-primary bg-primary text-white` ve başındaki kutu tik olur (seçili hâl renk + tik, §2.2); sağda klavye harfi küçük kutuda. Serbest cevap alanı §4.6 hapı (`h-11 rounded-full`). Düğmeler sitenin `Button`'u (`sm`): Geri (outline), Atla (ghost; yalnız zorunlu olmayan soruda), İleri / "Cevapları gönder" (default). Hata `text-sm font-medium text-red-600`. Kapanmış form tek satır: "Formu cevapladın." (yeşil tik) ya da "Form kapandı; isteğini yazarak söyleyebilirsin." Yeni bir anket/soru akışı gerekince bu bileşen kullanılır; radio/checkbox'lı yeni form tasarlanmaz. ## 5. Yerleşim ### 5.1 Genel - 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 adlar sarar (§4.15); tablo yatay kaydırmaz, dar ekranda sütunlar satır altına iner; sabit alt çubuk klavyeyle çakışmaz; `vh` yerine `dvh`. ### 5.2 Geniş ekran dışında ortala Alt sayfaların (katalog, detay) başlık bloğu **`lg` (1024 px) altında ortalı**, `lg`'de sola yaslıdır — mobil uygulama gibi telefonda ve tablette her şey ortada, masaüstünde tablo ve kartlarla aynı hizada: - Yol satırı: `flex flex-wrap items-center justify-center gap-1.5 text-sm text-slate-500 lg:justify-start` - Logo + h1: `flex flex-col items-center gap-4 text-center lg:flex-row lg:text-left` — logo telefonda **başlığın üstünde, ortada**. - Kimlik hapları: `flex flex-wrap items-center justify-center gap-2 lg:justify-start` - Özet paragraf: `mx-auto … text-center lg:mx-0 lg:text-left` - Sayfa ayracı: `mx-auto … lg:mx-0`; liste bölümü ve grup başlıkları `text-center lg:text-left`. - **Ortalanmaz:** liste/tablo satırlarının içeriği (göz satırdan satıra kayarken ortalı liste yorar), form alanları, uzun rehber metni. - Alt sayfa (§4.10) içeriği her ekranda ortalıdır. ### 5.2.1 Sayfalama — `Sayfalama`, `sayfalama.tsx` Haplar `h-11` (44 px), hover §2.1. Telefonda (sm altı) tek satır kalsın diye yalnız Önceki · aktif sayfa · Sonraki görünür; diğer numaralar `hidden sm:inline-flex` ile HTML'de durur (tarayıcı botları tüm sayfaları görür). 375 px'te 7 sayfalık şerit iki satıra kırılıyordu. ### 5.2.2 Dilim sekmeleri (Hayal / Dengeli / Güvenli) — `program-tablosu.tsx` Tek satırda üç hap 375 px'e sığmıyordu (418 px, sayfa yana kayıyordu). Telefonda `grid w-full grid-cols-3`, hapın içinde ikon+ad üstte, sayı altta; sm'den tek satır. Hap en az 44 px (`min-h-11`), hover §2.1. ### 5.2.3 Karşılaştırma tablosu (ana sayfa) — yatay kaydırma yok Dört sütunlu tablo yalnız `lg`'de. Altında her özellik kendi satırında (başlık ortalı `text-base font-semibold`), üç cevap altında üç sütun; KolayTercih sütunu `bg-primary/5` kutuda. Sütun adları üstte yapışık: `sticky top-24 sm:top-32` (site başlığı telefonda 96 px, sm'den itibaren 128 px — ölçüldü). Bilal, 25 Eyl 2026: "kaydırması gerekiyor, olmamalı". ### 5.3 Verimli ve havadar - İlişkili öğeler yan yana dizilir (iki sütun) — tek sütunda alt alta uzayan panel yapılmaz. - Yan yana dizmek "hepsini tek şeride sıkıştırmak" değildir: 23 Eyl'de denenen yatay "bilgi şeridi" (harita dahil altı değer tek satırda, yana kayan) reddedildi — harita küçüldü, sayılar ezildi, ekran kalabalıklaştı. ## 6. Derinlik, katman ve hareket 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ç). Sahne kartları (§4.31) hover'da 4 px yükselir. Modal arka planı `bg-black/10` + hafif blur. Yığın: içerik < sabit bar < çekmece/modal (`z-50`). Hareket kuralları (Apple, `motion/react`): - Varsayılan yay: `{ type: "spring", bounce: 0, duration: 0.35 }` — sekmesiz, sakin. Sekme yalnızca kullanıcı bir şeyi fırlattıysa (sürükle-bırak). - Arc UI'dan taşınan bileşenlerin yayları, eğrileri ve lastik direnci tek dosyada: `src/lib/hareket.ts` (`YAY.akici` panel/yığın, `YAY.donusum` biçim, `YAY.birakma` parmak bıraktıktan sonraki tek hafif sekme). Yeni bir Arc bileşeni yay uydurmaz, buradan alır; sınıflar Arc'ın CSS modülünden değil bu belgeden gelir. - Giriş ve çıkış **aynı yoldan** (aşağıdan geldiyse aşağı gider). - Basınca anında tepki: `active:scale-[0.97]` (buton), `[0.99]` (geniş satır), `[0.96]` (çarpı). - Hover'da ok `translate-x-0.5` kayar; kart yükselmesi yalnız landing kartında. - Kaydırmaya bağlı tetik `IntersectionObserver` ile (kaydırma dinleyicisi değil). - "Hareketi azalt": kayma/yay yok, yalnız opaklık (`useReducedMotion`, `motion-reduce:transition-opacity`). ## 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 ve hover = orange-500 | `indigo/purple` primary, mor→mavi gradyan, `gray/zinc` nötr | | Hover'da tek turuncu (`orange-500`); liste satırı adı mavi (§2.1 istisnası) | Liste dışında hover'da mavi; aynı ekranda `orange-600` yazı + `orange-300` kenarlık | | Kart: `rounded-2xl border-slate-200 bg-card shadow-sm` | Her şeyde `rounded-3xl`, camsı `backdrop-blur` kartlar, parlama gölgesi | | Sayı kartın en iri öğesi, ikon sağda küçük | İkon üstte büyük, sayı küçük; BÜYÜK HARFLİ `text-xs` etiket | | Sayfada ≤4 özet sayı, fazlası ayrıntı satırı → alt sayfa | 6+ kartı sayfaya dizmek ya da hepsini yatay şeride sıkıştırmak | | Harita gibi nefes alanını olduğu gibi bırakmak | Nefes alanını küçültüp bilgi şeridine gömmek | | Alt sayfada kartsız, ortalı, tek ekrana sığan içerik | Çekmece içinde çerçeveli kart; bölümler arasında süs piksel ayraç | | Gösterge kareleri masonry (kaymış sütun, farklı boy) | Hizalı eşit ızgara; 8 px'lik "neredeyse hizalı" kaymalar | | Liste satırında ad sarar, sayı alt satıra iner | `truncate` ile yarım ad; 32 px satır butonu | | Hareket: `Reveal`, piksel ısısı, `kt-unblur`, sekmesiz yay; `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, 10–11 px yazı | | Risk rengi + metin etiketi; tür ayrımı ikonla | Renk tek başına, "yerleşirsin" gibi vaat cümlesi | | Üç kart yalnızca üç gerçek öğe varsa | Hero + üç kart iskeleti refleksi | | Yüzey `bg-card`, tek koyu vurgu yüzeyi; karanlık mod token'dan (§2.3) | `dark:` sınıfı, yüzeyde `bg-white`, koyu hapta `text-white` | | Kapatma çarpısı `DialogContent` varsayılanı | Başka boyut/renkte çarpı | | Form alanı hap: `Input`/`SelectTrigger` varsayılanı (`h-12 rounded-full`), yalnız yerleşim sınıfı eklenir | Kullanım yerinde `h-9 rounded-lg bg-background`; kenarlıklı ham ``; `md:text-sm` | ## 8. Duyarlılık - Kırılma noktaları: 375 (temel), 640 `sm:`, 768 `md:`, 1024 `lg:`. Her bileşen önce 375'te tasarlanır. Ortalı ↔ sola yaslı geçişi `lg`'dedir (§5.2). - 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-5xl` alt sayfa h1), gövde 16 px altına inmez. - Modal genişliği `max-w-[calc(100%-2rem)]`; ayrıntı her zaman alt sayfada (`AltSayfa`, §4.10), alttan açılır. - Çekmece içeriği 375×812'de kaydırmasız sığar (§4.10). - `prefers-reduced-motion`: her animasyonun sade karşılığı var (`motion-reduce:animate-none`, `.kt-unblur-sade`, `useReducedMotion`). ## 9. Ajan için brief şablonu ve iş akışı ### 9.1 Brief Yeni bir UI işi istenince önce şu beş 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 üniversite sayfası. Tek kaynak: Kullanılacak kanonik parçalar (SectionEyebrow, Button+ArrowRight, OzetKart, AkademikAyrinti, NavBaslik…) Durumlar: boş / yükleniyor / hata / başarılı / girişsiz / kredisiz — hangileri var? His: Ekranın tek ana işi ne? Hangi 4 sayı önde, ne bir dokunuş derinde? ``` "Modern", "temiz", "şık" gibi yön belirtmeyen kelimeler kullanılmaz; yön = bu dosya. ### 9.2 Ölç, tahmin etme Bu dilde sorunların çoğu koddan görünmez (taşma, sığma, hizalanma). Tasarım işinde: - **Sığma:** metin genişliğini tarayıcıda ölç (gizli `span` + `getBoundingClientRect`); "sanırım sığar" ile yazma. Örnek: özet kartında "13.889" 36 px'te 95 px. - **Hizasızlık:** masonry'de karelerin `top`/`bottom` değerlerini ölç; komşu fark ≥ 24 px. - **Tek ekran:** çekmecede kaydırma kabının `scrollHeight` ≤ `clientHeight` (375×812). - **Genişlikler:** 375 / 768 / 1280 px'te bak; ortalı ↔ sola yaslı geçişini `lg`'de doğrula. - **Uç veri:** en uzun ad ("Adana Alparslan Türkeş Bilim ve Teknoloji Üniversitesi"), en büyük sayı, verisi eksik kurum (URAP'ta olmayan, istatistiği olmayan). ### 9.3 Tuzaklar (23 Eyl 2026'da yaşandı) - **Prettier'ı toplu çalıştırma.** Depo prettier düzeninde değil; bir dosyayı prettier'dan geçirmek yüzlerce satırlık biçim farkı üretir ve başkasının kaydedilmemiş işine karışır. Yalnız kendi yazdığın satırları elle düzenle. - **Geliştirme sunucusunda ilk tık.** Kod değişikliğinden hemen sonra sunucu derleyip sayfayı tazeleyebilir; o anda yapılan tıklama boşa gider. "Çekmece açılmıyor" demeden önce sayfa hazır olduktan sonra tekrar dene. - **Sayfada ikinci `
`.** Bölüm sayfasında içerik `
`'ı var; site üst çubuğunu `querySelector("header")` ile değil, bilinen bir öğenin `closest("header")`'ı ile bul. - **"use client" dosyasından sabit import etme.** Sunucu bileşeni o sabiti değer olarak değil istemci referansı olarak alır; paylaşılan sabit ayrı dosyada durur ya da elle yazılır. ### 9.4 Site taraması için denetim uyarıları `pnpm tasarim:denetim` bu dilin eski izlerini **uyarı** olarak listeler (lint'i kırmaz, dönüşüm listesidir): `minik-yazi` (10–11 px), `buyuk-harf-etiket` (uppercase + tracking-wide), `mavi-hover` (§2.1), `iri-sayi-tabular` (Cal Sans + tabular-nums), `ham-input` (§4.6 kenarlıklı ham input). `mavi-hover` §4.15 kanonik liste satırı adını (`text-base font-semibold leading-snug` + `hover:text-primary hover:underline` aynı satırda) kendiliğinden atlar — istisna uyarı vermez (Bilal'in kararı, 24 Eyl 2026). Eski `truncate text-sm` adlar yine uyarır; önce §4.15'e çevrilir. Bir ekranı dönüştüren ajan o ekrandaki uyarıları sıfırlar ya da neden kaldığını yazar. **Bilerek bırakılan uyarılar (24 Eyl 2026 taraması sonunda 12):** - `meraklisina-demo.tsx` (8 × minik-yazi): SVG `viewBox` 640 birim; 375 px'te 0,54 ölçekle çiziliyor, 11 birimlik yazı ekranda 5,9 px (ölçüldü). 12'ye çıkarmak yalnız 6,5 px eder ve etiketler çakışır — çözüm telefona ayrı (dikey) çizim; ayrı iş. - `secimlerim-paneli.tsx` (4): hiçbir yerde kullanılmıyor (ölü kod); dönüştürülmedi, silinmesi ayrı iş. ### 9.5 Bitirmeden `pnpm tasarim:denetim` sıfır hata (uyarılar raporda listelenir) + 375 px'te tek bakış (taşma, üst üste binme, dokunma hedefi, çekmece tek ekran) + §9.2 ölçümleri. - Yeni ayrıntı paneli mi? `Dialog` değil `AltSayfa` (§4.10, §4.19). İçinde tablo mu? §4.15 sınıfları, hücre `text-sm`, `text-xs` yok. Buton mu? Gölge yok, hover tek turuncu (§2.1, §6). ## 10. Samimi ton, ilerleme ve kutlama (öğrenci ekranları) Bilal'in isteği (25 Eyl 2026): "Duolingo gibi basit ve oyunsu, Apple gibi irdeleyici, samimi." Araştırma ve kaynaklar: `docs/tasarim/2026-09-25-samimi-arayuz-arastirmasi.md`. Özü: bizim öğrencimiz için samimi = **güven**; neşe dayatılmaz. ### 10.1 Her ekranın tek cümlelik cevabı - Öğrenci ekranı `h1` ile açılır ve ilk paragraf öğrencinin kendi durumunu sayıyla söyler. Örnek (`/sonuc`, `SonucBasligi`): "**85.000.** sıradasın (Sayısal). **4.760 program** sana açık; aşağıda riskine göre ayrıldı." - Altında liste durumu (`ListeDurumuSatiri`): boşsa ne yapılacağı, doluysa "Listende 5/24 program · 19 yer kaldı" düğmesi (çekmeceyi açar). ### 10.2 İlerleme - Sayıyla ve dürüst: "7/24", "Adım 2/3: Şehir". Yüzde, sahte hız, yapay ilerleme yok. - Sihirbaz adım göstergesi adlı (Alan · Şehir · Öncelik); dolum `scale-x` ile soldan, `duration-300 ease-[cubic-bezier(0.23,1,0.32,1)]`, hareketi azalt'ta geçişsiz. - Liste çekmecesinde risk dağılımı metinle (`RiskEtiketi` + sayı). Riskleri bilinen 6+ tercihli listede güvenli yoksa tek cümle ipucu — vaat değil, gerekçe. ### 10.3 Kutlama - Yalnız öğrencinin kendi yaptığı küçük adımda: ilk program (1/24) ve dolu liste (24/24). Bir kez, sakin bir bildirimle; aradaki eklemeler sessiz (düğme ✓, sayaç artar). - Yerleşme gibi **sonuçlarda kutlama yok**; açıkta kalan öğrenciye neşeli dil yok. - Hareket: `starting:scale-95 starting:opacity-0` + güçlü ease-out, 300 ms altı; konfeti, ses, sekme (bounce) yok. Hareketi azalt'ta yalnız opaklık. ### 10.4 Metin - Sen dili, etken çatı, fiil düğme ("Listemi aç", "Sıralamamı gir"). Şirin/zekice etiket yok. - Hata: ne olduğu + ne yapılacağı; suçlama ve ünlem yok. "Hay aksi", "Eyvah", "Oops" yok (denetim: `samimiyetsiz-unlem`). "Buraya tıkla" yok; link ne açtığını söyler. - Bekleme metni "…" ile biter ("Kontrol ediliyor…"). - "Kredi" dili: gerçek parayı sanal birime çevirmek aldatıcı desenler listesinde ("para birimi karmaşası"). Kredinin TL karşılığı pakete göre değiştiği için (≈4–5 TL) ekranda TL gösterip göstermemek Bilal'in kararına bırakıldı (25 Eyl 2026, açık). ### 10.5 Geri alınabilir işlem - Listeden çıkarma ve listeyi temizleme anında olur ama 8 sn "Geri al" bildirimi verir; çıkanlar eski sıralarına döner (`geriAlinabilirCikar`, `liste-cekmecesi.tsx`). Beklenen işlemde "Emin misin?" penceresi açılmaz (Apple: beklenen kayıpta uyarı yok). ### 10.6 Anlamsal yapı - Sayfa başına tek `h1`; bölümler `h2`. Başlıklarda `text-balance`. - Odak almayan durum değişikliği ekran okuyucuya duyurulur: `role="status"` (liste sayacı, sihirbaz adımı, bekleme). Bildirim yığını (§4.16) bunu kendisi yapar. - Açılır satır: `aria-expanded` + `aria-controls` (APG disclosure). - Site geneli "İçeriğe geç" linki `layout.tsx`'te; içerik kabı `#icerik`. - Çekmece kaydırma alanı `overscroll-contain`. ### 10.7 Almadıklarımız (Duolingo'dan) Seri (streak), kayıp korkusu, puan/XP, rozet koleksiyonu, liderlik tablosu, maskot, sahte aciliyet/kıtlık, utandırarak onay. Tercih günlük alışkanlık değil, tek seferlik kaygılı bir karar. ### 10.8 CTA bandı — `CtaBandi`, `src/components/cta-bandi.tsx` **Kanonik CTA bandı — mavi zemin + `PixelMasonry`** (Bilal'in kararı, 24 Eyl 2026: "Kendi Listem" çekmecesindeki bandın eski hâli daha güzeldi; örnek odur). Kabuk tek kaynaktan gelir, içerik çağıranındır: ```tsx {/* buyuk: ortalı, px-5 py-8 sm:p-12 */}

…

…

…başlık + alt satır solda, buton sağda (çekmece)… ``` Çekmecedeki kompakt bandın açık hâli (bileşenin ürettiği sınıflar): ```tsx

Risk analizini biz yaptık

Her seçimin yerleşme riski hazır — son kararı sen ver.

``` - Zemin `bg-primary` (sitenin mavisi), köşe `rounded-2xl`, yazı beyaz; alt satır da beyaz (`text-white`, `slate-300` değil). Piksel dokusu `PixelMasonry` (Bilal, 24 Eyl 2026: "arka planda büyüklü küçüklü, masonry şeklinde"): 2–4 hücrelik kareler 4×4'lük makro hücrelere kaymış düşer, çakışmaz ama hizaya girmez. Doku **kabın gerçek ölçüsüne göre** üretilir (ResizeObserver; sabit çizimi ölçeklemek yüksek kartlarda görünen kısmı boş banda düşürüyordu, 24 Eyl 2026'da yaşandı): kısa kenarın %30'u kadar kenar çerçevesi kenara doğru yoğunlaşır, orta tamamen boş; küçük kare yok (2–4 hücre), iri kare daha silik; **durağan** — imleç ısı fırçasına katılmaz, üzerine gelince hiçbir şey olmaz (Bilal, 24 Eyl 2026); yalnız seyrek turuncu vurgu kareleri kendi kendine yavaşça nefes alır. Kap `relative isolate overflow-hidden`, doku `-inset-y-6 -z-10`. Eşit ızgaralı eski `PixelField` kaldırıldı. - Tek turuncu buton, metin önce ok sonda (§4.1). Telefonda alt alta ve tam genişlik; `sm`'de yan yana, buton sağda. - Büyük (sayfa kapanışı) hâlinde aynı band ortalı ve iri: `px-5 py-8 text-center sm:p-12`, `-inset-y-10`, h2 `font-heading text-2xl font-bold sm:text-3xl`, paragraf `text-white/90`. - Kullanıldığı yerler: `/sonuc`'taki üç panel (sihirbaz, giriş bekleyen, "24 tercihlik listen hazır"), `/meraklisina` kapanış kartı (`DemoKapanisCta`), katalog altındaki `CtaSiraForm` kart varyantı, "Kendi Listem" çekmecesinin altı (kompakt), katalog üstü kompakt satırın **kayıtlı sıralamalı** hâli ("Sıralaman … tabanlarının neresinde? · Sıralaman kayıtlı: …"; Bilal, 24 Eyl 2026: "bu kısma piksel dokusu ekle"). O satır CLS için tek `section` içinde iki hâl taşıdığından `CtaBandi`'yi sarmaz; kompakt bandın sınıf setini birebir alır (`relative isolate overflow-hidden rounded-2xl bg-primary px-5 py-4 text-left text-white sm:py-5` + ilk çocuk `PikselZemin`), kenarlık saydam kalır ki iki hâlin kutusu aynı olsun. Aynı sayfadaki iki band farklı `seed` alır. **Piksel zemin yalnız CTA ve başlık yüzeylerinde — `PikselZemin`, `src/components/piksel-zemin.tsx`** (Ana sayfa kartlarındaki piksel **sahne** zemin değildir; kendi yuvasında duran resimdir, §4.31.) (Bilal, 24 Eyl 2026: önce "her CTA benzeri kısmın arkasında olmalı", sonra "/sonuc'taki kartın arkasına da piksel koymuşsun; pikseller CTA'larda olacak sadece"). CTA yüzeyi = çağrı yüzeyi: mavi `CtaBandi`, koyu kapanış kartı `PikselCtaYuzeyi`, arama penceresindeki koyu kart. **Ton ikidir:** `ton="koyu"` (renkli zemin, beyaz kareler) ve `ton="acik"` (beyaz zemin, `text-slate-400` kareler; turuncu vurgu kareleri aynı). Bilal (24 Eyl 2026): "her kısımda mavi arka kullanmışsın, çeşitlendir; beyaz arka planda piksel de güzel görünüyor" — bu yüzden `CtaBandi ton="beyaz"` (slate kenarlık, koyu yazı, paragraf `text-slate-600`) var ve aynı sayfada iki bant üst üste gelmesin diye dönüşümlü kullanılır: `/universiteler` altı ve `/meraklisina` kapanışı beyaz; şehir sayfası altı, `/sonuc` panelleri, çekmece altı mavi. Şehir sayfasının başlık yüzeyi (§4.17) de açık tonlu piksel zemindir. Beyaz içerik kartlarına (tadımlık, `/listem` üretim/kilit kartları, paket kartı, kaydet bandı, katalog üstü kompakt satırın **form** hâli, boş durumlar, sıralama-yok sayfası) **konmaz** — 24 Eyl'de denendi ve geri alındı. Aynı kompakt satırın kayıtlı sıralamalı hâli ise formsuz tek butonlu bir çağrı olduğundan mavi banttır ve dokuyu alır (yukarıda). Kap `relative isolate overflow-hidden`; zemin ilk çocuk; kareler beyaz. Doku kabın gerçek ölçüsüne göre üretilir: yalnız kenar çerçevesinde (kısa kenarın %30'u), orta tamamen boş; **küçük kare yok**, 2–4 hücrelik (17/27/37 px) kareler, iri olan seyrek ve daha silik (Bilal: "çok fazla piksel, küçük olanlar hiç olmasın"). **Kapanış yüzeyi — `PikselCtaYuzeyi`, `src/components/piksel-cta-yuzeyi.tsx` (yalnız ana sayfa kapanışı "Tercih listen, pişmanlık listesi olmasın").** Bilal'in kararı (24 Eyl 2026): "orası bayağı iyiydi; özellikle 24'lük pikseller tablo gibi — bu tür kreatif, interaktif şeyler çok güzel." Arama penceresindeki kartın dili: `rounded-3xl border border-blue-400/20 bg-slate-950 text-white`, arka planda `PixelMasonry` (seed ile), tek turuncu CTA. **Yazılıp silinen satır yok** (Bilal, 24 Eyl 2026: kaldırıldı); `FUNNEL_METINLERI` yalnız arama penceresindeki kartta (`arama-funnel-karti.tsx`) kalır. - **Kreatif — `PikselListe`, `src/components/piksel-liste.tsx`:** 24 kare = 24 tercih, hero'nun nokta ölçüsüyle (hücre 10, nokta 7.4, rx 2). Örnek modda liste kendini kurar (5 hayal · 13 dengeli · 6 güvenli, 110 ms arayla), yalnız ekrandayken. İmleç yakın kareleri büyütür; kart içindeki düğmeye imleç/odak gelince 24 kare birden dolar; dokunmada basılan kare ve komşuları nabız atar (`kt-piksel-nabiz`). Hareketi azalt: dolu, durağan. Renk her zaman `PikselListeAciklama` metniyle. - Piksel tablosunun arkası boş kalır (Bilal, 24 Eyl 2026: "arkasına çok piksel yığılmış"): tablo kabı `haric` ile zemine verilir, doku onun çevresini (14 px payla) her genişlikte boş bırakır. Kural genel: bir kreatif ya da iri sayı piksel zeminin üstüne geliyorsa `haric` ile boşaltılır; doku ile kreatif üst üste binmez. - Bu yüzey **sayfada bir kez** ve yalnız kapanışta durur; ara paneller ve çekmece mavi banttır. Yeni bir kreatif fikri (veriyi piksele çeviren, imlece tepki veren) önce burada denenir. - Çekmece başlığında denenen "gerçek liste" pikseli (12×2, her kare tercihin riski) **kaldırıldı**: başlığı çok dolu gösteriyordu (Bilal, 24 Eyl 2026). Başlık sayı + ilerleme çubuğu + risk dağılımı metniyle kalır. ### 10.9 Kayıtlı sıra satırı (katalog üstü, profilli) — `cta-sira-form.tsx` kompakt Bilal (24 Eyl 2026): "bu kısım UI kötü, Apple görünümü yok, yazılar küçük". §1.1 "sayı kahramandır" uygulanır: mavi bantta (§10.8 kompakt kabuk + `PikselZemin`) **iri kupa kutusu** (`flex size-14 items-center justify-center rounded-2xl bg-white/15` + `Trophy size-7`), yanında sıra `font-heading text-3xl font-bold leading-none tracking-tight sm:text-4xl` (Cal Sans'ta tabular-nums yok, §3) ve altında `text-sm font-semibold text-white/80` "sıra · Sayısal"; başlık `font-heading text-xl font-bold leading-tight text-balance sm:text-2xl`. **Buton yazısız** (Bilal, 24 Eyl 2026: "buton cılız kaldı, yazılı bir buton olmasın" — §4.1'in "metin + sondaki ok" kuralının bilinçli istisnası): `flex size-14 items-center justify-center rounded-full bg-orange-500 text-white` + `ArrowRight size-7`. **Gölge yok** (§6: derinlik gölgeyle verilmez; ilk sürümdeki `shadow-lg shadow-orange-500/30` kaldırıldı) ve **hover'da renk değişmez** — iri dolu turuncu yüzeyde `orange-600` kırmızımsı okunuyor (Bilal, 24 Eyl 2026); tepki `hover:scale-[1.04]` + ok 2 px kayar, basınca `scale-[0.95]`. Metinli CTA butonlarında `hover:bg-orange-600` kanonik kalır (§2.1); `aria-label` + `title` "Sıralamana uygun programları gör". Bandın tamamı gerilmiş linkle (`after:absolute after:inset-0`, §4.8) tıklanabilir. **Telefonda iki satır:** başlık (`text-lg`) üstte, altında kupa+sayı ile ok **yan yana** (`flex justify-center gap-5`; kupa kutusu ve ok telefonda 48 px, sm'den 56 px); lg'de tek satır (sayı · başlık · ok). Blok formun yüksekliğini **aşamaz** — aşarsa `overflow-hidden` kap üstten kırpar (24 Eyl 2026'da üç satırlı ilk sürümde başlık kesildi; ölç, §9.2).