main'deki b2bab50 ile aynı içerik (surum.ts, surum-rozeti.tsx, header, AGENTS.md
sürümleme kuralı, DESIGN.md §2.2/§4.14); bu dal 2.0.0 geliştirme sürümü.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
100 KiB
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 (
PixelMasonryile: 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 linklerdehover:underlinekalır). - Tıklanabilir kart / satır:
hover:border-orange-500 hover:bg-orange-50/60; içindeki iri sayı ya da başlıkgroup-hover:text-orange-500; sağdaki okgroup-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-600yazı,orange-300kenarlı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/30kullanan yerler var (landing kartı dahil); tarama sırasında bu kurala çevrilir. Denetim bunlarımavi-hoveruyarısıyla listeler; liste satırı adındaki uyarı istisnadır, dokunulmaz.
2.2 Palet kuralları
- Nötr yalnızca slate.
gray,zinc,neutral,stoneyazılmaz. indigo,purple,violet,fuchsia,pink,cyan,teal,lime,green,yellowyeni kullanım açmaz. Tek istisna "Gösterge karesi" satırındaki dolubg-indigo-500vebg-green-600zeminleri (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-600tek bir mevcut durum çipidir; yeni yere taşıma — üniversite sayfasında "Vakıf" çipi bu yüzden hap + ikonla değiştirildi, §4.12.) İkinci istisna: üst çubuktaki "Beta" sürüm rozeti, dolubg-indigo-500(§4.14, Bilal'in kararı, 7 Eki 2026) — gösterge karesiyle aynı mor, yine yalnız dolu zemin.- 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.tsiçindekiRISK_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 aztext-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, <html class="dark">). 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-whitedeğil.bg-whitekoyu 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ündekibg-white/15ikon kutusu. - Koyu hap (
bg-slate-900: "Giriş yap", "Ara", sekme göstergesi, toast düğmesi) yazısınıtext-slate-50ile alır,text-whiteile değil: koyu temada hap açığa, yazı koyuya döner. - Koyu vurgu yüzeyi (
bg-slate-950:PikselCtaYuzeyi,AramaFunnelKarti)kt-koyu-yuzeysınıfını taşır; iki temada koyu kalır, içindeki açık slate metinler çevrilmez.slate-950metin 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-cevirile açığa çevrilir; yazdırma çıktısı her zaman açıktır (.darkbloğu@media screeniçinde). - Yeni bir renk tonu ilk kez kullanılıyorsa (
bg-sky-50gibi).darkbloğ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<span className="font-bricolage italic tracking-tighter font-bold text-primary"> - 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(istenirsetext-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 datext-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-smyalnız ikincil bilgide,text-xsyalnı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-xskalıbı ("PROGRAM", "TOPLAM KONTENJAN") yazılmaz; etiket büyük-küçük harfli,text-sm font-semibold. - İri sayıda
tabular-numsyok: Cal Sans'ta sabit genişlikli rakam "daktilo" gibi aralıklı durur ("13.88 9").tabular-numsyalnızfont-sanstablo 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-9varsayılan,h-11/h-12funnel CTA'ları (44 px dokunma hedefi),size-9ikon butonu. - Odak:
focus-visible:ring-3 focus-visible:ring-ring/50; basıncaactive:translate-y-px. - Turuncu CTA (kanonik):
Metin önce, ok sonda. Başta ikon yok.
<Button size="lg" className="cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600"> Listemi oluştur <ArrowRight className="size-4" aria-hidden /> </Button>Sparklesyok. İstenirseactive:scale-[0.97]. - İkincil gezinme butonu ("Tüm sıralamayı gör →"):
<Button asChild size="lg" variant="outline" className="cursor-pointer px-6 transition-[background-color,border-color,color,transform] duration-150 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 active:scale-[0.97]"> <Link href="…">Tüm sıralamayı gör<ArrowRight className="size-4" aria-hidden /></Link> </Button> - 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
<SectionEyebrow>Nasıl çalışır?</SectionEyebrow>
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] + <XIcon className="size-4" aria-hidden /> + 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öşedePixelCorner) 7 Eki 2026'da kaldırıldı (Bilal: "sıkıcı kart tasarımları"); yeni yerde yazılmaz.PixelCornergiriş/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/10içindesize-5 text-primaryikon. Kart içinde sayının yanında küçük hâli:size-8 … sm:size-10+size-4 sm:size-5ikon (§4.8). - Gölge:
shadow-smvarsayılan; hover'dashadow-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 <RiskEtiketi risk={…} /> kullanır; elle yazılmaz.
Nokta + metin: <span className="size-2 rounded-full bg-emerald-500" /> 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 haptı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; hoverborder-slate-300; odakborder-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-smyok — 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 (classNameyalnı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, ikonpointer-events-none absolute left-5 top-1/2 size-4 -translate-y-1/2 text-slate-400, alanpl-12. - Seçim (
SelectTrigger): aynı hap —h-12 pl-5 pr-4 text-base, oktext-slate-400;size="sm"→h-9 px-4 text-sm(yalnız masaüstü tablo aksiyonu, §8). Açılan listerounded-2xl border border-slate-200 bg-card p-1.5 shadow-lg; satırrounded-full py-2 pl-4 pr-9 text-base, klavye/odakbg-slate-100, seçili işaretitext-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
<input>yalnız kendi hap kabının içinde: il arama (sihirbaz-adimlar.tsx,h-11 rounded-full border-slate-200kap) ve katalog arama modalı (üst şeritteh-16). Kenarlıklı ham input yazılmaz;Inputkullanılır. - Etiket her alanda: görünür
text-sm font-semibold text-slate-700ya dasr-only. Hata mesajı alanın altındarole="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; butonh-12(§4.1size="lg"), alansm:flex-1. Telefonda alt alta, ikisi de tam genişlik. - Denetim:
ince-form-alani(hata) —Input/SelectTrigger/Textareaüstüneh-7–h-10,rounded-sm/md/lg/xl,bg-background/border-inputyazılmış;ham-input(uyarı) — kenarlıklı ham<input>.
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 kutusuflex size-8 shrink-0 items-center justify-center rounded-xl bg-primary/10 sm:size-10. dlanlamı içindt(başlık) DOM'da önce gelir, görsel sıraorder-*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+ birimbin, 1.618.988 →1,62+ birimmilyon(bölüm sayfasındakikartSayisi). - 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ü kartcol-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.
- Bölüm (
- Tıklanabilir kart (ör. Türkiye sırası → sıralama sayfası): kartın tamamı link olur
(
after:absolute after:inset-0gerilmiş link), iç kaynak linkirelative z-10ile üstte kalır; hover §2.1. - Açıklama altında veri görseli gerekiyorsa (ör.
PixelSira)ekyuvası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].
- hover §2.1 +
- Solda ikon kutusu (
size-11), ortada iki satır: başlıkfont-heading text-lg font-bold, altında önizlemetruncate text-sm text-slate-500— içeride ne olduğunu söyler ("Hoca başına 25 öğrenci"), boş "Daha fazla" yazmaz. SağdaChevronRight 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:
<AltSayfaIcerik> + §4.3 çarpısı + <AltSayfaGovde className="px-4 pt-3 pb-[max(1.25rem,env(safe-area-inset-bottom))] sm:px-6">.
İç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-xsiki 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üğmesisize-11çerçevesizCircleMinus— ç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
SectionEyebrowdurmaz; başlık + tek cümle bağlam yeter. "Saniyede gör" çekmecesi (cta-sira-form.tsx) bu düzene çevrildi:AltSayfaBaslikortalı,AltSayfaAciklamabağ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ütunflex flex-1 flex-col gap-3, sağdakimt-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-primaryikon (Landmarkdevlet,Building2vakıf,MapPinil). 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 linktir (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 (/universitelerlistesi, 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ındaSATIR_IKINCIL_LINK. İstisna: satırın tamamı zaten link olan yerler (URAP sıralaması, arama sonucu) — iç içe<a>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:
<PixelSira sira={5} toplam={198} className="h-4" />(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:
<NavBaslik baslikId="uni-baslik" ad={uni.ad} logo={<UniLogo slug={slug} ad={uni.ad} boy="xs" />} />
<h1 id="uni-baslik" …>…</h1>
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.
Sürüm rozeti (src/components/surum-rozeti.tsx, 7 Eki 2026): logo yazısının hemen
sağında "Beta" hapı + sürüm numarası. Hap Arc UI Badge (uiarc.dev/components/badge) sm
boyunun karşılığı (yazı §3 alt sınırı gereği 11 yerine 12 px): inline-flex h-[22px] items-center rounded-full bg-indigo-500 px-2 text-xs leading-none font-semibold tracking-[-0.01em] text-white — renk akademik gösterge
karesinin moru (§2.2 istisnası), renkli zeminde yazı font-semibold. Sürüm hapın içinde
değil, yanında: text-xs font-medium text-slate-500 tabular-nums, hidden sm:inline
(dar ekranda yalnız hap kalır). Rozet logo yazısıyla aynı fade sınıflarını taşır; NavBaslik
yuvası açılınca birlikte söner. Sayı package.json'dan gelir (AGENTS.md "Sürümleme");
elle yazılmaz. Başka yerde tekrarlanmaz — SectionEyebrow kuralının tek istisnasıdır.
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-2nokta +text-xs font-semibold text-{renk}-600+RISK_ETIKET. - Veride BÜYÜK HARF gelen üniversite adı ekranda
trBaslikDuzeniile yazılır. - Ad kesilmez, sarar:
whitespace-normal+block text-base font-semibold leading-snug.truncateile "İ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:hiddeniçinde değerfont-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_GRUPiçinde her genişlikte yan yana akar, sığmazsa sarar; telefondatext-xs, sm'dentext-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-8gibi küçültme verilmez. Telefonda iki buton alt alta durur (inline-flex flex-col items-center gap-2 sm:flex-row, sütunw-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, etikettext-sm font-semibold text-slate-900, metintext-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 dolgusupy-3ve 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çindekixs(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 dolgusupy-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 şehirborder-primary bg-primary text-white+aria-current="page". Ad yanında üniversite sayısıfont-normal tabular-nums text-slate-400(aktiftetext-white/80).
- Çip satırında yalnız 2+ üniversiteli şehirler (≈28) durur; 90'ı aşkın şehrin tamamı
/universiteler#tum-sehirleraltı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ı (MapPinil + üniversite sayısı), özet paragraf; sağda (lg, 24rem sütun) ya da altta (telefon) şehri temsil eden piksel haritaSehirPikselHaritasi. Sonra kompaktCtaSiraForm,PagePixelDivider(seed 71), devlet / vakıf / KKTC-yurt dışı öbekleri — her biri §4.15 liste satırı (UniSatirlari: kenarlıklırounded-xlliste, 48 px logo,SATIR_AD_DUZad,SATIR_METAiç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" —/universitelerdizinindeki iki sütunlu kompaktUniLinkleriburada 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-primaryzemin, imleç yaklaşınca turuncuya ısınma (usePixelHeat, meet/slice ve canlı viewBox ile). Bulunulan ilin karelerifill-orange-500, hücrenin %88'i kadar iri, 35 ms arayla belirir (kt-piksel-belir) ve grup hâlinde nabız atar (animate-pulse3.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
SehirYuzeyikartınıdoldur(slice) ile kaplar, metin üstünde; kenarlarmask-imageile 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): ızgararelative isolate, üçüncü sütun yalnız yer tutar, haritaabsolute -inset-x-4 -inset-y-8 -z-10katmanda; 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 ilodakHizaile 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. /universitelerdizinindeki "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 (
Infoikonu, "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)"dlsatı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)" yereldetailsile 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, notlartext-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ı çekmecevaryant="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/<ad>.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 ikonusize-3.5: sürüyorLoader2 animate-spin text-primary, bittiCheck text-emerald-600, hataCircleAlert 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'inToolbileşeni kullanılmaz: ham araç adı (program_ara), İngilizce rozet, JSON girdi/çıktı vedark: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
Maximize2düğ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 hedefeanimate(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": "<px>" })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.Minimize2geri alır; sohbet durumu (useChat, kaydırma) korunur. Hareketi azalt: geçişsiz. Perde, sabit konum, ayrıDialog/AltSayfayok — 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ığı +mainpy-12 + ızgara mt-8; ölçüldü: telefonda 251, 768 px'te 267, 1280 px'te 217 px) + 7rem şerit + 1rem nefes. Eski18remsezon bandını saymıyordu. Paketsizdeki 480 px'lik panel aynı sayılarımax-holarak 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
BolmeTutamacidurur (§4.25); sürükleyince aynı--sohbet-kolondeğ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, sohbetmax-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/<il>,/paket,/listem) prompt-kitSourcekalı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öyleyensize-3.5ikon (BookOpenrehber,Landmarküniversite,GraduationCapbölüm,MapPinşehir,Coinspaket,ListCheckslistem), hover §2.1,sr-onlytü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-kitSource'un Google favicon'u vemutedpaleti dış siteler içindir, alınmadı. Sohbet balonuprosesı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 (useSpringstiffness 450 / damping 40, imlecin 18 px sağ altı; kenara sığmazsa sol/üst) veheight 0 → auto, opacity, scale 0,3 → 1ile 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.tsxKESFET_TONLARI slate):rounded-xl border border-slate-200/80 bg-card shadow-lg shadow-slate-900/5, çubukh-6 bg-slate-50/90- üç
size-2 bg-slate-300nokta (1 / 0,65 / 0,35) + adres hapı (kolaytercih.com/rehber/…,text-xs text-slate-500). Rehberde gövde yalnız kapak: tamRehberKapak(compact yok) 1200×630 çizilipscale(288/1200)ile pencereye oturur — yazı, logo ve piksel süs kesilmez; başlık/özet/iskelet yok. Üniversite/bölüm/şehir gövdesip-3:UniLogo mdya da §4.4 ikon kutusu, başlıkfont-heading text-sm font-bold line-clamp-2, özettext-xs leading-5 text-slate-500 line-clamp-3, künyetext-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ıktext-xs font-semibold text-slate-500sü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 soldaw-0.5 bg-slate-200çubuk, sağda her adımtext-xs font-medium text-slate-700+ durum ikonu. Açık başlar, kullanıcı kapatabilir; açılmaanimate-collapsible-down/up(tw-animate-css), hareketi azalt'ta geçişsiz. Tek araçta hap kalır. Palet slate'e çevrildi (muted/popoveryok). -
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: avatarDanismanAvatar 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ı gerekincelisteUyarilari'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).
/listemdeki 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.33SohbetAnketi, balonun altında sade kutu), sonraliste_revizearacıyla yapısal kural verir (il/alan/tip farkı, "ilk N" ölçütü, çıkar/ekle, iskelet;lib/revizyon-kurali.ts); liste koddan yeniden kurulur, sayfarouter.refresh()ile yenilenir, hap "Listeni yeniden kurdum" olarak kalır. Form cevabı kredi harcamaz. Kayıtlı geçmişte form ve revizyon sonucuchat_messages.metadan 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, verilanding-verisi.tsornekProgramlar): ö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) veRiskEtiketi. 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 karosusize-14 rounded-2xl border border-slate-200 bg-card+size-6ikon; ortadaki karosize-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-baseparagraf, 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 gibifont-sans text-base font-semibold text-slate-400, etikettext-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
<canvas>, 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ındap-6içindeh3(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. Sahnearia-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ü:
<section className="py-20 sm:py-24">; alt sayfalarpy-12–py-16. - Bölüm başlık bloğu (kanonik):
Ardından içerik
<div className="flex flex-col items-center gap-4 text-center"> <SectionEyebrow>Sorun</SectionEyebrow> <h2 className="font-heading text-3xl font-bold sm:text-4xl">…</h2> <p className="max-w-xl text-lg leading-relaxed text-slate-600">…</p> </div>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;
vhyerinedvh.
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.akicipanel/yığın,YAY.donusumbiçim,YAY.birakmaparmak 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.5kayar; kart yükselmesi yalnız landing kartında. - Kaydırmaya bağlı tetik
IntersectionObserverile (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 <input>; md:text-sm |
8. Duyarlılık
- Kırılma noktaları: 375 (temel), 640
sm:, 768md:, 1024lg:. Her bileşen önce 375'te tasarlanır. Ortalı ↔ sola yaslı geçişilg'dedir (§5.2). - Dokunma hedefi en az 44 px (
h-11,size-11); satır içi küçük butonh-9yalnızca masaüstü tablo aksiyonlarında. - Başlık ölçeği bir kademe düşer (
text-3xl→sm:text-5xlalt 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/bottomdeğ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
<header>. Bölüm sayfasında içerik<header>'ı var; site üst çubuğunuquerySelector("header")ile değil, bilinen bir öğeninclosest("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): SVGviewBox640 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?
DialogdeğilAltSayfa(§4.10, §4.19). İçinde tablo mu? §4.15 sınıfları, hücretext-sm,text-xsyok. 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ı
h1ile 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-xile 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ümlerh2. Başlıklardatext-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:
<CtaBandi seed={8}> {/* buyuk: ortalı, px-5 py-8 sm:p-12 */}
<h2 className="font-heading text-2xl font-bold text-balance sm:text-3xl">…</h2>
<p className="mx-auto mt-3 max-w-xl text-base leading-relaxed text-white/90">…</p>
<Button size="lg" className="mt-6 w-full cursor-pointer bg-orange-500 text-white hover:bg-orange-600 active:scale-[0.97] sm:w-auto">
Yapay Zeka listemi kur<ArrowRight className="size-4" aria-hidden />
</Button>
</CtaBandi>
<CtaBandi etiket="div" boyut="kompakt" className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
…başlık + alt satır solda, buton sağda (çekmece)…
</CtaBandi>
Çekmecedeki kompakt bandın açık hâli (bileşenin ürettiği sınıflar):
<div className="relative isolate flex flex-col gap-3 overflow-hidden rounded-2xl bg-primary px-5 py-4 text-left text-white sm:flex-row sm:items-center sm:justify-between sm:gap-4 sm:py-5">
<div aria-hidden className="pointer-events-none absolute inset-x-0 -inset-y-6 -z-10 text-white">
<PixelMasonry seed={8} />
</div>
<div className="min-w-0">
<p className="font-heading text-xl font-bold sm:text-2xl">Risk analizini biz yaptık</p>
<p className="mt-1 hidden truncate text-sm leading-relaxed text-white sm:block">
Her seçimin yerleşme riski hazır — son kararı sen ver.
</p>
</div>
<Button size="lg" className="h-12 w-full shrink-0 cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600 active:scale-[0.97] sm:w-auto">
Listemde aç
<ArrowRight className="size-4" aria-hidden />
</Button>
</div>
- Zemin
bg-primary(sitenin mavisi), köşerounded-2xl, yazı beyaz; alt satır da beyaz (text-white,slate-300değil). Piksel dokusuPixelMasonry(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. Kaprelative isolate overflow-hidden, doku-inset-y-6 -z-10. Eşit ızgaralı eskiPixelFieldkaldı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, h2font-heading text-2xl font-bold sm:text-3xl, paragraftext-white/90. - Kullanıldığı yerler:
/sonuc'taki üç panel (sihirbaz, giriş bekleyen, "24 tercihlik listen hazır"),/meraklisinakapanış kartı (DemoKapanisCta), katalog altındakiCtaSiraFormkart 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 teksectioniçinde iki hâl taşıdığındanCtaBandi'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 çocukPikselZemin), kenarlık saydam kalır ki iki hâlin kutusu aynı olsun. Aynı sayfadaki iki band farklıseedalı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 zamanPikselListeAciklamametniyle. - Piksel tablosunun arkası boş kalır (Bilal, 24 Eyl 2026: "arkasına çok piksel yığılmış"):
tablo kabı
haricile 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 geliyorsaharicile 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).