feat(tasarim): form alanları hap, CTA bandı tek kaynak, masonry piksel zemin, çekmeceler §4.10

- Input/Select/Textarea: shadcn'in ince varsayılanı yerine üst çubuk
  haplarıyla aynı kalıp (h-12, rounded-full, slate-200, 16 px; md:text-sm
  yok); kullanım yerleri yalnız yerleşim sınıfı taşır. DESIGN.md §4.6
  tam sınıf dizisi; denetime ince-form-alani (hata) ve ham-input (uyarı)
- CtaBandi (mavi zemin + piksel doku) tek kaynak: /sonuc iki panel, katalog
  altı kart, "Kendi Listem" çekmecesi altı. Ana sayfa kapanışı koyu
  PikselCtaYuzeyi + 24'lük piksel liste kreatifiyle kalır (Bilal: "orası
  bayağı iyiydi"); yazılıp silinen satır kaldırıldı
- PixelMasonry: CTA arka planları büyüklü küçüklü, hafif kaymış kareler;
  eşit ızgaralı PixelField kaldırıldı
- Çekmece başlığındaki 12×2 piksel liste kaldırıldı (çok dolu); sayı +
  ilerleme çubuğu + risk dağılımı geri geldi
- "Saniyede gör" çekmecesi §4.10 düzeninde: ortalı DrawerTitle + bağlam,
  rozet ve çizgili "neler alacaksın" listesi yok; kapı modalındaki iki
  rozet kalktı; denetime modal-rozet (hata)
- Kapı panelinde 3 px odak halkası kırpılmıyor (px-px → p-1)
- Liste satırı: üniversite adı + tür/il/süre adın altında tek akan satır,
  telefonda text-xs (SATIR_ALT_GRUP); katalog listelerinde ad kendi
  satırında (SATIR_GRUP space-y-2). Ölçüm 375 px canlı bölüm sayfası:
  satır yüksekliğini metin değil alt alta iki 44 px düğme belirliyor

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-24 12:08:24 +03:00
parent b8b7925ba9
commit 2099f20ed1
19 changed files with 516 additions and 295 deletions

View File

@@ -99,6 +99,12 @@ const KURALLAR: Kural[] = [
muaf: /src\/components\/pixel-decor\.tsx$/,
bul: regexKurali(/rounded-full border border-slate-200 bg-white px-3\.5 py-1\.5/),
},
{
ad: "modal-rozet",
seviye: "hata",
mesaj: "Çekmece/modal içinde SectionEyebrow yok; başlık + tek cümle bağlam (DESIGN.md §4.10)",
bul: blokIcinde(["DrawerContent", "DialogContent"], /<SectionEyebrow\b/),
},
{
ad: "cta-yildiz",
seviye: "hata",
@@ -154,6 +160,37 @@ const KURALLAR: Kural[] = [
return kanonik ? [] : [{ index: m.index, parca: m[0] }];
},
},
{
ad: "ince-form-alani",
seviye: "hata",
mesaj: "Input/SelectTrigger/Textarea üstüne yükseklik, köşe ya da zemin yazılmaz; hap varsayılanı kullanılır (DESIGN.md §4.6)",
bul: (icerik) => {
const sonuc: Array<{ index: number; parca: string }> = [];
// Açılış etiketinden ilk > işaretine kadar olan blok (self-closing dahil)
const acilis = /<(?:Input|SelectTrigger|Textarea)\b[^>]*?>/g;
const yasak =
/\b(?:(?:sm|md|lg):)?(?:h-(?:7|8|9|10)|rounded-(?:sm|md|lg|xl)|bg-background|border-input)\b/;
for (const m of icerik.matchAll(acilis)) {
const y = yasak.exec(m[0]);
if (y) sonuc.push({ index: (m.index ?? 0) + y.index, parca: y[0] });
}
return sonuc;
},
},
{
ad: "ham-input",
seviye: "uyari",
mesaj: "Kenarlıklı ham <input> yerine Input bileşeni; kenarlıksız ham input yalnız hap kabının içinde (DESIGN.md §4.6)",
bul: (icerik) => {
const sonuc: Array<{ index: number; parca: string }> = [];
for (const m of icerik.matchAll(/<input\b[^>]*?>/g)) {
if (/type=["'](?:hidden|checkbox|radio|range|file)["']/.test(m[0])) continue;
const k = /\bborder(?:-[a-z0-9/]+)?\b/.exec(m[0]);
if (k) sonuc.push({ index: (m.index ?? 0) + k.index, parca: k[0] });
}
return sonuc;
},
},
{
ad: "yabanci-font",
seviye: "hata",