Logonun yanına Arc UI Badge biçiminde, akademik gösterge morunda (bg-indigo-500) "Beta" hapı ve package.json'dan okunan sürüm numarası eklendi. Canlı sistem 1.0.0 olarak işaretlendi; semantik sürümleme kuralı AGENTS.md'ye, rozetin tasarım tanımı DESIGN.md §2.2/§4.14'e yazıldı. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
79 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 (Drawer) aynı sınıf seti DrawerClose üstünde kullanılır (§4.10).
4.4 Kart ve kutu
- Landing/öne çıkan kart:
<Card className="relative h-full overflow-hidden border-slate-200/70 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5">+ sağ üstte<PixelCorner className="absolute right-4 top-4" />. (Kodda hâlâhover:border-primary/30 hover:shadow-primary/5; §2.1 geçiş notu.) - 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ş koltuk varken 100'e yuvarlanmaz, en çok 99 yazar.- Bölüm (
grid grid-cols-2 gap-4 lg:grid-cols-4, haritası yok): En seçici (sıra + üniversite adı linkli) · En geniş kapı (ücretsiz devlet örgün programı ≥3 ise devlet kümesinde, açıklama "Devlet · Bingöl Üni. · 2026 taban sırası"; etiket "Devlette en geniş" 131 px'te iki satıra kırıldığı için kısa tutulur) · Orta taban (devlet programlarını sıraya dizince ortadakinin sırası; açıklamada "Devlet · 2021'de 105 bin · gevşedi") · Boş koltuk. 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 seçici bölüm (sıra + bölüm adı linkli) · Orta
taban (lisans programlarının ortası) · 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 (Drawer) içeriği
Ayrıntı her zaman alttan açılan sayfada (Drawer handleOnly, tutamaçlı); ekranın ortasında
açılan modal değil. Çekmece kabı ve çarpı cta-sira-form.tsx'teki çekmeceyle birebir:
DrawerContent className="max-h-[92dvh] bg-card sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl".
İç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:DrawerTitleortalı,DrawerDescriptionbağ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 (toast) — src/components/ui/sonner.tsx + globals.css
Tema sitenin temasını izler (useTheme().resolvedTheme, §2.3), sistemin değil: sistem koyu
temadayken sonner açıklamayı beyaza yakın griye çevirip beyaz zeminde okunmaz ediyordu (Bilal,
24 Eyl 2026: "toast açıklaması okunmuyor"). 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.
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 — Drawer handleOnly, 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/Draweryok — sohbet yeniden kurulmaz, sayfa zıplamaz. - 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.
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ç). Kartlar hover'da 4 px yükselir. Modal arka planı bg-black/10 + hafif blur. Yığın: içerik < sabit bar < çekmece/modal (z-50).
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). - 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 çekmecede (Drawer), 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ğilDrawer(§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). Bildirimler (sonner) 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
(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).