- docs/tasarim/DESIGN.md: 9 bölümlük görsel dil belgesi (renk rolleri, tipografi, tek kaynak bileşenlerin sınıf dizileri, yerleşim, yap/yapma, brief şablonu) - kolaytercih-tasarim skill'i: UI işinde tetiklenir, belgeye götürür, örnek verir; tasarimci ve yazilimci ajanlarına skills: ile önyüklenir - scripts/tasarim-denetim.ts: 13 kural (Badge, CTA'da Sparkles, palet dışı ton, gradyan metin, parlama, hareket spam'i, çarpı, font); pnpm lint'e bağlandı - ui-ux-pro-max genel kataloğu skills'ten .agents/skills-devre-disi/ altına taşındı - AGENTS.md: DESIGN.md kuralı; rozet sınıfı koda göre düzeltildi (font-bricolage yoktu) - arama-funnel-karti: palet dışı text-cyan-300 → text-orange-500 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
12 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); kodla çelişirse kod değil, bu dosya düzeltilir ve
çelişki raporlanır. Kural ihlallerini pnpm tasarim:denetim yakalar.
Biçim: Google Stitch'in DESIGN.md düzeni (9 bölüm). Sabit değerler Tailwind sınıfı olarak verilir; kodda da sınıf kullanılır, hex/oklch elle yazılmaz.
1. Görsel tema ve atmosfer
Bir cümle: Beyaz, bol nefesli, mavi bilgi + turuncu aksiyon; her yüzeyde küçük bir piksel imzası (hero'daki dot-matrix Türkiye haritasının dili) dolaşır.
- Zemin her zaman beyaz; koyu zemin yalnızca CTA bandı ve çekmece başlığı gibi tek bir
vurgu yüzeyinde (
PixelFieldile). - İmza dekoratiftir ama rastgele değildir: deterministik ızgara (hücre 10, nokta 7.4, rx 2),
imleç yaklaşınca turuncuya ısınan pikseller (
usePixelHeat), uzaklaşınca yavaş soğuma. - Ton: öğrenciye "sen" diyen, sakin, vaatsiz. Süs yok, gösteriş yok; hareket yalnızca bir şey söylüyorsa var.
- Karanlık mod yoktur.
dark:sınıfı yazılmaz (.darktoken'ları shadcn kalıntısıdır).
2. Renk paleti ve rolleri
| Rol | Sınıf | Nerede |
|---|---|---|
Bilgi/vurgu mavisi (primary) |
text-primary, bg-primary/10, border-primary/30 |
Rozet metni, ikon kutusu, hero'daki italik vurgu, linkler, kart hover kenarlığı |
| Aksiyon turuncusu | bg-orange-500 hover:bg-orange-600 text-white |
Funnel CTA butonları. Bir ekranda tek turuncu buton |
| Piksel vurgusu | fill-orange-500 (opaklık 0.55–0.85) |
Yalnızca piksel süslerinin "sıcak" noktaları |
| Başlık metni | text-slate-900 |
h1–h3, kart başlıkları |
| Gövde metni | text-slate-600 |
Paragraf, açıklama |
| İkincil metin | text-slate-500 |
Meta bilgi, yardımcı satır |
| Silik metin | text-slate-400 |
İpucu, devre dışı, placeholder |
| Kenarlık | border-slate-200 (landing kartlarında border-slate-200/70) |
Kart, rozet, çarpı, giriş alanı |
| İç zemin | bg-slate-50 |
Kartın içindeki ikincil kutu, tablo başlığı |
| Hover zemini | hover:bg-slate-100 |
Çarpı, ghost buton |
| Risk: güvenli | emerald-500 / text-emerald-600 |
Her zaman "Güvenli" metniyle |
| Risk: az riskli | amber-500 / text-amber-600 |
Her zaman "Az riskli" metniyle |
| Risk: riskli | red-500 / text-red-600 |
Her zaman "Riskli" metniyle |
| Uyarı kutusu | border-amber-200 bg-amber-50 text-amber-900 |
Bilgilendirme notu |
| Hata | text-destructive, text-red-600 |
Form hatası |
Kurallar:
- Nötr yalnızca slate.
gray,zinc,neutral,stoneyazılmaz. indigo,purple,violet,fuchsia,pink,cyan,teal,lime,green,yellowyeni kullanım açmaz. (bg-violet-50 text-violet-600tek bir mevcut durum çipidir; yeni yere taşıma.)- Gradyan metin (
bg-clip-text text-transparent) ve parlama gölgesi (shadow-[0_0_…]) yok. - Hex/oklch değeri sınıf içine yazılmaz (
text-[#…]); token ya da Tailwind tonu kullanılır. Risk renklerinin SVG karşılığısrc/lib/risk.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").
3. Tipografi
Dört yazı tipi, her birinin tek bir işi var:
| Sınıf | Yazı tipi | İş |
|---|---|---|
font-heading |
Cal Sans | Tüm başlıklar (h1–h3, kart başlığı). Her zaman font-bold ile |
font-sans (varsayılan) |
Clarity City 400–800 | Gövde, buton, form, tablo |
font-bricolage |
Bricolage Grotesque (opsz ekseni) | Vurgu: hero'da italik mavi span, küçük etiketler/çipler, sayısal rozetler |
font-mono |
Geist Mono | Yalnızca kod/markdown blokları. Arayüzde kullanılmaz |
Ölçek (kopyala, uydurma):
- Hero h1:
font-heading text-5xl font-bold tracking-[0.015em] sm:text-6xl; vurgu kelimesi<span className="font-bricolage italic tracking-tighter font-bold text-primary"> - Bölüm h2:
font-heading text-3xl font-bold sm:text-4xl(istenirsetext-slate-900) - Panel/kart h3:
font-heading text-xl font-bold· liste satırı başlığı:font-heading text-lg font-bold text-slate-900 - Küçük başlık:
font-heading text-base font-bold text-slate-900 - Bölüm giriş paragrafı:
max-w-xl text-lg leading-relaxed text-slate-600 - Gövde:
text-sm(tablo, form, kart içi) ya datext-base leading-relaxed(açıklama) - Etiket/rozet metni:
text-xs font-semibold - Yasak: Inter, Roboto, Arial, sistem fontu, serif,
font-[…]keyfi font; tek kelimelik büyük harf etiketler (uppercase yok, rozet metni büyük-küçük harfli yazılır).
4. Bileşen stilleri (tek kaynaklar)
Bir eleman iki yerde görünüyorsa stili tek kaynaktan gelir. Aşağıdakiler yeniden tasarlanmaz.
4.1 Buton — src/components/ui/button.tsx
- Her buton
rounded-full;h-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:
variant="outline"; sessiz:variant="ghost"; link görünümü:variant="link".
4.2 Rozet (bölüm başlığı üstündeki kapsül) — SectionEyebrow, src/components/pixel-decor.tsx
<SectionEyebrow>Nasıl çalışır?</SectionEyebrow>
Sınıfı: inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold text-primary + başta PixelMark.
@/components/ui/badge kullanılmaz; elle pill span yazılmaz. Filtre çipleri ve nav butonları bu kuralın dışındadır (onlar etkileşimlidir).
4.3 Modal kapatma çarpısı — DialogContent varsayılanı, src/components/ui/dialog.tsx
absolute top-3 right-3 z-10 flex size-9 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-popover text-slate-500 transition-[background-color,transform] duration-150 hover:bg-slate-100 hover:text-slate-800 active:scale-[0.96] + <XIcon className="size-4" aria-hidden /> + sr-only "Kapat".
Özel yerleşim gerekiyorsa showCloseButton={false} ver ve aynı sınıf setini kopyala.
4.4 Kart ve kutu
- Landing/öne çıkan kart:
<Card className="relative h-full overflow-hidden border-slate-200/70 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-primary/30 hover:shadow-lg hover:shadow-primary/5">+ sağ üstte<PixelCorner className="absolute right-4 top-4" />. - Sade kutu (form, panel, liste satırı):
rounded-2xl border border-slate-200 bg-white(+p-5/p-6). Küçük iç kutu:rounded-xl border border-slate-200 bg-slate-50. Not kutusu:rounded-lg. - İkon kutusu:
flex size-11 items-center justify-center rounded-xl bg-primary/10içindesize-5 text-primaryikon. - Gölge:
shadow-smvarsayılan; hover'dashadow-lg shadow-primary/5. Başka gölge yok.
4.5 Risk çipi / etiketi
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
shadcn Input, Select, Textarea, Slider. Etiket her alanda; hata mesajı alanın altında, ne olduğunu ve ne yapılacağını söyler. Sayısal alanlarda uç değerler (0, negatif, 1.000.000 üstü) ele alınır.
4.7 İkonlar
Yalnızca lucide-react. Boyut: size-4 buton/satır içi (varsayılan), size-5 ikon kutusu, size-3.5 küçük çip, size-6 üstü yalnızca boş durum. Dekoratif ikon aria-hidden; tek başına ikon buton aria-label ya da sr-only metin taşır. Emoji ikon olarak kullanılmaz.
5. Yerleşim
- Sayfa kabı:
mx-auto max-w-6xl px-4. Metin sütunu:max-w-xl(paragraf) /max-w-2xl–max-w-3xl(uzun içerik). - Landing bölümü:
<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 üniversite/program adları
min-w-0+ sarma ya datruncate; tablo yatay kaydırmaz, kart olur; sabit alt çubuk klavyeyle çakışmaz;vhyerinedvh.
6. Derinlik ve katman
Derinlik gölgeyle değil piksel katmanı ve hareket farkıyla verilir: başlık bloğu gövdeden hafif hızlı akar (Parallax strength={16} başlık, 7 içerik, 26 ayraç). Kartlar hover'da 4 px yükselir. Modal arka planı bg-black/10 + hafif blur. Yığın: içerik < sabit bar < çekmece/modal (z-50).
7. Yap / Yapma
| Yap | Yapma (AI izi) |
|---|---|
Rozet için SectionEyebrow |
Badge import'u, elle rounded-full border … px-3.5 py-1.5 span |
CTA: metin + sondaki ArrowRight |
Başta Sparkles/yıldız ikonu, "✨" |
| Nötr = slate; vurgu = primary mavi; aksiyon = orange-500 | indigo/purple primary, mor→mavi gradyan, gray/zinc nötr |
Kart: rounded-2xl border-slate-200 bg-white shadow-sm |
Her şeyde rounded-3xl, camsı backdrop-blur kartlar, parlama gölgesi |
Hareket: Reveal (bölüm girişi), piksel ısısı, kt-unblur; animate-ping yalnızca "şu anda canlı" noktasında |
Her elemanda fade-up, whileHover scale 1.05, animate-bounce |
Başlık font-heading, vurgu font-bricolage |
Inter/Roboto/serif, tek kelimelik BÜYÜK HARF etiket |
| Risk rengi + metin etiketi | Renk tek başına, "yerleşirsin" gibi vaat cümlesi |
| Üç kart yalnızca üç gerçek öğe varsa | Hero + üç kart iskeleti refleksi |
| Beyaz zemin, tek koyu vurgu yüzeyi | İstenmemiş karanlık mod, dark: sınıfı |
Kapatma çarpısı DialogContent varsayılanı |
Başka boyut/renkte çarpı |
8. Duyarlılık
- Kırılma noktaları: 375 (temel), 640
sm:, 768md:, 1024lg:. Her bileşen önce 375'te tasarlanır. - 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-4xl), gövde 16 px altına inmez. - Modal genişliği
max-w-[calc(100%-2rem)]; çekmece (Drawer) mobilde alttan açılır. prefers-reduced-motion: her animasyonun sade karşılığı var (motion-reduce:animate-none,.kt-unblur-sade).
9. Ajan için brief şablonu
Yeni bir UI işi istenince önce şu dört satır doldurulur, sonra kod yazılır:
Amaç: Kim, hangi ekranda, ne yapacak? (ör. veli, /paket, fiyatı karşılaştırıp satın alacak)
Referans: Sitedeki en yakın mevcut ekran/bileşen (dosya yolu). Yoksa "yok" yaz ve ana sayfa bölüm bloğunu al.
Tek kaynak: Kullanılacak kanonik parçalar (SectionEyebrow, Button+ArrowRight, Card+PixelCorner, PagePixelDivider…)
Durumlar: boş / yükleniyor / hata / başarılı / girişsiz / kredisiz — hangileri var?
"Modern", "temiz", "şık" gibi yön belirtmeyen kelimeler kullanılmaz; yön = bu dosya.
İş bitince: pnpm tasarim:denetim sıfır hata + 375 px'te tek bakış (taşma, üst üste binme, dokunma hedefi).