feat(tema): açık / koyu / sistem teması
All checks were successful
Deploy / deploy (push) Successful in 6m23s

- TemaSaglayici (next-themes) + alt bilgide TemaSecici
- globals.css: .dark bloğunda palet token'ları çevrilir; bileşenlere
  dark: sınıfı yazılmaz
- yüzeyler bg-white → bg-card, koyu haplar text-slate-50, SVG'lerde
  sabit renk yerine değişken
- DESIGN.md §2.3 + tasarim-denetim kuralları (yuzey-beyaz,
  koyu-hap-beyaz-yazi, dark-sinif), AGENTS.md karanlık mod bölümü
- docs: koyu tema denetimi raporu

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-05 10:20:02 +03:00
parent 9e4c5608eb
commit 78ad84922a
70 changed files with 637 additions and 243 deletions

View File

@@ -66,7 +66,7 @@ dokunma hedefi < 44 px, uzun üniversite adı. (Tarayıcı açma kuralı AGENTS.
**İstek:** "Üniversite sayfasına URAP kartı ekle." **İstek:** "Üniversite sayfasına URAP kartı ekle."
**Çıktı:** **Çıktı:**
```tsx ```tsx
<div className="relative overflow-hidden rounded-2xl border border-slate-200 bg-white p-5"> <div className="relative overflow-hidden rounded-2xl border border-slate-200 bg-card p-5">
<PixelCorner className="absolute right-4 top-4" /> <PixelCorner className="absolute right-4 top-4" />
<p className="text-xs font-semibold text-slate-500">URAP Türkiye</p> <p className="text-xs font-semibold text-slate-500">URAP Türkiye</p>
<p className="mt-1 font-heading text-2xl font-bold text-slate-900">18 <span className="text-base font-medium text-slate-400">/ 198</span></p> <p className="mt-1 font-heading text-2xl font-bold text-slate-900">18 <span className="text-base font-medium text-slate-400">/ 198</span></p>
@@ -79,7 +79,7 @@ dokunma hedefi < 44 px, uzun üniversite adı. (Tarayıcı açma kuralı AGENTS.
## 5. Kısa yasak listesi ## 5. Kısa yasak listesi
`Badge` import'u · elle pill span · CTA'da `Sparkles`/emoji · `indigo/purple/gray/zinc` · gradyan metin · `Badge` import'u · elle pill span · CTA'da `Sparkles`/emoji · `indigo/purple/gray/zinc` · gradyan metin ·
parlama gölgesi · `whileHover scale` · her elemanda fade-up · `dark:` · Inter/Roboto/serif · `text-[#hex]` · renk tek başına anlam. parlama gölgesi · `whileHover scale` · her elemanda fade-up · `dark:` · yüzeyde `bg-white` (yerine `bg-card`, §2.3) · Inter/Roboto/serif · `text-[#hex]` · renk tek başına anlam.
## 6. Rapor ## 6. Rapor

View File

@@ -24,9 +24,13 @@ Push emri geldiğinde önce lokalde `pnpm build` başarıyla geçmeli; geçmeden
UI'a dokunan her iş (yeni ekran, bileşen, kart, modal, buton, form; mevcut arayüz değişikliği) önce `docs/tasarim/DESIGN.md` okunarak yapılır; renk, yazı tipi, köşe, gölge, boşluk ve tek kaynak bileşenlerin sınıf dizileri oradan **birebir** alınır, "yaklaşık aynısı" yazılmaz. Aşağıdaki rozet/çarpı/CTA kuralları o belgenin özetidir. Genel tasarım katalogları (`ui-ux-pro-max` gibi "50 stil, 97 palet" kütüphaneleri) bu projede kullanılmaz; yön zaten belli. İş bitmeden `pnpm tasarim:denetim` sıfır hata vermeli (`pnpm lint` bunu da koşar); betik `scripts/tasarim-denetim.ts`, kural eklerken DESIGN.md'deki bölüm numarasına atıf yap. UI'a dokunan her iş (yeni ekran, bileşen, kart, modal, buton, form; mevcut arayüz değişikliği) önce `docs/tasarim/DESIGN.md` okunarak yapılır; renk, yazı tipi, köşe, gölge, boşluk ve tek kaynak bileşenlerin sınıf dizileri oradan **birebir** alınır, "yaklaşık aynısı" yazılmaz. Aşağıdaki rozet/çarpı/CTA kuralları o belgenin özetidir. Genel tasarım katalogları (`ui-ux-pro-max` gibi "50 stil, 97 palet" kütüphaneleri) bu projede kullanılmaz; yön zaten belli. İş bitmeden `pnpm tasarim:denetim` sıfır hata vermeli (`pnpm lint` bunu da koşar); betik `scripts/tasarim-denetim.ts`, kural eklerken DESIGN.md'deki bölüm numarasına atıf yap.
# Karanlık mod: token'la çalışır, `dark:` yazılmaz
Sitede açık / koyu / sistem teması var (DESIGN.md §2.3). Karanlık mod `src/app/globals.css` içindeki `.dark` bloğunda palet token'ları çevrilerek çalışır (slate ölçeği ters döner, renkli açık zeminler koyu tona iner); bileşenlere `dark:` sınıfı yazılmaz. Yeni UI yazarken: yüzey zemini `bg-card`'dır (`bg-white` koyu temada da beyaz kalır — yalnız logo karosu gibi gerçekten beyaz kalması gereken yerde); koyu hap (`bg-slate-900`) yazısını `text-slate-50` ile alır; SVG/satır içi stilde sabit renk yerine `var(--card)`, `var(--color-slate-200)` gibi değişken kullanılır; koyu vurgu yüzeyi (`bg-slate-950`) `kt-koyu-yuzey` sınıfını taşır. `pnpm tasarim:denetim` bunları `yuzey-beyaz`, `koyu-hap-beyaz-yazi` ve `dark-sinif` kurallarıyla yakalar.
# Badge/eyebrow rozetleri: tek kaynak SectionEyebrow # Badge/eyebrow rozetleri: tek kaynak SectionEyebrow
Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `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`; metin büyük-küçük harfli yazılır — uppercase yok). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır. Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `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`; metin büyük-küçük harfli yazılır — uppercase yok). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
# UI tutarlılığı: ortak elemanlar tek kaynaktan # UI tutarlılığı: ortak elemanlar tek kaynaktan

View File

@@ -0,0 +1,114 @@
# Koyu tema — gözle denetim (tasarımcı, 4 Eki 2026)
Lokal dev sunucusunda (çalışma ağacı, commit yok) koyu tema 375 / 768 / 1280 px'te gezildi.
Kod değiştirilmedi. Sunucu iş sonunda kapatıldı.
**Neden tarayıcı açıldı:** kontrast, açık kalan lekeler, taşma ve koyu temadaki yüzey ayrımı koddan
görülemiyor; değişiklik canlıda da yok.
## Özet (5 madde)
1. Koyu tema genel olarak sağlam: gezilen ~20 ekranın çoğunda okunmayan yazı, beyaz leke ya da kaybolan kenarlık yok.
2. **Temaya bağlı 2 önemli hata var:** `/sonuc`'ta seçili sekmenin sayısı görünmüyor; `/paket`'te iyzico/Visa/Troy logoları koyu zeminde kayboluyor.
3. Temaya bağlı 1 kozmetik leke: arama penceresindeki "Üniversiteler" karosunun ikon kutusu beyaz kalıyor (`sky-*` çevrilmemiş).
4. Girişli ekranlara girilmedi; koddan iki risk çıktı (kilit ikonu, sohbetteki kod bloğu) — gözle doğrulanmalı.
5. Temayla ilgisi olmayan ama gezerken görülen 2 mobil taşma var (`/paket` canlıda da taşıyor; arama penceresinde çarpı ekran dışına çıkıyor).
`pnpm tasarim:denetim`: **0 hata, 12 uyarı** (hepsi eski: `secimlerim-paneli.tsx` büyük harf etiket / tabular-nums, `meraklisina-demo.tsx` 12 px altı yazı).
## Bulgular (önem sırasıyla)
### Önemli
**1. `/sonuc` — seçili dilim sekmesinde sayı okunmuyor** (375, 768, 1280)
- Görülen: seçili sekme koyu temada açık hapa dönüyor (doğru), "Dengeli" yazısı koyu (doğru), ama altındaki/yanındaki sayı ("186") beyaz kaldığı için açık hap üstünde görünmüyor. Sekme ikonu da (sarı terazi) açık hap üstünde çok silik.
- Kaynak: `src/features/liste/components/program-tablosu.tsx:234` → `text-white/70`; ikon `:75, :82, :89` → `renkAktif: text-red-400 / text-amber-400 / text-emerald-400` (koyu hap için seçilmiş açık tonlar).
- Kural: DESIGN.md §2.3 "koyu hap yazısını `text-slate-50` ile alır, `text-white` ile değil".
- Düzeltme: sayı `text-slate-50/70`. İkon için en basiti: seçili sekmede ikon da hapın yazı rengini alsın (`text-slate-50`); anlamı zaten etiket taşıyor. Renk korunacaksa `renkAktif` kaldırılıp `renk` kullanılır ama sarı açık hapta yine zayıf kalır.
**2. `/paket` — iyzico logo bandı koyu zeminde kayboluyor** (375, 1280)
- Görülen: "VISA" ve "troy" neredeyse görünmüyor, iyzico yazısı silik. Footer'daki aynı bant beyaz hap üstünde ve sorunsuz.
- Kaynak: `src/features/odeme/components/paket-satinal.tsx:86-92` ve `src/features/odeme/components/odeme-sayfasi.tsx:90-96` — `kt-acik-logo` sınıfı yok (footer'da var: `site-footer.tsx:205`).
- Düzeltme: iki `Image`'a `kt-acik-logo` ekle. (Ödeme sayfası girişli; gözle bakılmadı, aynı kod.)
- Not: iyzico sözleşmesi logoların görünür olmasını istiyor; bu yüzden kozmetik değil.
**3. `/listem` kilit satırı — ikon kaybolur** (koddan çıkarım, girişli ekran)
- `src/features/rapor/components/listem-govde.tsx:294` → `bg-orange-100 text-orange-700`. `orange-100` `.dark` bloğunda yok (açık şeftali kalır), `orange-700` ise açık tona çevrilmiş → açık zemin üstünde açık ikon.
- Düzeltme: `globals.css` `.dark` bloğuna `--color-orange-100` koyu karşılığı ekle (ör. `oklch(0.32 0.07 50)`), ya da sınıfı `bg-orange-50` yap.
**4. Danışman sohbetinde kod bloğu** (koddan çıkarım, girişli ekran)
- `src/components/ui/code-block.tsx:36` → shiki teması sabit `github-light`: koyu yüzeyde koyu yazı.
- Düzeltme: temayı `useTheme().resolvedTheme`'e göre `github-dark` / `github-light` seç (toast'taki desenle aynı, §4.16). Danışman nadiren kod yazdığı için aciliyeti düşük.
### Kozmetik
**5. Arama penceresi (boş durum) — "Üniversiteler" karosu beyaz ikon kutusu** (1280; 375'te de aynı kod)
- Görülen: üç keşif karosundan ortadakinin ikon kutusu parlak beyaz/açık mavi; diğer ikisi koyu.
- Kaynak: `src/features/katalog/components/katalog-arama.tsx:95-97` → `bg-sky-300`, `bg-sky-50`, `bg-sky-100` (ve `:101` `bg-amber-300`). `.dark` bloğunda yalnız `sky-200` ve `sky-600` var.
- Düzeltme: `.dark` bloğuna `--color-sky-50`, `--color-sky-100` koyu ton ekle (§2.3 son madde: "yeni ton eklenince karşılığı yazılır").
**6. Mobil tarayıcı çubuğu rengi sistemi izliyor, siteyi değil**
- `src/app/layout.tsx:75-78` `themeColor` `prefers-color-scheme` ile seçiliyor. Sistem açık + sitede "Koyu" seçiliyse adres çubuğu açık renk kalır. Düşük öncelik; istenirse tema değişince `<meta name="theme-color">` güncellenir.
**7. `/meraklisina` 375 px — beyaz şema kâğıdı üst çubuğun altından geçerken logo çevresi grileşiyor**
- Logo yazısı okunuyor ama bulanık katman kâğıdın beyazını taşıyor. Rehber kapaklarında aynı durum gözlenmedi (üst çubuk koyu kaldı). Bilal baksın; düzeltme şart değil.
### Temayla ilgisi yok, gezerken görüldü
**8. `/paket` 375 px — sayfa yatay taşıyor** (önemli; **canlıda da var**, kolaytercih.com/paket'te doğrulandı)
- Görülen: "299 TL" → "299 T", madde metinleri ve turuncu buton sağdan kesik.
- Muhtemel kaynak: `paket-satinal.tsx:58` `grid gap-6 sm:grid-cols-[1fr_auto]` — telefonda tek sütun `auto`; `:133` buton metni ("Giriş yap — ilk 3 tercihini ücretsiz gör") tek satırda sığmadığı için sütunu genişletiyor.
- Düzeltme: kaba `grid-cols-[minmax(0,1fr)]` (telefon) ve butona `whitespace-normal h-auto min-h-12` ya da metni kısalt.
**9. Arama penceresi 375 px — sonuç gelince içerik sağa taşıyor, kapatma çarpısı ekran dışında** (önemli; canlıda doğrulanamadı)
- Görülen: "bilgisayar" yazınca uzun bölüm adı ve rehber kartı pencerenin sağ kenarından kesiliyor; giriş satırındaki çarpı görünmüyor. Sonuç yokken (boş/"bulunamadı") düzen doğru, çarpı yerinde.
- Muhtemel kaynak: `katalog-arama.tsx:396` — `DialogContent` `grid` ama sütun tanımı yok; `truncate` satırlar sütunu genişletiyor.
- Düzeltme: aynı satıra `grid-cols-[minmax(0,1fr)]`.
**10. Sihirbaz — kapatma çarpısı üçüncü adım çubuğunun ucuna biniyor** (375, 1280; kozmetik)
- `sihirbaz-adimlar.tsx` adım çubuğu satırına sağdan çarpı kadar boşluk (`pr-12`).
**11. `/giris` — "Giriş bağlantısı gönder" butonunda başta zarf ikonu** (kozmetik)
- AGENTS.md CTA kuralı: başta ikon yok, sonda `ArrowRight`. Kaynak `src/features/kullanici/components/giris-form.tsx:181` civarı.
**12. Arama penceresi alt satırı** — sonuçlar listelenirken de "En az 2 harf yazarak ara" yazıyor (metin; kozmetik).
## Sorunsuz bulunan ekranlar (koyu tema)
- Ana sayfa 375 / 768 / 1280: hero + piksel harita, sorun kartları, üç adım, sayılar + dürüstlük notu, karşılaştırma tablosu, fiyat kartları, SSS, CTA bandı, footer, tema seçici, iyzico hapı.
- Üst çubuk: logo, orta nav, "Ara" (açık hap + koyu yazı) ve Kbd'ler, "Giriş yap", sıralama hapı, Listem sayacı, üst mavi bant, üst/alt blur.
- Arama penceresi 1280: giriş satırı, üniversite sonuçları + logo karoları, çarpı, koyu funnel kartı.
- `/universiteler`, `/universiteler/istanbul` (şehir yüzeyi + piksel harita), `/universite/ankara-universitesi` (özet kartlar, harita, program tabloları, eğilim çizgisi), akademik göstergeler çekmecesi, `/bolumler`, `/bolum/bilgisayar-muhendisligi` (375 + 1280), netler çekmecesi.
- Sihirbaz: sıralama penceresi, puan türü açılır listesi, alan çipleri, şehir çipleri + il seçim haritası, öncelik adımı.
- `/sonuc`: başlık, Türkiye haritası, tablo satırları, risk etiketleri (sekme hariç — bulgu 1).
- Liste çekmecesi, kaydet banner'ı, "Listene eklendi" bildirimi (açık düğme + koyu yazı).
- `/rehber` (kapaklar bilinçli beyaz), mermaid şemalı yazı, `/meraklisina` (dilim şeridi, huni şeması beyaz kâğıtta), `/giris`, `/iletisim`, `/gizlilik`, 404.
- Odak halkası: hero giriş alanı ve "Giriş yap" üstünde mavi halka görünür.
- Açık tema, ana sayfa 1280: hero, üç adım, tablo, fiyat, CTA bandı, footer — gerileme görülmedi.
## Bakılamayanlar
- Girişli ekranlar: `/listem` raporu, danışman sohbeti, `/odeme`, kredi/tercih değişti modalları.
- KKTC/yurt dışı haritaları (`yurtdisi-haritalar.tsx`) — test seçiminde çıkmadı.
- Tema değişirken titreme/flash: araç anlık kare yakalayamıyor; görünür bir bozulma fark edilmedi ama doğrulanmış sayılmaz.
- Hover hâlleri tek tek denenmedi (yalnız netler düğmesinde turuncu hover görüldü, sorunsuz).
- Ekran görüntüleri 1280'de %62 ölçekli geldi; ince kontrast farkları (silik gri metinler) gözle kesinleştirilemedi.
## Bilal'in gözle bakması gerekenler
1. `/sonuc` → seçili sekme (Hayal/Dengeli/Güvenli), koyu tema.
2. `/paket` → iyzico logo satırı, koyu tema; aynı sayfa telefonda sağdan kesik mi.
3. Telefonda arama → "bilgisayar" yaz → çarpı görünüyor mu.
4. Girişliyken `/listem` kilit satırı ve bir danışman yanıtı (kod bloğu varsa).
5. `/rehber` listesi koyu temada: beyaz kapaklar art arda — bilinçli karar, göze nasıl geldiğine bak.
## Bilal'den istenen
1. Bulgu 1 ve 2'nin commit öncesi düzeltilmesine onay (iki küçük sınıf değişikliği) — 1 dk.
2. Bulgu 8 ve 9 (mobil taşma, canlıda da var) için ayrı iş açılsın mı kararı — 2 dk.
3. Girişli ekranlara koyu temada bir kez göz atmak (liste yukarıda, madde 4) — 5 dk.
## Not
Önizleme tarayıcısında test verisi kaldı (sıralama 85.000, listede 3 program) ve tema "Koyu"da kalmış olabilir;
yalnız önizleme panelinin yerel depolamasında, koda ya da veritabanına yazılmadı. Form gönderimi, giriş, ödeme yapılmadı.

View File

@@ -48,15 +48,16 @@ ve üniversite sayfası. Bu hissi veren şeyler, ekrandan bağımsız:
### 1.2 Genel kurallar ### 1.2 Genel kurallar
- Zemin her zaman beyaz; koyu zemin yalnızca CTA bandı ve çekmece başlığı gibi tek bir - Açık temada zemin beyaz (koyu temada karşılığı, §2.3); koyu zemin yalnızca CTA bandı ve
vurgu yüzeyinde (`PixelMasonry` ile: büyüklü küçüklü, hafif kaymış kareler). çekmece başlığı gibi tek bir vurgu yüzeyinde (`PixelMasonry` ile: büyüklü küçüklü, hafif kaymış kareler).
- İmza dekoratiftir ama rastgele değildir: deterministik ızgara (hücre 10, nokta 7.4, rx 2), - İ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. 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 **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. piksel ayraç alt sayfalarda ve kompakt panellerde kullanılmaz.
- Ton: öğrenciye "sen" diyen, sakin, vaatsiz. Süs yok, gösteriş yok; hareket yalnızca - Ton: öğrenciye "sen" diyen, sakin, vaatsiz. Süs yok, gösteriş yok; hareket yalnızca
bir şey söylüyorsa var. bir şey söylüyorsa var.
- **Karanlık mod yoktur.** `dark:` sınıfı yazılmaz (`.dark` token'ları shadcn kalıntısıdır). - **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 ## 2. Renk paleti ve rolleri
@@ -123,6 +124,43 @@ turuncu **tek tondur: `orange-500`** — CTA butonunun turuncusuyla birebir ayn
altında kalır (sitenin turuncu CTA'sı da aynı ikiliyi kullanır). Bu zeminlerde etiket altında kalır (sitenin turuncu CTA'sı da aynı ikiliyi kullanır). Bu zeminlerde etiket
`font-bold`, sayı en az `text-3xl`; uzun metin konmaz. `font-bold`, sayı en az `text-3xl`; uzun metin konmaz.
### 2.3 Karanlık mod
Bilal'in kararı (4 Eki 2026): sitede açık / koyu / sistem teması var; varsayılan açık.
Seçici `src/components/tema-secici.tsx` (footer'da), sağlayıcı `src/components/tema-saglayici.tsx`
(`next-themes`, `<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-white` değil.** `bg-white` koyu temada da beyaz kalır; yalnız
gerçekten beyaz kalması gereken yerde yazılır: üniversite logosu karosu (`uni-logo.tsx`),
kaydırıcı topuzu, rehber kapak görseli, renkli dolu zemin üstündeki `bg-white/15` ikon kutusu.
- **Koyu hap** (`bg-slate-900`: "Giriş yap", "Ara", sekme göstergesi, toast düğmesi) yazısını
`text-slate-50` ile alır, `text-white` ile değil: koyu temada hap açığa, yazı koyuya döner.
- **Koyu vurgu yüzeyi** (`bg-slate-950`: `PikselCtaYuzeyi`, `AramaFunnelKarti`) `kt-koyu-yuzey`
sınıfını taşır; iki temada koyu kalır, içindeki açık slate metinler çevrilmez. `slate-950`
metin rengi olarak kullanılmaz.
- **SVG ve satır içi stilde** sabit renk yerine değişken: `var(--card)`, `var(--color-slate-200)`,
`var(--kt-harita-dolu)`. Risk renkleri (`RISK_RENK`) ve logo renkleri iki temada aynıdır.
- **Açık kalan adalar:** el çizimi şemalar (`kt-sema-kagit`) ve iyzico logo bandı
(`kt-acik-logo`; footer, paket ve ödeme sayfası) koyu temada beyaz kâğıt/hap üstünde durur;
tek renk koyu logo (URAP) `kt-koyu-cevir` ile açığa çevrilir; yazdırma çıktısı her zaman açıktır
(`.dark` bloğu `@media screen` içinde).
- Yeni bir renk tonu ilk kez kullanılıyorsa (`bg-sky-50` gibi) `.dark` bloğuna karşılığı eklenir;
eklenmezse koyu temada açık renkli bir leke olarak kalır.
## 3. Tipografi ## 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: 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:
@@ -199,7 +237,7 @@ bir dosyaya (`src/components/…`) çıkarılıp iki yer de oradan kullanır.
```tsx ```tsx
<SectionEyebrow>Nasıl çalışır?</SectionEyebrow> <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`. 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ı `@/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; 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). çekmece ve modal başlıklarında kullanılmaz (§4.10, Bilal 24 Eyl 2026).
@@ -211,7 +249,7 @@ Alt sayfada (`Drawer`) aynı sınıf seti `DrawerClose` üstünde kullanılır (
### 4.4 Kart ve kutu ### 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.) - 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-white` (+ `p-5`/`p-6`). Küçük iç kutu: `rounded-xl border border-slate-200 bg-slate-50`. Not kutusu: `rounded-lg`. - Sade kutu (form, panel, liste satırı): `rounded-2xl border border-slate-200 bg-card` (+ `p-5`/`p-6`). Küçük iç kutu: `rounded-xl border border-slate-200 bg-slate-50`. Not kutusu: `rounded-lg`.
- İkon kutusu: `flex size-11 items-center justify-center rounded-xl bg-primary/10` içinde `size-5 text-primary` ikon. Kart içinde sayının yanında küçük hâli: `size-8 … sm:size-10` + `size-4 sm:size-5` ikon (§4.8). - İkon kutusu: `flex size-11 items-center justify-center rounded-xl bg-primary/10` içinde `size-5 text-primary` ikon. Kart içinde sayının yanında küçük hâli: `size-8 … sm:size-10` + `size-4 sm:size-5` ikon (§4.8).
- Gölge: `shadow-sm` varsayılan; hover'da `shadow-lg shadow-orange-500/5`. Başka gölge yok. - Gölge: `shadow-sm` varsayılan; hover'da `shadow-lg shadow-orange-500/5`. Başka gölge yok.
@@ -223,7 +261,7 @@ Nokta + metin: `<span className="size-2 rounded-full bg-emerald-500" />` yanınd
Form alanı da bir **hap**tır: üst çubuktaki arama/kullanıcı haplarıyla aynı kalıp (48 px, tam Form alanı da bir **hap**tır: üst çubuktaki arama/kullanıcı haplarıyla aynı kalıp (48 px, tam
yuvarlak, slate-200 kenarlık, 16 px yazı). shadcn'in ince varsayılanı (`h-8 rounded-lg 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. 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-white px-5 text-base text-slate-900 placeholder:text-slate-400`; - **Metin alanı (`Input`)**: `h-12 w-full rounded-full border border-slate-200 bg-card px-5 text-base text-slate-900 placeholder:text-slate-400`;
hover `border-slate-300`; odak `border-primary ring-3 ring-ring/50`; hata (`aria-invalid`) hover `border-slate-300`; odak `border-primary ring-3 ring-ring/50`; hata (`aria-invalid`)
`border-red-500 ring-3 ring-red-500/20`; devre dışı `bg-slate-50 opacity-50`. `md:text-sm` yok — gövde `border-red-500 ring-3 ring-red-500/20`; devre dışı `bg-slate-50 opacity-50`. `md:text-sm` yok — gövde
16 px altına inmez (§3) ve iOS odakta yakınlaştırmaz. Kullanım yerinde yükseklik/köşe/zemin 16 px altına inmez (§3) ve iOS odakta yakınlaştırmaz. Kullanım yerinde yükseklik/köşe/zemin
@@ -233,9 +271,9 @@ border-input md:text-sm`) bu projede yoktur; temel bileşenler 24 Eyl 2026'da bu
`pointer-events-none absolute left-5 top-1/2 size-4 -translate-y-1/2 text-slate-400`, alan `pl-12`. `pointer-events-none absolute left-5 top-1/2 size-4 -translate-y-1/2 text-slate-400`, alan `pl-12`.
- **Seçim (`SelectTrigger`)**: aynı hap — `h-12 pl-5 pr-4 text-base`, ok `text-slate-400`; - **Seçim (`SelectTrigger`)**: aynı hap — `h-12 pl-5 pr-4 text-base`, ok `text-slate-400`;
`size="sm"` → `h-9 px-4 text-sm` (yalnız masaüstü tablo aksiyonu, §8). Açılan liste `size="sm"` → `h-9 px-4 text-sm` (yalnız masaüstü tablo aksiyonu, §8). Açılan liste
`rounded-2xl border border-slate-200 bg-white p-1.5 shadow-lg`; satır `rounded-full py-2 pl-4 pr-9 text-base`, `rounded-2xl border border-slate-200 bg-card p-1.5 shadow-lg`; satır `rounded-full py-2 pl-4 pr-9 text-base`,
klavye/odak `bg-slate-100`, seçili işareti `text-primary`. klavye/odak `bg-slate-100`, seçili işareti `text-primary`.
- **Çok satır (`Textarea`)**: hap değil sade kutu (§4.4): `min-h-24 rounded-2xl border border-slate-200 bg-white px-5 py-3 text-base`; - **Ç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 hover/odak/hata metin alanıyla aynı. Sohbet kutusu (`prompt-input.tsx`) kenarlıksız ve şeffaf
üstüne yazar; tek istisna. üstüne yazar; tek istisna.
- **Kenarlıksız ham `<input>`** yalnız kendi hap kabının içinde: il arama - **Kenarlıksız ham `<input>`** yalnız kendi hap kabının içinde: il arama
@@ -265,7 +303,7 @@ yanındaki 2×2).
└──────────────────────┘ └──────────────────────┘
``` ```
- Kap: `flex flex-col rounded-2xl border border-slate-200 bg-white p-4 sm:p-5`. - 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ı"; - Sayı satırı: `flex items-start justify-between gap-1.5`; sayı §3 "Özet kartı sayısı";
ikon kutusu `flex size-8 shrink-0 items-center justify-center rounded-xl bg-primary/10 sm:size-10`. ikon kutusu `flex size-8 shrink-0 items-center justify-center rounded-xl bg-primary/10 sm:size-10`.
- `dl` anlamı için `dt` (başlık) DOM'da önce gelir, görsel sıra `order-*` ile kurulur. - `dl` anlamı için `dt` (başlık) DOM'da önce gelir, görsel sıra `order-*` ile kurulur.
@@ -283,7 +321,7 @@ yanındaki 2×2).
### 4.9 Ayrıntı satırı — `AkademikAyrinti`, `akademik-ayrinti.tsx` ### 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"). Ö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-white p-4 sm:p-5` - `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 + `active:scale-[0.99]`.
- Solda ikon kutusu (`size-11`), ortada iki satır: başlık `font-heading text-lg font-bold`, - Solda ikon kutusu (`size-11`), ortada iki satır: başlık `font-heading text-lg font-bold`,
altında **önizleme** `truncate text-sm text-slate-500` — içeride ne olduğunu söyler ("Hoca altında **önizleme** `truncate text-sm text-slate-500` — içeride ne olduğunu söyler ("Hoca
@@ -293,7 +331,7 @@ yanındaki 2×2).
### 4.10 Alt sayfa (Drawer) içeriği ### 4.10 Alt sayfa (Drawer) içeriği
Ayrıntı her zaman **alttan açılan sayfada** (`Drawer handleOnly`, tutamaçlı); ekranın ortasında 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: açılan modal değil. Çekmece kabı ve çarpı `cta-sira-form.tsx`'teki çekmeceyle birebir:
`DrawerContent className="max-h-[92dvh] bg-white sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl"`. `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ı): İçerik kuralları (Apple ayrıntı sayfası):
- **Her ekranda ortalı:** başlık `px-10 text-center font-heading text-2xl font-bold`, altında - **Her ekranda ortalı:** başlık `px-10 text-center font-heading text-2xl font-bold`, altında
@@ -351,7 +389,7 @@ aşağı kaymış, kare boyları farklı — ne tepeler ne bitişler hizalı.**
### 4.12 Kimlik hapları (tür, il) ### 4.12 Kimlik hapları (tür, il)
Başlığın altında kurumun kimliği; navbar haplarının ölçüsünde: 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-white px-4 text-sm font-semibold text-slate-800` `inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-card px-4 text-sm font-semibold text-slate-800`
+ başta `size-4 text-primary` ikon (`Landmark` devlet, `Building2` vakıf, `MapPin` il). Tür + başta `size-4 text-primary` ikon (`Landmark` devlet, `Building2` vakıf, `MapPin` il). Tür
renkle değil ikonla ayrılır. Rozet (§4.2) değildir. **Devlet/vakıf hapı tür sayfasına** renkle değil ikonla ayrılır. Rozet (§4.2) değildir. **Devlet/vakıf hapı tür sayfasına**
(§4.18), **il hapı şehir sayfasına link**tir (Bilal, 24 Eyl 2026: "şehirlerin geçtiği her yer tıklanabilir") — aynı (§4.18), **il hapı şehir sayfasına link**tir (Bilal, 24 Eyl 2026: "şehirlerin geçtiği her yer tıklanabilir") — aynı
@@ -431,18 +469,18 @@ tablosu bu sabitleri kullanır, sınıfı elle yazmaz.
- Tablo başlığı `h-12 text-sm font-semibold text-slate-500`; hücre dolgusu `py-4 pl-4 sm:pl-5`. - Tablo başlığı `h-12 text-sm font-semibold text-slate-500`; hücre dolgusu `py-4 pl-4 sm:pl-5`.
### 4.16 Bildirim (toast) — `src/components/ui/sonner.tsx` + `globals.css` ### 4.16 Bildirim (toast) — `src/components/ui/sonner.tsx` + `globals.css`
Tema **light'a sabit** (karanlık mod yok, §1.2): sistem koyu temadayken sonner açıklamayı beyaza Tema **sitenin temasını izler** (`useTheme().resolvedTheme`, §2.3), sistemin değil: sistem koyu
yakın griye çevirip beyaz zeminde okunmaz ediyordu (Bilal, 24 Eyl 2026: "toast açıklaması temadayken sonner açıklamayı beyaza yakın griye çevirip beyaz zeminde okunmaz ediyordu (Bilal,
okunmuyor"). Kutu `rounded-2xl border-slate-200`; başlık `font-semibold text-slate-900`; açıklama 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` beyaz `text-slate-600`; aksiyon düğmesi üst çubuktaki koyu hap (`h-9 rounded-full bg-slate-900`,
yazı, hover `slate-700`). Metin §10.4: ne oldu + ne yapılacak; kilometre taşı toast'ları 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. (`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` ### 4.17 Şehir çipleri — `SehirCipleri`, `src/features/katalog/components/sehir-cipleri.tsx`
Şehre göre üniversite gezinmesi (`/universiteler` üstü ve `/universiteler/[il]` altı). Ş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: 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]` `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-white text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500`, + pasif `border-slate-200 bg-card text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500`,
bulunulan şehir `border-primary bg-primary text-white` + `aria-current="page"`. Ad yanında bulunulan şehir `border-primary bg-primary text-white` + `aria-current="page"`. Ad yanında
üniversite sayısı `font-normal tabular-nums text-slate-400` (aktifte `text-white/80`). üniversite sayısı `font-normal tabular-nums text-slate-400` (aktifte `text-white/80`).
- Çip satırında yalnız **2+ üniversiteli** şehirler (≈28) durur; 90'ı aşkın şehrin tamamı - Çip satırında yalnız **2+ üniversiteli** şehirler (≈28) durur; 90'ı aşkın şehrin tamamı
@@ -450,7 +488,7 @@ bulunulan şehir `border-primary bg-primary text-white` + `aria-current="page"`.
bakılan önde, ayrıntı bir dokunuş derinde"). Satırın sonunda "Tüm şehirler (N)" çipi. 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 - Ş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 yüzeyi** (`SehirYuzeyi`: `relative isolate overflow-hidden rounded-3xl border border-slate-200
bg-white p-6 sm:p-8`, `PikselZemin ton="acik"` seed 31, harita kabı `haric`), içinde h1 bg-card p-6 sm:p-8`, `PikselZemin ton="acik"` seed 31, harita kabı `haric`), içinde h1
"İstanbul Üniversiteleri Taban Puanları 2026", kimlik hapları (`MapPin` il + üniversite "İstanbul Üniversiteleri Taban Puanları 2026", kimlik hapları (`MapPin` il + üniversite
sayısı), özet paragraf; sağda (lg, 24rem sütun) ya da altta (telefon) **şehri temsil eden sayısı), özet paragraf; sağda (lg, 24rem sütun) ya da altta (telefon) **şehri temsil eden
piksel harita** `SehirPikselHaritasi`. Sonra kompakt `CtaSiraForm`, `PagePixelDivider` piksel harita** `SehirPikselHaritasi`. Sonra kompakt `CtaSiraForm`, `PagePixelDivider`
@@ -602,7 +640,7 @@ Hareket kuralları (Apple, `motion/react`):
| CTA: metin + sondaki `ArrowRight` | Başta `Sparkles`/yıldız ikonu, "✨" | | 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 | | 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 | | 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-white shadow-sm` | Her şeyde `rounded-3xl`, camsı `backdrop-blur` kartlar, parlama gölgesi | | 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 | | 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 | | 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 | | Harita gibi nefes alanını olduğu gibi bırakmak | Nefes alanını küçültüp bilgi şeridine gömmek |
@@ -613,7 +651,7 @@ Hareket kuralları (Apple, `motion/react`):
| Başlık `font-heading`, vurgu `font-bricolage` | Inter/Roboto/serif, tek kelimelik BÜYÜK HARF etiket, 10–11 px yazı | | 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 | | 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 | | Üç 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ı | | 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ı | | 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` | | 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` |

View File

@@ -97,7 +97,7 @@ const KURALLAR: Kural[] = [
seviye: "hata", seviye: "hata",
mesaj: "Elle yazılmış rozet; SectionEyebrow'u içe aktar (DESIGN.md §4.2)", mesaj: "Elle yazılmış rozet; SectionEyebrow'u içe aktar (DESIGN.md §4.2)",
muaf: /src\/components\/pixel-decor\.tsx$/, muaf: /src\/components\/pixel-decor\.tsx$/,
bul: regexKurali(/rounded-full border border-slate-200 bg-white px-3\.5 py-1\.5/), bul: regexKurali(/rounded-full border border-slate-200 bg-card px-3\.5 py-1\.5/),
}, },
{ {
ad: "modal-rozet", ad: "modal-rozet",
@@ -199,10 +199,28 @@ const KURALLAR: Kural[] = [
}, },
{ {
ad: "dark-sinif", ad: "dark-sinif",
seviye: "uyari", seviye: "hata",
mesaj: "Üründe karanlık mod yok; dark: sınıfı gereksiz (DESIGN.md §1)", mesaj: "Karanlık mod token'la çalışır; dark: sınıfı yazılmaz, .dark bloğuna karşılık eklenir (DESIGN.md §2.3)",
uiDahil: true,
bul: regexKurali(/(?<=[\s"'`])dark:[a-z]/), bul: regexKurali(/(?<=[\s"'`])dark:[a-z]/),
}, },
{
ad: "yuzey-beyaz",
seviye: "hata",
mesaj: "Yüzey zemini bg-card; bg-white koyu temada da beyaz kalır (DESIGN.md §2.3)",
// Bilinçli beyaz kalanlar: logo karosu, kaydırıcı topuzu, sabit paletli
// rehber kapağı. Renkli dolu zemin üstündeki bg-white/15 serbest.
uiDahil: true,
muaf: /src\/components\/(?:uni-logo|ui\/slider|ui\/skiper-ui\/skiper41)\.tsx$|src\/features\/rehber\/components\/rehber-kapak\.tsx$/,
bul: regexKurali(/(?<![\w-])(?:bg|from|to|via)-white(?!\/15)(?![\w-])/),
},
{
ad: "koyu-hap-beyaz-yazi",
seviye: "hata",
mesaj: "Koyu hapta (bg-slate-900) yazı text-slate-50; text-white koyu temada açık hap üstünde kaybolur (DESIGN.md §2.3)",
uiDahil: true,
bul: regexKurali(/\bbg-slate-900\b[^"'`\n]*\btext-white\b|\btext-white\b[^"'`\n]*\bbg-slate-900\b/),
},
{ {
ad: "hex-renk", ad: "hex-renk",
seviye: "uyari", seviye: "uyari",

View File

@@ -82,40 +82,137 @@
--sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0); --sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0); --sidebar-ring: oklch(0.708 0 0);
/* Harita il zeminleri (tercih-haritasi, yurtdisi-haritalar) */
--kt-harita-secili: oklch(0.97 0.014 254.6); /* blue-50 */
--kt-harita-dolu: oklch(0.882 0.059 254.1); /* blue-200 */
} }
.dark { /* Karanlık mod (DESIGN.md §2.3). Bileşenlere `dark:` sınıfı yazılmaz; tema
--background: oklch(0.145 0 0); palet token'larını çevirerek çalışır: slate ölçeği ters döner (50 = sayfa
--foreground: oklch(0.985 0 0); zemini, 900 = başlık metni), yüzeyler `bg-card`'dan gelir, renkli açık
--card: oklch(0.205 0 0); zeminler (orange-50, amber-50…) koyu tona, koyu renkli metinler (amber-900,
--card-foreground: oklch(0.985 0 0); emerald-800…) açık tona iner. `text-white` ve dolu marka zeminleri
--popover: oklch(0.205 0 0); (orange-500, primary, emerald-500…) iki temada aynıdır.
--popover-foreground: oklch(0.985 0 0); `@media screen`: yazdırma çıktısı tema ne olursa olsun açık kalır. */
--primary: oklch(0.707 0.143 254.6); @media screen {
--primary-foreground: oklch(0.145 0 0); .dark {
--secondary: oklch(0.269 0 0); --background: oklch(0.21 0.03 262);
--secondary-foreground: oklch(0.985 0 0); --foreground: oklch(0.95 0.008 250);
--muted: oklch(0.269 0 0); --card: oklch(0.21 0.03 262);
--muted-foreground: oklch(0.708 0 0); --card-foreground: oklch(0.95 0.008 250);
--accent: oklch(0.269 0 0); --popover: oklch(0.21 0.03 262);
--accent-foreground: oklch(0.985 0 0); --popover-foreground: oklch(0.95 0.008 250);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.26 0.03 262);
--secondary-foreground: oklch(0.95 0.008 250);
--muted: oklch(0.26 0.03 262);
--muted-foreground: oklch(0.68 0.04 257);
--accent: oklch(0.26 0.03 262);
--accent-foreground: oklch(0.95 0.008 250);
--destructive: oklch(0.704 0.191 22.216); --destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%); --border: oklch(0.31 0.03 260);
--input: oklch(1 0 0 / 15%); --input: oklch(0.31 0.03 260);
--ring: oklch(0.556 0 0); --sidebar: oklch(0.21 0.03 262);
--chart-1: oklch(0.87 0 0); --sidebar-foreground: oklch(0.95 0.008 250);
--chart-2: oklch(0.556 0 0); --sidebar-primary: oklch(0.623 0.188 259.8);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0); --sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0); --sidebar-accent: oklch(0.26 0.03 262);
--sidebar-accent-foreground: oklch(0.985 0 0); --sidebar-accent-foreground: oklch(0.95 0.008 250);
--sidebar-border: oklch(1 0 0 / 10%); --sidebar-border: oklch(0.31 0.03 260);
--sidebar-ring: oklch(0.556 0 0); --sidebar-ring: oklch(0.556 0 0);
/* Nötr ölçek: ters çevrilmiş slate. 950 çevrilmez — koyu vurgu
yüzeyinin (kt-koyu-yuzey) zeminidir, iki temada koyu kalır. */
--color-slate-50: oklch(0.165 0.025 262);
--color-slate-100: oklch(0.26 0.03 262);
--color-slate-200: oklch(0.31 0.03 260);
--color-slate-300: oklch(0.4 0.035 258);
--color-slate-400: oklch(0.6 0.04 257);
--color-slate-500: oklch(0.68 0.04 257);
--color-slate-600: oklch(0.76 0.035 256);
--color-slate-700: oklch(0.83 0.025 255);
--color-slate-800: oklch(0.89 0.015 255);
--color-slate-900: oklch(0.95 0.008 250);
/* Renkli açık zeminler ve kenarlıklar → koyu ton */
--color-orange-50: oklch(0.27 0.05 50);
--color-orange-100: oklch(0.32 0.07 50);
--color-orange-200: oklch(0.45 0.1 48);
--color-amber-50: oklch(0.27 0.045 80);
--color-amber-100: oklch(0.32 0.06 80);
--color-amber-200: oklch(0.45 0.09 78);
--color-emerald-50: oklch(0.26 0.04 165);
--color-emerald-100: oklch(0.31 0.055 165);
--color-emerald-200: oklch(0.42 0.08 165);
--color-red-50: oklch(0.26 0.05 25);
--color-red-100: oklch(0.31 0.07 25);
--color-red-200: oklch(0.42 0.1 25);
--color-rose-50: oklch(0.26 0.05 12);
--color-rose-100: oklch(0.31 0.07 12);
--color-sky-50: oklch(0.26 0.04 235);
--color-sky-100: oklch(0.31 0.055 235);
--color-sky-200: oklch(0.42 0.07 235);
--color-violet-50: oklch(0.27 0.05 293);
/* Koyu renkli metinler → açık ton (koyu zeminde okunsun) */
--color-orange-700: oklch(0.8 0.13 55);
--color-amber-700: oklch(0.84 0.13 85);
--color-amber-800: oklch(0.88 0.11 88);
--color-amber-900: oklch(0.92 0.08 90);
--color-emerald-600: oklch(0.74 0.15 163);
--color-emerald-700: oklch(0.8 0.13 163);
--color-emerald-800: oklch(0.86 0.11 164);
--color-emerald-900: oklch(0.91 0.08 165);
--color-red-600: oklch(0.7 0.19 24);
--color-red-700: oklch(0.77 0.15 22);
--color-red-800: oklch(0.84 0.11 20);
--color-red-900: oklch(0.9 0.07 18);
--color-rose-700: oklch(0.8 0.12 12);
--color-rose-800: oklch(0.86 0.09 10);
--color-sky-600: oklch(0.74 0.13 235);
--kt-harita-secili: oklch(0.27 0.05 258);
--kt-harita-dolu: oklch(0.42 0.1 258);
}
/* Koyu vurgu yüzeyi (CTA bandı, arama funnel kartı): zemini slate-950,
içindeki açık slate metinler iki temada aynı kalsın diye ölçek burada
açık temadaki değerlerine geri döner. */
.dark .kt-koyu-yuzey {
--color-slate-50: oklch(0.984 0.003 247.858);
--color-slate-100: oklch(0.968 0.007 247.896);
--color-slate-200: oklch(0.929 0.013 255.508);
--color-slate-300: oklch(0.869 0.022 252.894);
--color-slate-400: oklch(0.704 0.04 256.788);
--color-slate-500: oklch(0.554 0.046 257.417);
--color-slate-600: oklch(0.446 0.043 257.281);
--color-slate-700: oklch(0.372 0.044 257.287);
--color-slate-800: oklch(0.279 0.041 260.031);
--color-slate-900: oklch(0.208 0.042 265.755);
}
/* El çizimi şemalar (mermaid) açık kâğıt için çizilir: düğüm renkleri
tanımın içinde sabit. Koyu temada şema beyaz bir kâğıdın üstünde durur. */
.dark .kt-sema-kagit {
padding: 0.75rem;
border-radius: 1rem;
background: #fff;
}
/* Tek renk koyu logolar (URAP): koyu temada açığa çevrilir; yerleşim
oynamaz. Çok renkli marka logolarında kullanılmaz (renk bozulur). */
.dark .kt-koyu-cevir {
filter: invert(1) hue-rotate(180deg);
}
/* Çok renkli, koyu metinli logo görselleri (iyzico bandı: kart markaları)
beyaz hap üstünde durur. */
.dark .kt-acik-logo {
box-sizing: content-box;
padding: 0.5rem 0.875rem;
border-radius: 0.75rem;
background: #fff;
}
} }
/* TypingAnimation imleci (animate-blink-cursor utility'si) */ /* TypingAnimation imleci (animate-blink-cursor utility'si) */
@@ -280,14 +377,14 @@
Maske bulanıklığı aynı yönde söndürür — sert kenar kalmaz. */ Maske bulanıklığı aynı yönde söndürür — sert kenar kalmaz. */
.kt-sayfa-blur-ust { .kt-sayfa-blur-ust {
top: 0; top: 0;
background: linear-gradient(to top, transparent, #f8fafc); background: linear-gradient(to top, transparent, var(--color-slate-50));
-webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent); -webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent);
mask-image: linear-gradient(to bottom, #000 50%, transparent); mask-image: linear-gradient(to bottom, #000 50%, transparent);
} }
.kt-sayfa-blur-alt { .kt-sayfa-blur-alt {
bottom: 0; bottom: 0;
background: linear-gradient(to bottom, transparent, #f8fafc); background: linear-gradient(to bottom, transparent, var(--color-slate-50));
-webkit-mask-image: linear-gradient(to top, #000 50%, transparent); -webkit-mask-image: linear-gradient(to top, #000 50%, transparent);
mask-image: linear-gradient(to top, #000 50%, transparent); mask-image: linear-gradient(to top, #000 50%, transparent);
} }
@@ -373,7 +470,7 @@
border-radius: 9999px; border-radius: 9999px;
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 600; font-weight: 600;
color: #fff; color: var(--color-slate-50);
background: var(--color-slate-900); background: var(--color-slate-900);
} }
.toaster [data-sonner-toast][data-styled="true"] [data-button]:hover { .toaster [data-sonner-toast][data-styled="true"] [data-button]:hover {

View File

@@ -26,7 +26,7 @@ export default function IletisimPage() {
</p> </p>
<a <a
href="mailto:destek@kolaytercih.com" href="mailto:destek@kolaytercih.com"
className="mt-6 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50" className="mt-6 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-card px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50"
> >
<Mail className="size-4 text-primary" aria-hidden /> <Mail className="size-4 text-primary" aria-hidden />
destek@kolaytercih.com destek@kolaytercih.com

View File

@@ -12,6 +12,7 @@ import { HeaderGate } from "@/components/header-gate";
import { DevPanelMount } from "@/components/dev/dev-panel-mount"; import { DevPanelMount } from "@/components/dev/dev-panel-mount";
import { ConsoleAsr } from "@/components/console-asr"; import { ConsoleAsr } from "@/components/console-asr";
import { CerezBilgi } from "@/components/cerez-bilgi"; import { CerezBilgi } from "@/components/cerez-bilgi";
import { TemaSaglayici } from "@/components/tema-saglayici";
import { JsonLd, organizationJsonLd, webSiteJsonLd, SITE_URL } from "@/lib/seo"; import { JsonLd, organizationJsonLd, webSiteJsonLd, SITE_URL } from "@/lib/seo";
import "./globals.css"; import "./globals.css";
@@ -71,7 +72,11 @@ export const metadata: Metadata = {
}; };
export const viewport: Viewport = { export const viewport: Viewport = {
themeColor: "#f8fafc", // Gövde zemini (bg-slate-50) — açık ve koyu temadaki karşılığı
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#f8fafc" },
{ media: "(prefers-color-scheme: dark)", color: "#080e19" },
],
}; };
export default function RootLayout({ export default function RootLayout({
@@ -82,16 +87,20 @@ export default function RootLayout({
return ( return (
<html <html
lang="tr" lang="tr"
// next-themes ilk boyamadan önce <html>'e `dark` sınıfını ve
// color-scheme'i yazar; sunucu HTML'iyle fark beklenen bir farktır.
suppressHydrationWarning
// `h-full` verme: html auto yükseklikte içerikle büyür, viewport tabanı // `h-full` verme: html auto yükseklikte içerikle büyür, viewport tabanı
// body'deki min-h-dvh'den gelir. // body'deki min-h-dvh'den gelir.
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`} className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`}
> >
<body className="min-h-dvh flex flex-col bg-slate-50"> <body className="min-h-dvh flex flex-col bg-slate-50">
<TemaSaglayici>
{/* Klavyeyle gelen için ilk durak: üst bandı ve menüyü atla {/* Klavyeyle gelen için ilk durak: üst bandı ve menüyü atla
(WCAG 2.4.1). Odaklanınca görünür, sitenin hap ölçüsünde. */} (WCAG 2.4.1). Odaklanınca görünür, sitenin hap ölçüsünde. */}
<a <a
href="#icerik" href="#icerik"
className="sr-only focus:not-sr-only focus:fixed focus:top-3 focus:left-3 focus:z-[60] focus:inline-flex focus:h-11 focus:items-center focus:rounded-full focus:border focus:border-slate-200 focus:bg-white focus:px-4 focus:text-sm focus:font-semibold focus:text-slate-900 focus:shadow-lg focus:outline-none focus-visible:ring-3 focus-visible:ring-ring/50" className="sr-only focus:not-sr-only focus:fixed focus:top-3 focus:left-3 focus:z-[60] focus:inline-flex focus:h-11 focus:items-center focus:rounded-full focus:border focus:border-slate-200 focus:bg-card focus:px-4 focus:text-sm focus:font-semibold focus:text-slate-900 focus:shadow-lg focus:outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
> >
İçeriğe geç İçeriğe geç
</a> </a>
@@ -125,6 +134,7 @@ export default function RootLayout({
<ConsoleAsr /> <ConsoleAsr />
{/* Dev süperadmin paneli — prod build'de modül grafiğine bile girmez */} {/* Dev süperadmin paneli — prod build'de modül grafiğine bile girmez */}
{process.env.NODE_ENV !== "production" ? <DevPanelMount /> : null} {process.env.NODE_ENV !== "production" ? <DevPanelMount /> : null}
</TemaSaglayici>
<JsonLd data={organizationJsonLd()} /> <JsonLd data={organizationJsonLd()} />
<JsonLd data={webSiteJsonLd()} /> <JsonLd data={webSiteJsonLd()} />
{/* Rybbit analitik — afterInteractive: hydration sonrası client'ta {/* Rybbit analitik — afterInteractive: hydration sonrası client'ta

View File

@@ -243,7 +243,7 @@ export default function Home() {
</div> </div>
<div <div
aria-hidden aria-hidden
className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(ellipse_58%_52%_at_50%_42%,rgba(248,250,252,0.9)_25%,rgba(248,250,252,0)_75%)]" className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(ellipse_58%_52%_at_50%_42%,color-mix(in_oklab,var(--color-slate-50)_90%,transparent)_25%,transparent_75%)]"
/> />
<Parallax <Parallax
fromStart fromStart
@@ -257,7 +257,7 @@ export default function Home() {
> >
<HeroForm /> <HeroForm />
</div> </div>
<div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-700 shadow-xs"> <div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-card px-3 py-2 text-left text-xs text-slate-700 shadow-xs">
<span> <span>
<strong className="font-semibold text-slate-900"> <strong className="font-semibold text-slate-900">
Veri: YÖK Atlas Veri: YÖK Atlas
@@ -364,7 +364,7 @@ export default function Home() {
<Parallax strength={7} className="mt-12 grid gap-6 md:grid-cols-3"> <Parallax strength={7} className="mt-12 grid gap-6 md:grid-cols-3">
{steps.map((s, i) => ( {steps.map((s, i) => (
<Reveal key={s.step} delay={i * 0.08} className="h-full"> <Reveal key={s.step} delay={i * 0.08} className="h-full">
<div className="relative h-full rounded-2xl border border-slate-200/70 bg-white p-8 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5"> <div className="relative h-full rounded-2xl border border-slate-200/70 bg-card p-8 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5">
<span className="absolute -top-4 left-8 flex size-8 items-center justify-center rounded-full bg-orange-500 font-heading text-sm font-bold text-white"> <span className="absolute -top-4 left-8 flex size-8 items-center justify-center rounded-full bg-orange-500 font-heading text-sm font-bold text-white">
{s.step} {s.step}
</span> </span>
@@ -385,7 +385,7 @@ export default function Home() {
<Parallax strength={10} className="mx-auto mt-12 w-full max-w-3xl"> <Parallax strength={10} className="mx-auto mt-12 w-full max-w-3xl">
<Reveal <Reveal
delay={0.1} delay={0.1}
className="overflow-hidden rounded-2xl border border-slate-200/70 bg-white shadow-sm" className="overflow-hidden rounded-2xl border border-slate-200/70 bg-card shadow-sm"
> >
<dl className="grid grid-cols-1 divide-y divide-slate-200 sm:grid-cols-3 sm:divide-x sm:divide-y-0"> <dl className="grid grid-cols-1 divide-y divide-slate-200 sm:grid-cols-3 sm:divide-x sm:divide-y-0">
{[ {[
@@ -466,10 +466,10 @@ export default function Home() {
lg'de klasik dört sütunlu tablo. */} lg'de klasik dört sütunlu tablo. */}
<Parallax strength={7} className="mt-12"> <Parallax strength={7} className="mt-12">
<Reveal delay={0.08}> <Reveal delay={0.08}>
<div className="rounded-2xl border border-slate-200/70 bg-white shadow-sm lg:hidden"> <div className="rounded-2xl border border-slate-200/70 bg-card shadow-sm lg:hidden">
<div <div
aria-hidden aria-hidden
className="sticky top-24 z-10 grid grid-cols-3 sm:top-32 gap-2 rounded-t-2xl border-b border-slate-100 bg-white/95 px-3 py-3 text-center text-sm font-semibold text-slate-500 backdrop-blur" className="sticky top-24 z-10 grid grid-cols-3 sm:top-32 gap-2 rounded-t-2xl border-b border-slate-100 bg-card/95 px-3 py-3 text-center text-sm font-semibold text-slate-500 backdrop-blur"
> >
<span>Robotlar ve botlar</span> <span>Robotlar ve botlar</span>
<span>İnsan danışman</span> <span>İnsan danışman</span>
@@ -508,7 +508,7 @@ export default function Home() {
</ul> </ul>
</div> </div>
<div className="hidden overflow-hidden rounded-2xl border border-slate-200/70 bg-white shadow-sm lg:block"> <div className="hidden overflow-hidden rounded-2xl border border-slate-200/70 bg-card shadow-sm lg:block">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow className="bg-slate-50 hover:bg-slate-50"> <TableRow className="bg-slate-50 hover:bg-slate-50">
@@ -590,7 +590,7 @@ export default function Home() {
> >
<Reveal <Reveal
delay={0.08} delay={0.08}
className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm" className="rounded-2xl border-2 border-orange-500 bg-card p-8 shadow-sm"
> >
<div className="flex flex-wrap items-baseline justify-between gap-2"> <div className="flex flex-wrap items-baseline justify-between gap-2">
<h3 className="font-heading text-xl font-bold"> <h3 className="font-heading text-xl font-bold">
@@ -643,7 +643,7 @@ export default function Home() {
<Reveal <Reveal
delay={0.16} delay={0.16}
className="flex h-fit flex-col rounded-2xl border border-slate-200/70 bg-white p-6 shadow-sm sm:w-56" className="flex h-fit flex-col rounded-2xl border border-slate-200/70 bg-card p-6 shadow-sm sm:w-56"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Coins className="size-4 text-amber-500" aria-hidden /> <Coins className="size-4 text-amber-500" aria-hidden />
@@ -691,7 +691,7 @@ export default function Home() {
<Accordion <Accordion
type="single" type="single"
collapsible collapsible
className="mt-10 rounded-2xl border border-slate-200/70 bg-white px-6 shadow-sm" className="mt-10 rounded-2xl border border-slate-200/70 bg-card px-6 shadow-sm"
> >
{faqs.map((faq) => ( {faqs.map((faq) => (
<AccordionItem <AccordionItem

View File

@@ -71,7 +71,7 @@ export function AramaFunnelKarti({ onSec }: { onSec: () => void }) {
return ( return (
<section <section
aria-label="Tercih listeni kur" aria-label="Tercih listeni kur"
className="relative isolate mt-5 overflow-hidden rounded-2xl border border-blue-400/20 bg-slate-950 px-4 py-5 text-white sm:px-5" className="kt-koyu-yuzey relative isolate mt-5 overflow-hidden rounded-2xl border border-blue-400/20 bg-slate-950 px-4 py-5 text-white sm:px-5"
> >
<PikselZemin seed={61} /> <PikselZemin seed={61} />
<div className="grid items-center gap-4 sm:grid-cols-[minmax(0,1fr)_auto] sm:gap-5"> <div className="grid items-center gap-4 sm:grid-cols-[minmax(0,1fr)_auto] sm:gap-5">

View File

@@ -47,7 +47,7 @@ export function CtaBandi({
className={cn( className={cn(
"relative isolate overflow-hidden rounded-2xl", "relative isolate overflow-hidden rounded-2xl",
ton === "beyaz" ton === "beyaz"
? "border border-slate-200 bg-white text-slate-900" ? "border border-slate-200 bg-card text-slate-900"
: "bg-primary text-white", : "bg-primary text-white",
buyuk ? "px-5 py-8 text-center sm:p-12" : "px-5 py-4 text-left sm:py-5", buyuk ? "px-5 py-8 text-center sm:p-12" : "px-5 py-4 text-left sm:py-5",
className, className,

View File

@@ -52,8 +52,8 @@ const BASIS =
// Yarı saydam malzeme; şeffaflık azaltılsın diyen kullanıcıya opak yüzey. // Yarı saydam malzeme; şeffaflık azaltılsın diyen kullanıcıya opak yüzey.
const MALZEME = const MALZEME =
"border border-white/60 bg-white/80 shadow-2xl shadow-slate-900/20 backdrop-blur-2xl backdrop-saturate-150 " + "border border-white/60 bg-card/80 shadow-2xl shadow-slate-900/20 backdrop-blur-2xl backdrop-saturate-150 " +
"[@media(prefers-reduced-transparency:reduce)]:bg-white [@media(prefers-reduced-transparency:reduce)]:backdrop-blur-none"; "[@media(prefers-reduced-transparency:reduce)]:bg-card [@media(prefers-reduced-transparency:reduce)]:backdrop-blur-none";
export function DevPanel() { export function DevPanel() {
const [acik, setAcik] = useState(false); const [acik, setAcik] = useState(false);
@@ -139,7 +139,7 @@ export function DevPanel() {
onClick={paneliAc} onClick={paneliAc}
title="Dev süperadmin paneli" title="Dev süperadmin paneli"
style={{ borderRadius: 18 }} style={{ borderRadius: 18 }}
className={`fixed bottom-20 left-4 z-50 inline-flex h-9 cursor-pointer items-center gap-1.5 px-3 text-xs font-bold tracking-wide text-white ${MALZEME} !bg-slate-900/85 print:hidden ${BASIS} hover:!bg-slate-800/85`} className={`fixed bottom-20 left-4 z-50 inline-flex h-9 cursor-pointer items-center gap-1.5 px-3 text-xs font-bold tracking-wide text-slate-50 ${MALZEME} !bg-slate-900/85 print:hidden ${BASIS} hover:!bg-slate-800/85`}
> >
<Wrench className="size-3.5 text-violet-300" aria-hidden /> <Wrench className="size-3.5 text-violet-300" aria-hidden />
DEV DEV
@@ -186,7 +186,7 @@ export function DevPanel() {
Oturum Oturum
</p> </p>
{g ? ( {g ? (
<div className="mt-2 rounded-xl border border-slate-900/5 bg-white/60 px-3 py-2 text-xs"> <div className="mt-2 rounded-xl border border-slate-900/5 bg-card/60 px-3 py-2 text-xs">
<p className="font-semibold text-slate-800">{g.email}</p> <p className="font-semibold text-slate-800">{g.email}</p>
<p className="mt-0.5 tabular-nums text-slate-500"> <p className="mt-0.5 tabular-nums text-slate-500">
{g.kredi} kredi · {g.hasPaket ? "paketli" : "paketsiz"} ·{" "} {g.kredi} kredi · {g.hasPaket ? "paketli" : "paketsiz"} ·{" "}
@@ -218,7 +218,7 @@ export function DevPanel() {
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
placeholder="deneme@ornek.dev" placeholder="deneme@ornek.dev"
className="h-9 min-w-0 flex-1 rounded-lg border border-slate-900/10 bg-white/70 px-2.5 text-xs outline-none transition-colors duration-150 focus-visible:border-violet-400" className="h-9 min-w-0 flex-1 rounded-lg border border-slate-900/10 bg-card/70 px-2.5 text-xs outline-none transition-colors duration-150 focus-visible:border-violet-400"
/> />
<button <button
type="button" type="button"
@@ -272,7 +272,7 @@ export function DevPanel() {
type="button" type="button"
disabled={mesgul || !g} disabled={mesgul || !g}
onClick={() => calistir(s.fn)} onClick={() => calistir(s.fn)}
className={`cursor-pointer rounded-xl border border-slate-900/10 bg-white/60 px-2.5 py-2 text-left text-xs hover:border-violet-300 hover:bg-violet-50/80 disabled:cursor-default disabled:opacity-40 ${BASIS}`} className={`cursor-pointer rounded-xl border border-slate-900/10 bg-card/60 px-2.5 py-2 text-left text-xs hover:border-violet-300 hover:bg-violet-50/80 disabled:cursor-default disabled:opacity-40 ${BASIS}`}
> >
<span className="block font-semibold text-slate-800"> <span className="block font-semibold text-slate-800">
{s.ad} {s.ad}
@@ -325,7 +325,7 @@ export function DevPanel() {
<a <a
key={s.href} key={s.href}
href={s.href} href={s.href}
className={`cursor-pointer rounded-full border border-slate-900/10 bg-white/60 px-2.5 py-1 text-[11px] text-slate-700 hover:border-violet-300 hover:bg-violet-50/80 ${BASIS}`} className={`cursor-pointer rounded-full border border-slate-900/10 bg-card/60 px-2.5 py-1 text-[11px] text-slate-700 hover:border-violet-300 hover:bg-violet-50/80 ${BASIS}`}
> >
{s.ad} {s.ad}
</a> </a>

View File

@@ -31,7 +31,7 @@ export function OzetKart({
}) { }) {
return ( return (
<div <div
className={`flex flex-col rounded-2xl border border-slate-200 bg-white p-4 sm:p-5 ${className ?? ""}`} className={`flex flex-col rounded-2xl border border-slate-200 bg-card p-4 sm:p-5 ${className ?? ""}`}
> >
<dt className="order-2 mt-2 text-base font-semibold text-slate-900"> <dt className="order-2 mt-2 text-base font-semibold text-slate-900">
{etiket} {etiket}

View File

@@ -38,7 +38,7 @@ export function PikselCtaYuzeyi({
onFocusCapture={(e) => setTamamla(hedefMi(e.target))} onFocusCapture={(e) => setTamamla(hedefMi(e.target))}
onBlurCapture={() => setTamamla(false)} onBlurCapture={() => setTamamla(false)}
className={cn( className={cn(
"relative isolate overflow-hidden rounded-3xl border border-blue-400/20 bg-slate-950 text-white shadow-xl shadow-slate-900/10", "kt-koyu-yuzey relative isolate overflow-hidden rounded-3xl border border-blue-400/20 bg-slate-950 text-white shadow-xl shadow-slate-900/10",
className, className,
)} )}
> >

View File

@@ -481,7 +481,7 @@ export function SectionEyebrow({
return ( return (
<span <span
className={cn( className={cn(
"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", "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",
className, className,
)} )}
> >

View File

@@ -2,6 +2,7 @@ import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { Amiri_Quran } from "next/font/google"; import { Amiri_Quran } from "next/font/google";
import { PixelMark } from "@/components/pixel-decor"; import { PixelMark } from "@/components/pixel-decor";
import { TemaSecici } from "@/components/tema-secici";
import { getAllBolumler } from "@/lib/katalog"; import { getAllBolumler } from "@/lib/katalog";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -199,6 +200,7 @@ export function SiteFooter() {
İletişim İletişim
</Link> </Link>
</nav> </nav>
<TemaSecici className="mt-6" />
{/* iyzico işyeri sözleşmesi gereği: "iyzico ile Öde" + kart logoları {/* iyzico işyeri sözleşmesi gereği: "iyzico ile Öde" + kart logoları
sitede görünür olmalı. Resmî logo bandı (iyzico logo paketi). */} sitede görünür olmalı. Resmî logo bandı (iyzico logo paketi). */}
<Image <Image
@@ -206,7 +208,7 @@ export function SiteFooter() {
alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme" alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme"
width={429} width={429}
height={32} height={32}
className="mx-auto mt-6 h-6 w-auto" className="kt-acik-logo mx-auto mt-6 h-6 w-auto"
/> />
</div> </div>
</div> </div>

View File

@@ -0,0 +1,43 @@
"use client";
import { useEffect } from "react";
import { ThemeProvider, useTheme } from "next-themes";
// Gövde zemini (bg-slate-50) — açık ve koyu temadaki karşılığı
const ZEMIN = { light: "#f8fafc", dark: "#080e19" };
/**
* Mobil adres çubuğu rengi: layout'taki `themeColor` sistemi izler; kullanıcı
* sitede sistemden farklı bir tema seçtiyse meta etiketleri ona eşitlenir.
*/
function AdresCubuguRengi() {
const { resolvedTheme } = useTheme();
useEffect(() => {
const renk = resolvedTheme === "dark" ? ZEMIN.dark : ZEMIN.light;
for (const meta of document.querySelectorAll('meta[name="theme-color"]')) {
meta.setAttribute("content", renk);
}
}, [resolvedTheme]);
return null;
}
/**
* Tema (DESIGN.md §2.3): <html>'e `dark` sınıfı yazılır, renkler
* globals.css'teki `.dark` token eşlemesinden gelir. Varsayılan açık tema;
* kullanıcı footer'daki TemaSecici ile koyu ya da "sistem"e geçer, seçim
* tarayıcıda saklanır.
*/
export function TemaSaglayici({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider
attribute="class"
defaultTheme="light"
enableSystem
storageKey="kt-tema"
disableTransitionOnChange
>
<AdresCubuguRengi />
{children}
</ThemeProvider>
);
}

View File

@@ -0,0 +1,61 @@
"use client";
import { useSyncExternalStore } from "react";
import { useTheme } from "next-themes";
import { Monitor, Moon, Sun } from "lucide-react";
import { cn } from "@/lib/utils";
const SECENEKLER = [
{ deger: "light", etiket: "Açık", ikon: Sun },
{ deger: "dark", etiket: "Koyu", ikon: Moon },
{ deger: "system", etiket: "Sistem", ikon: Monitor },
] as const;
const aboneOlma = () => () => {};
/**
* Tema seçici: açık / koyu / sistem (DESIGN.md §2.3). Seçili tema yalnızca
* tarayıcıda bilinir; sunucu HTML'inde hiçbir seçenek işaretli gelmez,
* hydration sonrası işaretlenir (yerleşim oynamaz).
*/
export function TemaSecici({ className }: { className?: string }) {
const { theme, setTheme } = useTheme();
const tarayicida = useSyncExternalStore(
aboneOlma,
() => true,
() => false,
);
return (
<div
role="radiogroup"
aria-label="Tema"
className={cn(
"inline-flex items-center gap-1 rounded-full border border-slate-200 bg-card p-1",
className,
)}
>
{SECENEKLER.map(({ deger, etiket, ikon: Ikon }) => {
const secili = tarayicida && theme === deger;
return (
<button
key={deger}
type="button"
role="radio"
aria-checked={secili}
onClick={() => setTheme(deger)}
className={cn(
"inline-flex h-9 cursor-pointer items-center gap-1.5 rounded-full px-3 text-sm font-semibold transition-[background-color,color,transform] duration-150 outline-none focus-visible:ring-3 focus-visible:ring-ring/50 active:scale-[0.97]",
secili
? "bg-slate-900 text-slate-50"
: "text-slate-600 hover:text-orange-500",
)}
>
<Ikon className="size-4" aria-hidden />
{etiket}
</button>
);
})}
</div>
);
}

View File

@@ -17,7 +17,7 @@ function Avatar({
data-slot="avatar" data-slot="avatar"
data-size={size} data-size={size}
className={cn( className={cn(
"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", "group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6",
className className
)} )}
{...props} {...props}

View File

@@ -5,7 +5,7 @@ import { Slot } from "radix-ui"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
const badgeVariants = cva( const badgeVariants = cva(
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 [&>svg]:pointer-events-none [&>svg]:size-3!",
{ {
variants: { variants: {
variant: { variant: {
@@ -13,11 +13,11 @@ const badgeVariants = cva(
secondary: secondary:
"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80", "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
destructive: destructive:
"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20", "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 [a]:hover:bg-destructive/20",
outline: outline:
"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground", "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
ghost: ghost:
"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50", "hover:bg-muted hover:text-muted-foreground",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline",
}, },
}, },

View File

@@ -5,19 +5,19 @@ import { Slot } from "radix-ui"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
const buttonVariants = cva( const buttonVariants = cva(
"group/button inline-flex shrink-0 items-center justify-center rounded-full border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "group/button inline-flex shrink-0 items-center justify-center rounded-full border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
{ {
variants: { variants: {
variant: { variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/80", default: "bg-primary text-primary-foreground hover:bg-primary/80",
outline: outline:
"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50", "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
secondary: secondary:
"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
ghost: ghost:
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50", "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
destructive: destructive:
"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40", "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline",
}, },
size: { size: {

View File

@@ -1,6 +1,7 @@
"use client" "use client"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
import { useTheme } from "next-themes"
import React, { useEffect, useState } from "react" import React, { useEffect, useState } from "react"
export type CodeBlockProps = { export type CodeBlockProps = {
@@ -33,11 +34,15 @@ export type CodeBlockCodeProps = {
function CodeBlockCode({ function CodeBlockCode({
code, code,
language = "tsx", language = "tsx",
theme = "github-light", theme: temaProp,
className, className,
...props ...props
}: CodeBlockCodeProps) { }: CodeBlockCodeProps) {
const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null) const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)
// Tema verilmediyse sitenin temasını izler (DESIGN.md §2.3)
const { resolvedTheme } = useTheme()
const theme =
temaProp ?? (resolvedTheme === "dark" ? "github-dark" : "github-light")
useEffect(() => { useEffect(() => {
async function highlight() { async function highlight() {

View File

@@ -13,7 +13,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
type={type} type={type}
data-slot="input" data-slot="input"
className={cn( className={cn(
"h-12 w-full min-w-0 rounded-full border border-slate-200 bg-white px-5 text-base text-slate-900 transition-colors duration-150 outline-none placeholder:text-slate-400 hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-slate-50 disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20", "h-12 w-full min-w-0 rounded-full border border-slate-200 bg-card px-5 text-base text-slate-900 transition-colors duration-150 outline-none placeholder:text-slate-400 hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-slate-50 disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20",
className className
)} )}
{...props} {...props}

View File

@@ -5,7 +5,7 @@ function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
<kbd <kbd
data-slot="kbd" data-slot="kbd"
className={cn( className={cn(
"pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3", "pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background [&_svg:not([class*='size-'])]:size-3",
className className
)} )}
{...props} {...props}

View File

@@ -44,7 +44,7 @@ function SelectTrigger({
data-slot="select-trigger" data-slot="select-trigger"
data-size={size} data-size={size}
className={cn( className={cn(
"flex w-fit cursor-pointer items-center justify-between gap-2 rounded-full border border-slate-200 bg-white py-2 pr-4 pl-5 text-base text-slate-900 whitespace-nowrap transition-colors duration-150 outline-none select-none hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20 data-placeholder:text-slate-400 data-[size=default]:h-12 data-[size=sm]:h-9 data-[size=sm]:pr-3 data-[size=sm]:pl-4 data-[size=sm]:text-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "flex w-fit cursor-pointer items-center justify-between gap-2 rounded-full border border-slate-200 bg-card py-2 pr-4 pl-5 text-base text-slate-900 whitespace-nowrap transition-colors duration-150 outline-none select-none hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20 data-placeholder:text-slate-400 data-[size=default]:h-12 data-[size=sm]:h-9 data-[size=sm]:pr-3 data-[size=sm]:pl-4 data-[size=sm]:text-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className className
)} )}
{...props} {...props}
@@ -69,7 +69,7 @@ function SelectContent({
<SelectPrimitive.Content <SelectPrimitive.Content
data-slot="select-content" data-slot="select-content"
data-align-trigger={position === "item-aligned"} data-align-trigger={position === "item-aligned"}
className={cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-2xl border border-slate-200 bg-white text-slate-900 shadow-lg duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )} className={cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-2xl border border-slate-200 bg-card text-slate-900 shadow-lg duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
position={position} position={position}
align={align} align={align}
{...props} {...props}
@@ -148,7 +148,7 @@ function SelectScrollUpButton({
<SelectPrimitive.ScrollUpButton <SelectPrimitive.ScrollUpButton
data-slot="select-scroll-up-button" data-slot="select-scroll-up-button"
className={cn( className={cn(
"z-10 flex cursor-default items-center justify-center bg-white py-1 text-slate-400 [&_svg:not([class*='size-'])]:size-4", "z-10 flex cursor-default items-center justify-center bg-card py-1 text-slate-400 [&_svg:not([class*='size-'])]:size-4",
className className
)} )}
{...props} {...props}
@@ -167,7 +167,7 @@ function SelectScrollDownButton({
<SelectPrimitive.ScrollDownButton <SelectPrimitive.ScrollDownButton
data-slot="select-scroll-down-button" data-slot="select-scroll-down-button"
className={cn( className={cn(
"z-10 flex cursor-default items-center justify-center bg-white py-1 text-slate-400 [&_svg:not([class*='size-'])]:size-4", "z-10 flex cursor-default items-center justify-center bg-card py-1 text-slate-400 [&_svg:not([class*='size-'])]:size-4",
className className
)} )}
{...props} {...props}

View File

@@ -1,18 +1,20 @@
"use client" "use client"
import { useTheme } from "next-themes"
import { Toaster as Sonner, type ToasterProps } from "sonner" import { Toaster as Sonner, type ToasterProps } from "sonner"
import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon } from "lucide-react" import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon } from "lucide-react"
/** /**
* Bildirimler (DESIGN.md §4.16). Tema "light"e sabit: üründe karanlık mod * Bildirimler (DESIGN.md §4.16). Tema sitenin temasını izler (sistemin
* yok (§1.2); sistem koyu temadayken sonner açıklamayı beyaza yakın griye * değil): sonner kendi "system" algısıyla açık sitede koyu toast metni
* çevirip beyaz zeminde okunmaz hâle getiriyordu (Bilal, 24 Eyl 2026: * basıp açıklamayı okunmaz ediyordu (Bilal, 24 Eyl 2026: "toast açıklaması
* "toast açıklaması okunmuyor"). Metin ve buton renkleri globals.css'te. * okunmuyor"). Metin ve buton renkleri globals.css'te.
*/ */
const Toaster = ({ ...props }: ToasterProps) => { const Toaster = ({ ...props }: ToasterProps) => {
const { resolvedTheme } = useTheme()
return ( return (
<Sonner <Sonner
theme="light" theme={resolvedTheme === "dark" ? "dark" : "light"}
className="toaster group" className="toaster group"
icons={{ icons={{
success: ( success: (

View File

@@ -33,7 +33,7 @@ const tabsListVariants = cva(
line: "gap-1 bg-transparent", line: "gap-1 bg-transparent",
// Nav'daki "Giriş yap" pili ile aynı dil: beyaz kapsül içinde koyu // Nav'daki "Giriş yap" pili ile aynı dil: beyaz kapsül içinde koyu
// aktif hap (bkz. user-nav.tsx). Kayan gösterge tüketicide çizilir. // aktif hap (bkz. user-nav.tsx). Kayan gösterge tüketicide çizilir.
pill: "gap-1 rounded-full border border-slate-200 bg-white p-1 group-data-horizontal/tabs:h-auto", pill: "gap-1 rounded-full border border-slate-200 bg-card p-1 group-data-horizontal/tabs:h-auto",
}, },
}, },
defaultVariants: { defaultVariants: {
@@ -66,12 +66,12 @@ function TabsTrigger({
<TabsPrimitive.Trigger <TabsPrimitive.Trigger
data-slot="tabs-trigger" data-slot="tabs-trigger"
className={cn( className={cn(
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent",
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground", "data-active:bg-background data-active:text-foreground",
// Pill varyantı: arka planı tüketicideki kayan gösterge verir, trigger // Pill varyantı: arka planı tüketicideki kayan gösterge verir, trigger
// şeffaf kalır; aktif metin koyu hap üstünde beyaza döner. // şeffaf kalır; aktif metin koyu hap üstünde açık tona döner (koyu temada hap açık, metin koyu).
"group-data-[variant=pill]/tabs-list:h-auto group-data-[variant=pill]/tabs-list:rounded-full group-data-[variant=pill]/tabs-list:data-active:bg-transparent group-data-[variant=pill]/tabs-list:data-active:text-white", "group-data-[variant=pill]/tabs-list:h-auto group-data-[variant=pill]/tabs-list:rounded-full group-data-[variant=pill]/tabs-list:data-active:bg-transparent group-data-[variant=pill]/tabs-list:data-active:text-slate-50",
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
className className
)} )}

View File

@@ -12,7 +12,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
<textarea <textarea
data-slot="textarea" data-slot="textarea"
className={cn( className={cn(
"flex field-sizing-content min-h-24 w-full rounded-2xl border border-slate-200 bg-white px-5 py-3 text-base text-slate-900 transition-colors duration-150 outline-none placeholder:text-slate-400 hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-slate-50 disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20", "flex field-sizing-content min-h-24 w-full rounded-2xl border border-slate-200 bg-card px-5 py-3 text-base text-slate-900 transition-colors duration-150 outline-none placeholder:text-slate-400 hover:border-slate-300 focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-slate-50 disabled:opacity-50 aria-invalid:border-red-500 aria-invalid:ring-3 aria-invalid:ring-red-500/20",
className className
)} )}
{...props} {...props}

View File

@@ -167,7 +167,7 @@ export function BolumProgramListesi({
<> <>
<div <div
ref={listeRef} ref={listeRef}
className="scroll-mt-24 overflow-hidden rounded-2xl border border-slate-200 bg-white" className="scroll-mt-24 overflow-hidden rounded-2xl border border-slate-200 bg-card"
> >
{/* Şişko ve sade (DESIGN.md §4.15): üniversite adı kesilmez, sarar; {/* Şişko ve sade (DESIGN.md §4.15): üniversite adı kesilmez, sarar;
satır butonları 44 px. 375 px'te yalnız ad + butonlar sütun satır butonları 44 px. 375 px'te yalnız ad + butonlar sütun

View File

@@ -149,11 +149,11 @@ export function IlIcerik({ slug }: { slug: string }) {
{/* Kimlik hapları (DESIGN.md §4.12): il + üniversite sayısı */} {/* Kimlik hapları (DESIGN.md §4.12): il + üniversite sayısı */}
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start"> <p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start">
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800"> <span className="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">
<MapPin className="size-4 text-primary" aria-hidden /> <MapPin className="size-4 text-primary" aria-hidden />
{il.ad} {il.ad}
</span> </span>
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800"> <span className="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">
{devlet.length >= vakif.length ? ( {devlet.length >= vakif.length ? (
<Landmark className="size-4 text-primary" aria-hidden /> <Landmark className="size-4 text-primary" aria-hidden />
) : ( ) : (

View File

@@ -85,19 +85,19 @@ function macMiOku(): boolean {
const KESFET_TONLARI = { const KESFET_TONLARI = {
slate: { slate: {
pencere: "border-slate-200/80 bg-white", pencere: "border-slate-200/80 bg-card",
nokta: "bg-slate-300", nokta: "bg-slate-300",
rozet: "border-slate-200 bg-slate-50 text-slate-600", rozet: "border-slate-200 bg-slate-50 text-slate-600",
cizgi: "bg-slate-200/90", cizgi: "bg-slate-200/90",
}, },
sky: { sky: {
pencere: "border-sky-200/70 bg-white", pencere: "border-sky-200/70 bg-card",
nokta: "bg-sky-300", nokta: "bg-sky-300",
rozet: "border-sky-200 bg-sky-50 text-sky-600", rozet: "border-sky-200 bg-sky-50 text-sky-600",
cizgi: "bg-sky-100", cizgi: "bg-sky-100",
}, },
amber: { amber: {
pencere: "border-amber-200/70 bg-white", pencere: "border-amber-200/70 bg-card",
nokta: "bg-amber-300", nokta: "bg-amber-300",
rozet: "border-amber-200 bg-amber-50 text-amber-600", rozet: "border-amber-200 bg-amber-50 text-amber-600",
cizgi: "bg-amber-100", cizgi: "bg-amber-100",
@@ -267,7 +267,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
return ( return (
<> <>
{/* lg altında logo + sağ küme ile çakışır (absolute); o aralıkta gizli */} {/* lg altında logo + sağ küme ile çakışır (absolute); o aralıkta gizli */}
<nav className="absolute left-1/2 hidden -translate-x-1/2 items-center gap-1 rounded-full border border-slate-200 bg-white p-1.5 text-base font-medium text-slate-600 lg:flex"> <nav className="absolute left-1/2 hidden -translate-x-1/2 items-center gap-1 rounded-full border border-slate-200 bg-card p-1.5 text-base font-medium text-slate-600 lg:flex">
{profil ? ( {profil ? (
<button <button
type="button" type="button"
@@ -289,7 +289,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
</span> </span>
<span <span
aria-hidden aria-hidden
className="flex max-w-0 items-center gap-1 overflow-hidden rounded-full bg-slate-100 px-0 py-1.5 text-xs font-medium text-slate-500 opacity-0 transition-[max-width,padding,opacity,background-color,color] duration-200 group-hover/profil:max-w-28 group-hover/profil:bg-white group-hover/profil:px-2.5 group-hover/profil:text-slate-900 group-hover/profil:opacity-100 group-focus-visible/profil:max-w-28 group-focus-visible/profil:bg-white group-focus-visible/profil:px-2.5 group-focus-visible/profil:text-slate-900 group-focus-visible/profil:opacity-100" className="flex max-w-0 items-center gap-1 overflow-hidden rounded-full bg-slate-100 px-0 py-1.5 text-xs font-medium text-slate-500 opacity-0 transition-[max-width,padding,opacity,background-color,color] duration-200 group-hover/profil:max-w-28 group-hover/profil:bg-card group-hover/profil:px-2.5 group-hover/profil:text-slate-900 group-hover/profil:opacity-100 group-focus-visible/profil:max-w-28 group-focus-visible/profil:bg-card group-focus-visible/profil:px-2.5 group-focus-visible/profil:text-slate-900 group-focus-visible/profil:opacity-100"
> >
<SquarePen className="size-3 shrink-0" aria-hidden /> <SquarePen className="size-3 shrink-0" aria-hidden />
Değiştir Değiştir
@@ -318,15 +318,15 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
<button <button
type="button" type="button"
onClick={() => modalDegisti(true)} onClick={() => modalDegisti(true)}
className="flex cursor-pointer items-center gap-2 rounded-full bg-slate-900 px-5 py-2 text-white transition-[background-color,transform] duration-150 hover:bg-slate-700 active:scale-[0.97]" className="flex cursor-pointer items-center gap-2 rounded-full bg-slate-900 px-5 py-2 text-slate-50 transition-[background-color,transform] duration-150 hover:bg-slate-700 active:scale-[0.97]"
> >
<Search className="size-4" aria-hidden /> <Search className="size-4" aria-hidden />
Ara Ara
<KbdGroup aria-hidden className="ml-1"> <KbdGroup aria-hidden className="ml-1">
<Kbd className="bg-white/15 text-white/85"> <Kbd className="bg-slate-50/15 text-slate-50/85">
{macMi ? "⌘" : "Ctrl"} {macMi ? "⌘" : "Ctrl"}
</Kbd> </Kbd>
<Kbd className="bg-white/15 text-white/85">K</Kbd> <Kbd className="bg-slate-50/15 text-slate-50/85">K</Kbd>
</KbdGroup> </KbdGroup>
</button> </button>
</nav> </nav>
@@ -340,7 +340,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
onPointerEnter={preloadTercihProfiliKapisi} onPointerEnter={preloadTercihProfiliKapisi}
onFocus={preloadTercihProfiliKapisi} onFocus={preloadTercihProfiliKapisi}
aria-label={`Sıralamanı ve tercihlerini değiştir (${profil.sira.toLocaleString("tr-TR")} · ${PUAN_TURU_ETIKET[profil.tur] ?? profil.tur})`} aria-label={`Sıralamanı ve tercihlerini değiştir (${profil.sira.toLocaleString("tr-TR")} · ${PUAN_TURU_ETIKET[profil.tur] ?? profil.tur})`}
className="flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-white py-1 pl-2.5 pr-1.5 text-xs font-semibold text-slate-900 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:h-12 sm:gap-2 sm:pl-3.5 sm:pr-2 sm:text-sm" className="flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-card py-1 pl-2.5 pr-1.5 text-xs font-semibold text-slate-900 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:h-12 sm:gap-2 sm:pl-3.5 sm:pr-2 sm:text-sm"
> >
<Trophy <Trophy
className="size-3.5 shrink-0 text-orange-500 sm:size-4" className="size-3.5 shrink-0 text-orange-500 sm:size-4"
@@ -367,7 +367,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
onPointerEnter={preloadTercihProfiliKapisi} onPointerEnter={preloadTercihProfiliKapisi}
onFocus={preloadTercihProfiliKapisi} onFocus={preloadTercihProfiliKapisi}
aria-label="Başarı sıralamanı gir" aria-label="Başarı sıralamanı gir"
className="flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-white py-1 pl-2.5 pr-2.5 text-xs font-semibold text-slate-900 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:h-12 sm:gap-2 sm:pl-3.5 sm:pr-3 sm:text-sm" className="flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-card py-1 pl-2.5 pr-2.5 text-xs font-semibold text-slate-900 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:h-12 sm:gap-2 sm:pl-3.5 sm:pr-3 sm:text-sm"
> >
<Trophy <Trophy
className="size-3.5 shrink-0 text-orange-500 sm:size-4" className="size-3.5 shrink-0 text-orange-500 sm:size-4"
@@ -380,7 +380,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
type="button" type="button"
onClick={() => modalDegisti(true)} onClick={() => modalDegisti(true)}
aria-label="Bölüm, üniversite veya rehber ara" aria-label="Bölüm, üniversite veya rehber ara"
className="flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white text-slate-700 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:size-12" className="flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-card text-slate-700 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:size-12"
> >
<Search className="size-4" aria-hidden /> <Search className="size-4" aria-hidden />
</button> </button>
@@ -393,7 +393,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
event.preventDefault(); event.preventDefault();
inputRef.current?.focus(); inputRef.current?.focus();
}} }}
className="max-h-[min(720px,calc(100dvh-2rem))] grid-rows-[auto_minmax(0,1fr)_auto] gap-0 overflow-hidden rounded-2xl bg-white p-0 duration-200 sm:max-w-2xl motion-reduce:data-open:zoom-in-100 motion-reduce:data-closed:zoom-out-100" className="max-h-[min(720px,calc(100dvh-2rem))] grid-cols-[minmax(0,1fr)] grid-rows-[auto_minmax(0,1fr)_auto] gap-0 overflow-hidden rounded-2xl bg-card p-0 duration-200 sm:max-w-2xl motion-reduce:data-open:zoom-in-100 motion-reduce:data-closed:zoom-out-100"
> >
<DialogTitle className="sr-only"> <DialogTitle className="sr-only">
Bölüm, üniversite ve rehber ara Bölüm, üniversite ve rehber ara
@@ -416,7 +416,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
placeholder="Bölüm, üniversite veya rehber ara..." placeholder="Bölüm, üniversite veya rehber ara..."
aria-label="Bölüm, üniversite veya rehber ara" aria-label="Bölüm, üniversite veya rehber ara"
autoComplete="off" autoComplete="off"
className="h-16 min-w-0 flex-1 bg-transparent text-base text-slate-950 outline-none placeholder:text-slate-400 sm:h-18 sm:text-lg" className="h-16 min-w-0 flex-1 bg-transparent text-base text-slate-900 outline-none placeholder:text-slate-400 sm:h-18 sm:text-lg"
/> />
<button <button
type="button" type="button"
@@ -531,7 +531,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
> >
<ProgressiveBlur <ProgressiveBlur
position="top" position="top"
backgroundColor="#ffffff" backgroundColor="var(--card)"
height="56px" height="56px"
blurAmount="4px" blurAmount="4px"
/> />
@@ -542,7 +542,7 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
> >
<ProgressiveBlur <ProgressiveBlur
position="bottom" position="bottom"
backgroundColor="#ffffff" backgroundColor="var(--card)"
height="56px" height="56px"
blurAmount="4px" blurAmount="4px"
/> />
@@ -550,7 +550,11 @@ export function KatalogArama({ rehberler }: { rehberler: RehberAramaKaydi[] }) {
</div> </div>
<div className="flex items-center justify-between border-t border-slate-200 bg-slate-50/80 px-4 py-3 text-xs text-slate-500 sm:px-5"> <div className="flex items-center justify-between border-t border-slate-200 bg-slate-50/80 px-4 py-3 text-xs text-slate-500 sm:px-5">
<span>En az 2 harf yazarak ara</span> <span>
{aramaAktif
? "Bölüm, üniversite ve rehberde aranıyor"
: "En az 2 harf yazarak ara"}
</span>
<span className="hidden items-center gap-1.5 sm:flex"> <span className="hidden items-center gap-1.5 sm:flex">
<Kbd>Esc</Kbd> ile kapat <Kbd>Esc</Kbd> ile kapat
</span> </span>
@@ -597,7 +601,7 @@ function BaslangicIcerigi({ onSec }: { onSec: () => void }) {
/> />
</div> </div>
<div className="mt-5 flex gap-3 rounded-2xl bg-slate-50 px-3.5 py-3.5 sm:px-4"> <div className="mt-5 flex gap-3 rounded-2xl bg-slate-50 px-3.5 py-3.5 sm:px-4">
<span className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full bg-white text-slate-400 shadow-[0_0_0_1px_rgba(15,23,42,0.06)]"> <span className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full bg-card text-slate-400 shadow-[0_0_0_1px_rgba(15,23,42,0.06)]">
<Search className="size-3.5" aria-hidden /> <Search className="size-3.5" aria-hidden />
</span> </span>
<div className="min-w-0"> <div className="min-w-0">
@@ -638,7 +642,7 @@ function KesfetLinki({
<Link <Link
href={href} href={href}
onClick={onSec} onClick={onSec}
className="group/kesfet flex cursor-pointer flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white transition-transform duration-150 ease-out active:scale-[0.97]" className="group/kesfet flex cursor-pointer flex-col overflow-hidden rounded-2xl border border-slate-200 bg-card transition-transform duration-150 ease-out active:scale-[0.97]"
> >
{/* Mini tarayıcı — sekme içinde tek büyük ikon, alta doğru maske ile solar */} {/* Mini tarayıcı — sekme içinde tek büyük ikon, alta doğru maske ile solar */}
<div <div
@@ -652,7 +656,7 @@ function KesfetLinki({
<span className={`size-1.5 rounded-full ${palet.nokta}`} /> <span className={`size-1.5 rounded-full ${palet.nokta}`} />
<span className={`size-1.5 rounded-full ${palet.nokta} opacity-65`} /> <span className={`size-1.5 rounded-full ${palet.nokta} opacity-65`} />
<span className={`size-1.5 rounded-full ${palet.nokta} opacity-35`} /> <span className={`size-1.5 rounded-full ${palet.nokta} opacity-35`} />
<span className="ml-1.5 h-1.5 max-w-[55%] flex-1 rounded-full bg-white shadow-[0_0_0_1px_rgba(15,23,42,0.06)]" /> <span className="ml-1.5 h-1.5 max-w-[55%] flex-1 rounded-full bg-card shadow-[0_0_0_1px_rgba(15,23,42,0.06)]" />
</div> </div>
<div className="relative min-h-0 flex-1 overflow-hidden"> <div className="relative min-h-0 flex-1 overflow-hidden">
<div className="absolute inset-x-0 top-0 flex flex-col items-center gap-1.5 pt-2 sm:gap-2 sm:pt-2.5"> <div className="absolute inset-x-0 top-0 flex flex-col items-center gap-1.5 pt-2 sm:gap-2 sm:pt-2.5">
@@ -666,14 +670,14 @@ function KesfetLinki({
</div> </div>
<ProgressiveBlur <ProgressiveBlur
position="bottom" position="bottom"
backgroundColor="#ffffff" backgroundColor="var(--card)"
height="45%" height="45%"
blurAmount="2px" blurAmount="2px"
/> />
</div> </div>
</div> </div>
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-white to-transparent" /> <div className="pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-card to-transparent" />
</div> </div>
<span className="min-w-0 px-2.5 pb-3 pt-2 text-center sm:px-3.5 sm:pb-3.5 sm:pt-2.5 sm:text-left"> <span className="min-w-0 px-2.5 pb-3 pt-2 text-center sm:px-3.5 sm:pb-3.5 sm:pt-2.5 sm:text-left">
@@ -761,7 +765,7 @@ function RehberSonucKarti({
<Link <Link
href={`/rehber/${yazi.slug}`} href={`/rehber/${yazi.slug}`}
onClick={onSec} onClick={onSec}
className="group overflow-hidden rounded-xl border border-slate-200 bg-white p-1.5 transition-[border-color,background-color,transform] duration-150 hover:border-slate-300 hover:bg-slate-50 active:scale-[0.99]" className="group overflow-hidden rounded-xl border border-slate-200 bg-card p-1.5 transition-[border-color,background-color,transform] duration-150 hover:border-slate-300 hover:bg-slate-50 active:scale-[0.99]"
> >
<RehberKapak baslik={yazi.baslik} compact className="rounded-lg" /> <RehberKapak baslik={yazi.baslik} compact className="rounded-lg" />
<span className="block px-2 pb-1.5 pt-2.5"> <span className="block px-2 pb-1.5 pt-2.5">

View File

@@ -99,7 +99,7 @@ export function ProgramNetleriButonu({
type="button" type="button"
title="Son yerleşenin netleri" title="Son yerleşenin netleri"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white text-slate-500 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.92] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${className}`} className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-card text-slate-500 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.92] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${className}`}
> >
<ListChecks className="size-4" aria-hidden /> <ListChecks className="size-4" aria-hidden />
<span className="sr-only">{isim} — son yerleşenin netleri</span> <span className="sr-only">{isim} — son yerleşenin netleri</span>
@@ -107,7 +107,7 @@ export function ProgramNetleriButonu({
</DrawerTrigger> </DrawerTrigger>
{/* Çekmece kabı ve çarpı cta-sira-form.tsx'teki çekmeceyle birebir (§4.10, §4.3) */} {/* Çekmece kabı ve çarpı cta-sira-form.tsx'teki çekmeceyle birebir (§4.10, §4.3) */}
<DrawerContent <DrawerContent
className="max-h-[92dvh] bg-white sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl" className="max-h-[92dvh] bg-card sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<DrawerClose className="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]"> <DrawerClose className="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]">

View File

@@ -123,7 +123,7 @@ export function Sayfalama({
{sayfa > 1 {sayfa > 1
? gecis( ? gecis(
sayfa - 1, sayfa - 1,
"inline-flex h-11 items-center gap-1 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 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]", "inline-flex h-11 items-center gap-1 rounded-full border border-slate-200 bg-card px-4 text-sm font-semibold text-slate-700 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]",
<> <>
<ChevronLeft className="size-4" aria-hidden /> <ChevronLeft className="size-4" aria-hidden />
Önceki Önceki
@@ -145,7 +145,7 @@ export function Sayfalama({
n, n,
n === sayfa n === sayfa
? "inline-flex h-11 min-w-11 items-center justify-center rounded-full bg-primary px-2 text-sm font-semibold text-primary-foreground" ? "inline-flex h-11 min-w-11 items-center justify-center rounded-full bg-primary px-2 text-sm font-semibold text-primary-foreground"
: "hidden h-11 min-w-11 items-center justify-center rounded-full border border-slate-200 bg-white px-2 text-sm font-semibold text-slate-700 sm:inline-flex 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]", : "hidden h-11 min-w-11 items-center justify-center rounded-full border border-slate-200 bg-card px-2 text-sm font-semibold text-slate-700 sm:inline-flex 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]",
n, n,
{ aktif: n === sayfa }, { aktif: n === sayfa },
) )
@@ -154,7 +154,7 @@ export function Sayfalama({
{sayfa < toplamSayfa {sayfa < toplamSayfa
? gecis( ? gecis(
sayfa + 1, sayfa + 1,
"inline-flex h-11 items-center gap-1 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 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]", "inline-flex h-11 items-center gap-1 rounded-full border border-slate-200 bg-card px-4 text-sm font-semibold text-slate-700 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]",
<> <>
Sonraki Sonraki
<ChevronRight className="size-4" aria-hidden /> <ChevronRight className="size-4" aria-hidden />

View File

@@ -12,7 +12,7 @@ const sayi = (n: number) => n.toLocaleString("tr-TR");
const CIP_TEMEL = const CIP_TEMEL =
"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]"; "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]";
const CIP_PASIF = const CIP_PASIF =
"border-slate-200 bg-white text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500"; "border-slate-200 bg-card text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500";
const CIP_AKTIF = "border-primary bg-primary text-white"; const CIP_AKTIF = "border-primary bg-primary text-white";
/** /**

View File

@@ -17,7 +17,7 @@ export function SehirYuzeyi({
harita: ReactNode; harita: ReactNode;
}) { }) {
return ( return (
<section className="relative isolate mt-6 overflow-hidden rounded-3xl border border-slate-200 bg-white"> <section className="relative isolate mt-6 overflow-hidden rounded-3xl border border-slate-200 bg-card">
{/* İki katlı mask: dış kat metnin tarafına doğru eritir (telefonda {/* İki katlı mask: dış kat metnin tarafına doğru eritir (telefonda
yukarı, lg'de sola), iç kat dik yöndeki iki kenarı eritir — hiçbir yukarı, lg'de sola), iç kat dik yöndeki iki kenarı eritir — hiçbir
kenarda yarım kesilmiş kare kalmaz. */} kenarda yarım kesilmiş kare kalmaz. */}

View File

@@ -139,13 +139,13 @@ export function TurIcerik({ tur }: { tur: TurSlug }) {
</h1> </h1>
{/* Kimlik hapları (§4.12): tür + öteki türe geçiş */} {/* Kimlik hapları (§4.12): tür + öteki türe geçiş */}
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start"> <p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start">
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800"> <span className="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">
<Ikon className="size-4 text-primary" aria-hidden /> <Ikon className="size-4 text-primary" aria-hidden />
{tur === "devlet" ? "Devlet" : "Vakıf"} {tur === "devlet" ? "Devlet" : "Vakıf"}
</span> </span>
<Link <Link
href={`/universiteler/${digerTur.slug}`} href={`/universiteler/${digerTur.slug}`}
className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800 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]" className="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 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]"
> >
<DigerIkon className="size-4 text-primary" aria-hidden /> <DigerIkon className="size-4 text-primary" aria-hidden />
{digerTur.ad} {digerTur.ad}
@@ -213,7 +213,7 @@ export function TurIcerik({ tur }: { tur: TurSlug }) {
<li key={s.il}> <li key={s.il}>
<a <a
href={`#sehir-${turkishSlugify(s.il)}`} href={`#sehir-${turkishSlugify(s.il)}`}
className="inline-flex h-10 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-white px-3.5 text-sm font-semibold text-slate-700 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]" className="inline-flex h-10 cursor-pointer items-center gap-1.5 rounded-full border border-slate-200 bg-card px-3.5 text-sm font-semibold text-slate-700 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]"
> >
{s.ad} {s.ad}
<span className="font-normal tabular-nums text-slate-400"> <span className="font-normal tabular-nums text-slate-400">

View File

@@ -62,7 +62,7 @@ export function TurkiyeSiralamasi() {
<PagePixelDivider seed={71} className="mt-8" /> <PagePixelDivider seed={71} className="mt-8" />
<ol className="mt-8 divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-white"> <ol className="mt-8 divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-card">
{satirlar.map((u) => { {satirlar.map((u) => {
const ad = u.ozet?.ad ?? trBaslikDuzeni(u.slug.replace(/-/g, " ")); const ad = u.ozet?.ad ?? trBaslikDuzeni(u.slug.replace(/-/g, " "));
const tur = u.ozet?.unitur ? UNITUR_ETIKET[u.ozet.unitur]?.cip : null; const tur = u.ozet?.unitur ? UNITUR_ETIKET[u.ozet.unitur]?.cip : null;

View File

@@ -28,7 +28,7 @@ export function UniSatirlari({
gizliIl?: string | null; gizliIl?: string | null;
}) { }) {
return ( return (
<ol className="mt-4 divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-white text-left"> <ol className="mt-4 divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-card text-left">
{uniler.map((u) => { {uniler.map((u) => {
const il = u.il && u.il !== gizliIl ? u.il : null; const il = u.il && u.il !== gizliIl ? u.il : null;
return ( return (

View File

@@ -59,7 +59,7 @@ export function UniversiteProgramTablosu({
<h2 className="mb-4 text-center font-heading text-xl font-bold text-slate-900 sm:text-2xl lg:text-left"> <h2 className="mb-4 text-center font-heading text-xl font-bold text-slate-900 sm:text-2xl lg:text-left">
{fakulte} {fakulte}
</h2> </h2>
<div className="overflow-hidden rounded-2xl border border-slate-200 bg-white"> <div className="overflow-hidden rounded-2xl border border-slate-200 bg-card">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow className="hover:bg-transparent"> <TableRow className="hover:bg-transparent">

View File

@@ -21,7 +21,7 @@ export function UrapLogo({ className = "h-8" }: { className?: string }) {
width={819} width={819}
height={261} height={261}
unoptimized unoptimized
className={`w-auto ${className}`} className={`kt-koyu-cevir w-auto ${className}`}
/> />
</a> </a>
); );

View File

@@ -41,7 +41,7 @@ export function DogrulaKarti({
return ( return (
<div className="relative"> <div className="relative">
<div className="relative rounded-2xl border border-slate-200 bg-white p-8 shadow-sm"> <div className="relative rounded-2xl border border-slate-200 bg-card p-8 shadow-sm">
<h1 className="font-heading text-xl font-bold">Girişini onayla</h1> <h1 className="font-heading text-xl font-bold">Girişini onayla</h1>
<p className="mt-2 text-sm text-slate-600"> <p className="mt-2 text-sm text-slate-600">
Bu bağlantı senin için üretildi ve{" "} Bu bağlantı senin için üretildi ve{" "}
@@ -93,7 +93,7 @@ export function DogrulaKarti({
export function DogrulaKartiSkeleton() { export function DogrulaKartiSkeleton() {
return ( return (
<div className="rounded-2xl border border-slate-200 bg-white p-8 shadow-sm"> <div className="rounded-2xl border border-slate-200 bg-card p-8 shadow-sm">
<Skeleton className="h-7 w-40" /> <Skeleton className="h-7 w-40" />
<Skeleton className="mt-3 h-4 w-full" /> <Skeleton className="mt-3 h-4 w-full" />
<Skeleton className="mt-1.5 h-4 w-2/3" /> <Skeleton className="mt-1.5 h-4 w-2/3" />

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { Mail, MailCheck } from "lucide-react"; import { ArrowRight, MailCheck } from "lucide-react";
import { toast } from "sonner"; import { toast } from "sonner";
import { authClient } from "@/lib/auth-client"; import { authClient } from "@/lib/auth-client";
import { olay } from "@/lib/analitik"; import { olay } from "@/lib/analitik";
@@ -181,8 +181,8 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
className="h-11 w-full cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600" className="h-11 w-full cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600"
disabled={busy !== null} disabled={busy !== null}
> >
<Mail className="size-4" aria-hidden />
{busy === "email" ? "Gönderiliyor…" : "Giriş bağlantısı gönder"} {busy === "email" ? "Gönderiliyor…" : "Giriş bağlantısı gönder"}
<ArrowRight className="size-4" aria-hidden />
</Button> </Button>
</form> </form>
</div> </div>

View File

@@ -33,7 +33,7 @@ export async function GirisKarti({
return ( return (
<> <>
<div className="relative"> <div className="relative">
<div className="relative rounded-2xl border border-slate-200 bg-white p-8 shadow-sm"> <div className="relative rounded-2xl border border-slate-200 bg-card p-8 shadow-sm">
{baglantiHatasi && ( {baglantiHatasi && (
<div <div
role="alert" role="alert"
@@ -98,7 +98,7 @@ export async function GirisKarti({
export function GirisKartiSkeleton() { export function GirisKartiSkeleton() {
return ( return (
<> <>
<div className="rounded-2xl border border-slate-200 bg-white p-8 shadow-sm"> <div className="rounded-2xl border border-slate-200 bg-card p-8 shadow-sm">
{/* Başlık + alt metin */} {/* Başlık + alt metin */}
<Skeleton className="h-8 w-40" /> <Skeleton className="h-8 w-40" />
<Skeleton className="mt-3 h-4 w-full" /> <Skeleton className="mt-3 h-4 w-full" />

View File

@@ -44,7 +44,7 @@ export function GirisLinki() {
return ( return (
<Button <Button
asChild asChild
className="h-9 cursor-pointer rounded-full bg-slate-900 px-3.5 text-sm font-medium text-white transition-colors duration-200 hover:bg-slate-700 sm:h-12 sm:px-7 sm:text-base" className="h-9 cursor-pointer rounded-full bg-slate-900 px-3.5 text-sm font-medium text-slate-50 transition-colors duration-200 hover:bg-slate-700 sm:h-12 sm:px-7 sm:text-base"
> >
<Link href={href}>Giriş yap</Link> <Link href={href}>Giriş yap</Link>
</Button> </Button>

View File

@@ -11,7 +11,7 @@ export function SignOutButton() {
<Button <Button
size="sm" size="sm"
variant="ghost" variant="ghost"
className="size-9 cursor-pointer rounded-full border border-slate-200 bg-white text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 hover:text-slate-900 sm:size-12" className="size-9 cursor-pointer rounded-full border border-slate-200 bg-card text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 hover:text-slate-900 sm:size-12"
aria-label="Çıkış yap" aria-label="Çıkış yap"
onClick={async () => { onClick={async () => {
await authClient.signOut(); await authClient.signOut();

View File

@@ -51,7 +51,7 @@ export async function UserNav() {
href="/listem" href="/listem"
aria-label="Yapay Zeka Listem" aria-label="Yapay Zeka Listem"
title="Yapay Zeka'nın kurduğu 24 tercihlik listen" title="Yapay Zeka'nın kurduğu 24 tercihlik listen"
className="inline-flex h-9 items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-white px-3 text-xs font-semibold text-slate-700 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 sm:h-12 sm:gap-2 sm:px-5 sm:text-sm" className="inline-flex h-9 items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-card px-3 text-xs font-semibold text-slate-700 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 sm:h-12 sm:gap-2 sm:px-5 sm:text-sm"
> >
<ClipboardList className="size-3.5 text-primary sm:size-4" aria-hidden /> <ClipboardList className="size-3.5 text-primary sm:size-4" aria-hidden />
{/* Etiket her genişlikte gizli; anlamı yukarıdaki aria-label + title {/* Etiket her genişlikte gizli; anlamı yukarıdaki aria-label + title
@@ -65,7 +65,7 @@ export async function UserNav() {
</Link> </Link>
<Link <Link
href="/paket?kaynak=nav" href="/paket?kaynak=nav"
className="inline-flex h-9 items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-white px-3 text-xs font-semibold text-slate-700 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 sm:h-12 sm:gap-2 sm:px-5 sm:text-sm" className="inline-flex h-9 items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-card px-3 text-xs font-semibold text-slate-700 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50 sm:h-12 sm:gap-2 sm:px-5 sm:text-sm"
title="Kredilerin — yüklemek için tıkla" title="Kredilerin — yüklemek için tıkla"
> >
<Coins className="size-3.5 text-amber-500 sm:size-4" aria-hidden /> <Coins className="size-3.5 text-amber-500 sm:size-4" aria-hidden />

View File

@@ -60,7 +60,7 @@ export function KaydetBanner() {
ref={gorunumRef} ref={gorunumRef}
// Telefonda metin kendi satırında, düğme altında tam genişlik: // Telefonda metin kendi satırında, düğme altında tam genişlik:
// yan yana dizince başlık kelime kelime kırılıyordu (375 px). // yan yana dizince başlık kelime kelime kırılıyordu (375 px).
className="pointer-events-auto relative mx-auto flex max-w-xl flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-white p-4 pr-14 shadow-xl sm:flex-nowrap sm:gap-4" className="pointer-events-auto relative mx-auto flex max-w-xl flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-card p-4 pr-14 shadow-xl sm:flex-nowrap sm:gap-4"
> >
{/* Kullanıcının o anki işletim sisteminin logosu: "bu tarayıcıda" {/* Kullanıcının o anki işletim sisteminin logosu: "bu tarayıcıda"
mesajını somutlaştırır */} mesajını somutlaştırır */}

View File

@@ -156,7 +156,7 @@ export function ListeCekmecesi() {
onAnimationEnd={(open) => setOturdu(open)} onAnimationEnd={(open) => setOturdu(open)}
> >
<DrawerContent <DrawerContent
className="min-h-0 max-h-[92dvh] bg-white sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl" className="min-h-0 max-h-[92dvh] bg-card sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl"
> >
{/* Alt sayfa başlığı (DESIGN.md §4.10): ortalı başlık + bağlam; {/* Alt sayfa başlığı (DESIGN.md §4.10): ortalı başlık + bağlam;
çarpı §4.3 kanonik sınıf setinde, temizle düğmesi aynı ölçüde çarpı §4.3 kanonik sınıf setinde, temizle düğmesi aynı ölçüde
@@ -437,7 +437,7 @@ function CekmeceSatiri({
dragElastic={{ left: 0, right: 0.7 }} dragElastic={{ left: 0, right: 0.7 }}
dragSnapToOrigin dragSnapToOrigin
onDragEnd={kaydirinca} onDragEnd={kaydirinca}
className="relative flex items-center gap-3 bg-white py-3" className="relative flex items-center gap-3 bg-card py-3"
> >
<button <button
type="button" type="button"

View File

@@ -24,7 +24,7 @@ export function ListeDurumuSatiri() {
if (liste.length === 0) { if (liste.length === 0) {
return ( return (
<p className="mx-auto mt-5 max-w-sm text-sm leading-relaxed text-slate-500 lg:mx-0 lg:max-w-none"> <p className="mx-auto mt-5 max-w-sm text-sm leading-relaxed text-slate-500 lg:mx-0 lg:max-w-none">
<span className="mr-1.5 inline-flex size-6 items-center justify-center rounded-full border border-slate-200 bg-white align-middle text-slate-500"> <span className="mr-1.5 inline-flex size-6 items-center justify-center rounded-full border border-slate-200 bg-card align-middle text-slate-500">
<Plus className="size-3.5" aria-hidden /> <Plus className="size-3.5" aria-hidden />
<span className="sr-only">Artı düğmesi</span> <span className="sr-only">Artı düğmesi</span>
</span> </span>
@@ -39,7 +39,7 @@ export function ListeDurumuSatiri() {
<button <button
type="button" type="button"
onClick={cekmeceAc} onClick={cekmeceAc}
className="group inline-flex h-11 cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800 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]" className="group inline-flex h-11 cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-card px-4 text-sm font-semibold text-slate-800 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]"
> >
Listende {liste.length}/{MANUEL_LISTE_MAX} program Listende {liste.length}/{MANUEL_LISTE_MAX} program
<span className="font-medium text-slate-500 group-hover:text-orange-500"> <span className="font-medium text-slate-500 group-hover:text-orange-500">

View File

@@ -32,7 +32,7 @@ export function ListemButonu() {
aria-expanded={acik} aria-expanded={acik}
aria-label={`Kendi listem — ${liste.length}/${MANUEL_LISTE_MAX} program`} aria-label={`Kendi listem — ${liste.length}/${MANUEL_LISTE_MAX} program`}
title="Tablodan seçtiğin programlar" title="Tablodan seçtiğin programlar"
className="relative inline-flex h-9 cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-white px-3 text-xs font-semibold text-slate-700 transition-[color,background-color,border-color,transform] duration-200 hover:border-slate-300 hover:bg-slate-50 active:scale-[0.97] sm:h-12 sm:gap-2 sm:px-5 sm:text-sm" className="relative inline-flex h-9 cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-full border border-slate-200 bg-card px-3 text-xs font-semibold text-slate-700 transition-[color,background-color,border-color,transform] duration-200 hover:border-slate-300 hover:bg-slate-50 active:scale-[0.97] sm:h-12 sm:gap-2 sm:px-5 sm:text-sm"
> >
<ListChecks className="size-3.5 text-primary sm:size-4" aria-hidden /> <ListChecks className="size-3.5 text-primary sm:size-4" aria-hidden />
{/* Etiket her genişlikte gizli: konteyner 1152 px'te sabit olduğu için {/* Etiket her genişlikte gizli: konteyner 1152 px'te sabit olduğu için

View File

@@ -134,7 +134,7 @@ export function ProgramEkleButonu({
className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border transition-[background-color,border-color,color,transform] duration-150 active:scale-[0.92] disabled:cursor-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${ className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border transition-[background-color,border-color,color,transform] duration-150 active:scale-[0.92] disabled:cursor-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${
listede listede
? "border-emerald-200 bg-emerald-50 text-emerald-600" ? "border-emerald-200 bg-emerald-50 text-emerald-600"
: "border-slate-200 bg-white text-slate-500 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 disabled:opacity-40" : "border-slate-200 bg-card text-slate-500 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 disabled:opacity-40"
} ${className}`} } ${className}`}
> >
{listede ? ( {listede ? (

View File

@@ -65,28 +65,24 @@ const DILIMLER: {
icon: typeof Rocket; icon: typeof Rocket;
renk: string; renk: string;
// Aktif hap koyu (slate-900) — ikon tonu okunurluk için bir kademe açılır // Aktif hap koyu (slate-900) — ikon tonu okunurluk için bir kademe açılır
renkAktif: string;
}[] = [ }[] = [
{ {
key: "hayal", key: "hayal",
etiket: DILIM_ETIKET.hayal, etiket: DILIM_ETIKET.hayal,
icon: Rocket, icon: Rocket,
renk: "text-red-500", renk: "text-red-500",
renkAktif: "text-red-400",
}, },
{ {
key: "dengeli", key: "dengeli",
etiket: DILIM_ETIKET.dengeli, etiket: DILIM_ETIKET.dengeli,
icon: Scale, icon: Scale,
renk: "text-amber-500", renk: "text-amber-500",
renkAktif: "text-amber-400",
}, },
{ {
key: "garanti", key: "garanti",
etiket: DILIM_ETIKET.garanti, etiket: DILIM_ETIKET.garanti,
icon: ShieldCheck, icon: ShieldCheck,
renk: "text-emerald-600", renk: "text-emerald-600",
renkAktif: "text-emerald-400",
}, },
]; ];
@@ -208,7 +204,7 @@ export function ProgramTablosu({
<TabsTrigger <TabsTrigger
key={d.key} key={d.key}
value={d.key} value={d.key}
className="relative min-h-11 cursor-pointer px-2 py-1.5 text-sm font-semibold transition-colors duration-200 hover:text-orange-500 data-active:hover:text-white group-data-[variant=pill]/tabs-list:h-auto sm:px-4" className="relative min-h-11 cursor-pointer px-2 py-1.5 text-sm font-semibold transition-colors duration-200 hover:text-orange-500 data-active:hover:text-slate-50 group-data-[variant=pill]/tabs-list:h-auto sm:px-4"
> >
{aktif ? ( {aktif ? (
<motion.span <motion.span
@@ -225,13 +221,13 @@ export function ProgramTablosu({
<span className="relative z-10 inline-flex flex-col items-center gap-0.5 sm:flex-row sm:gap-1.5"> <span className="relative z-10 inline-flex flex-col items-center gap-0.5 sm:flex-row sm:gap-1.5">
<span className="inline-flex items-center gap-1.5"> <span className="inline-flex items-center gap-1.5">
<d.icon <d.icon
className={`size-4 ${aktif ? d.renkAktif : d.renk}`} className={`size-4 ${aktif ? "text-slate-50" : d.renk}`}
aria-hidden aria-hidden
/> />
{d.etiket} {d.etiket}
</span> </span>
<span <span
className={`text-sm font-medium tabular-nums ${aktif ? "text-white/70" : "text-slate-400"}`} className={`text-sm font-medium tabular-nums ${aktif ? "text-slate-50/70" : "text-slate-400"}`}
> >
{sonuclar.toplam[d.key].toLocaleString("tr-TR")} {sonuclar.toplam[d.key].toLocaleString("tr-TR")}
</span> </span>
@@ -246,7 +242,7 @@ export function ProgramTablosu({
const toplam = sonuclar.toplam[d.key]; const toplam = sonuclar.toplam[d.key];
return ( return (
<TabsContent key={d.key} value={d.key}> <TabsContent key={d.key} value={d.key}>
<div className="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-white"> <div className="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-card">
{satirlar.length === 0 ? ( {satirlar.length === 0 ? (
<p className="px-5 py-8 text-center text-sm text-slate-500"> <p className="px-5 py-8 text-center text-sm text-slate-500">
Bu dilimde filtrene uyan program bulunamadı. Bu dilimde filtrene uyan program bulunamadı.

View File

@@ -62,7 +62,7 @@ export function SecimlerimPaneli() {
if (liste.length === 0) { if (liste.length === 0) {
return ( return (
<section className="rounded-2xl border border-slate-200 bg-white p-8 text-center"> <section className="rounded-2xl border border-slate-200 bg-card p-8 text-center">
<ListChecks className="mx-auto size-10 text-slate-300" aria-hidden /> <ListChecks className="mx-auto size-10 text-slate-300" aria-hidden />
<h2 className="mt-4 font-heading text-xl font-bold"> <h2 className="mt-4 font-heading text-xl font-bold">
Henüz program seçmedin Henüz program seçmedin
@@ -99,7 +99,7 @@ export function SecimlerimPaneli() {
return ( return (
<section className="flex flex-col gap-6"> <section className="flex flex-col gap-6">
<div className="rounded-2xl border border-slate-200 bg-white p-5"> <div className="rounded-2xl border border-slate-200 bg-card p-5">
<div className="flex flex-wrap items-start justify-between gap-4"> <div className="flex flex-wrap items-start justify-between gap-4">
<div> <div>
<h2 className="flex items-center gap-2 font-heading text-xl font-bold"> <h2 className="flex items-center gap-2 font-heading text-xl font-bold">
@@ -228,7 +228,7 @@ const SecimSatiri = memo(function SecimSatiri({
return ( return (
<li <li
className={`rounded-2xl border border-l-4 border-slate-200 bg-white p-4 ${ className={`rounded-2xl border border-l-4 border-slate-200 bg-card p-4 ${
stil?.kenar ?? "border-l-slate-300" stil?.kenar ?? "border-l-slate-300"
}`} }`}
> >

View File

@@ -320,12 +320,12 @@ export function TercihHaritasi({
} }
fill={ fill={
secili secili
? "oklch(0.97 0.014 254.6)" // blue-50: seçili zemin ? "var(--kt-harita-secili)" // seçili zemin
: iceriyor : iceriyor
? "oklch(0.882 0.059 254.1)" // blue-200 ? "var(--kt-harita-dolu)"
: "oklch(0.929 0.013 255.5)" // slate-200 : "var(--color-slate-200)"
} }
stroke="white" stroke="var(--card)"
strokeWidth={secili ? 1.6 * sf : 1 * sf} strokeWidth={secili ? 1.6 * sf : 1 * sf}
onClick={() => { onClick={() => {
if (secili) onSeciliIlDegisti(null); if (secili) onSeciliIlDegisti(null);
@@ -356,7 +356,7 @@ export function TercihHaritasi({
cy={cy} cy={cy}
r={11} r={11}
fill={renk} fill={renk}
stroke="white" stroke="var(--card)"
strokeWidth={2} strokeWidth={2}
/> />
<text <text
@@ -405,7 +405,7 @@ export function TercihHaritasi({
cx={p.x} cx={p.x}
cy={p.y} cy={p.y}
r={r} r={r}
fill="white" fill="var(--card)"
stroke={RISK_RENK[p.risk]} stroke={RISK_RENK[p.risk]}
strokeWidth={2.5 * sf} strokeWidth={2.5 * sf}
/> />
@@ -423,7 +423,7 @@ export function TercihHaritasi({
cy={p.y - r * 0.78} cy={p.y - r * 0.78}
r={7.5 * sf} r={7.5 * sf}
fill={RISK_RENK[p.risk]} fill={RISK_RENK[p.risk]}
stroke="white" stroke="var(--card)"
strokeWidth={1.5 * sf} strokeWidth={1.5 * sf}
/> />
<text <text
@@ -445,8 +445,8 @@ export function TercihHaritasi({
cx={p.x} cx={p.x}
cy={p.y} cy={p.y}
r={r} r={r}
fill={p.kilitli ? "oklch(0.704 0.04 256.8)" : RISK_RENK[p.risk]} fill={p.kilitli ? "var(--color-slate-400)" : RISK_RENK[p.risk]}
stroke="white" stroke="var(--card)"
strokeWidth={2 * sf} strokeWidth={2 * sf}
strokeDasharray={p.kilitli ? `${4 * sf} ${3 * sf}` : undefined} strokeDasharray={p.kilitli ? `${4 * sf} ${3 * sf}` : undefined}
/> />
@@ -471,8 +471,8 @@ export function TercihHaritasi({
textAnchor="middle" textAnchor="middle"
fontSize={16 * sf} fontSize={16 * sf}
fontWeight={600} fontWeight={600}
fill="oklch(0.279 0.041 260.0)" // slate-800 fill="var(--color-slate-800)"
stroke="white" stroke="var(--card)"
strokeWidth={4 * sf} strokeWidth={4 * sf}
paintOrder="stroke" paintOrder="stroke"
className="pointer-events-none select-none" className="pointer-events-none select-none"
@@ -491,7 +491,7 @@ export function TercihHaritasi({
size="sm" size="sm"
variant="outline" variant="outline"
onClick={() => onSeciliIlDegisti(null)} onClick={() => onSeciliIlDegisti(null)}
className="absolute left-3 top-3 cursor-pointer rounded-full bg-white/90 backdrop-blur" className="absolute left-3 top-3 cursor-pointer rounded-full bg-card/90 backdrop-blur"
> >
<ArrowLeft className="size-4" aria-hidden /> <ArrowLeft className="size-4" aria-hidden />
Türkiye Türkiye
@@ -513,7 +513,7 @@ export function TercihHaritasi({
<button <button
type="button" type="button"
onClick={onTercihSec ? () => onTercihSec(sira) : undefined} onClick={onTercihSec ? () => onTercihSec(sira) : undefined}
className="flex min-h-11 cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-white py-1.5 pl-1.5 pr-3.5 text-sm transition-[background-color,border-color,transform] duration-150 hover:border-orange-500 hover:bg-orange-50/60 active:scale-[0.97]" className="flex min-h-11 cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-card py-1.5 pl-1.5 pr-3.5 text-sm transition-[background-color,border-color,transform] duration-150 hover:border-orange-500 hover:bg-orange-50/60 active:scale-[0.97]"
> >
<span <span
className="flex size-7 shrink-0 items-center justify-center rounded-full font-heading text-xs font-bold text-white" className="flex size-7 shrink-0 items-center justify-center rounded-full font-heading text-xs font-bold text-white"

View File

@@ -68,8 +68,8 @@ export function YurtdisiHaritalar({
<path <path
key={`b${i}`} key={`b${i}`}
d={d} d={d}
fill="oklch(0.929 0.013 255.5)" // slate-200 fill="var(--color-slate-200)"
stroke="white" stroke="var(--card)"
strokeWidth={2} strokeWidth={2}
/> />
))} ))}
@@ -77,8 +77,8 @@ export function YurtdisiHaritalar({
<path <path
key={`u${i}`} key={`u${i}`}
d={d} d={d}
fill="oklch(0.882 0.059 254.1)" // blue-200: tercih içeren zemin fill="var(--kt-harita-dolu)" // tercih içeren zemin
stroke="white" stroke="var(--card)"
strokeWidth={2} strokeWidth={2}
> >
<title>{harita.ad}</title> <title>{harita.ad}</title>
@@ -103,7 +103,7 @@ export function YurtdisiHaritalar({
cy={p.y} cy={p.y}
r={26} r={26}
fill={RISK_PIN_RENK[baskinRisk(p.riskler)]} fill={RISK_PIN_RENK[baskinRisk(p.riskler)]}
stroke="white" stroke="var(--card)"
strokeWidth={5} strokeWidth={5}
/> />
<text <text

View File

@@ -52,7 +52,7 @@ export async function OdemeSayfasi({ siparisId }: { siparisId?: string }) {
{/* iyzico gömülü kart formu */} {/* iyzico gömülü kart formu */}
<section <section
aria-label="Kart bilgileri" aria-label="Kart bilgileri"
className="mt-6 rounded-2xl border border-slate-200 bg-white p-5 shadow-sm" className="mt-6 rounded-2xl border border-slate-200 bg-card p-5 shadow-sm"
> >
<IyzicoFormu icerik={order.iyzicoFormContent} /> <IyzicoFormu icerik={order.iyzicoFormContent} />
</section> </section>
@@ -92,7 +92,7 @@ export async function OdemeSayfasi({ siparisId }: { siparisId?: string }) {
alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme" alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme"
width={429} width={429}
height={32} height={32}
className="mx-auto mt-5 h-6 w-auto" className="kt-acik-logo mx-auto mt-5 h-6 w-auto"
/> />
</div> </div>
); );

View File

@@ -37,7 +37,7 @@ export async function OdemeSonucKarti({ siparis }: { siparis?: string }) {
: false; : false;
if (iade) { if (iade) {
return ( return (
<div className="rounded-2xl border border-amber-200 bg-white p-8 shadow-sm"> <div className="rounded-2xl border border-amber-200 bg-card p-8 shadow-sm">
<RotateCcw className="mx-auto size-12 text-amber-500" aria-hidden /> <RotateCcw className="mx-auto size-12 text-amber-500" aria-hidden />
<h1 className="mt-4 font-heading text-2xl font-bold"> <h1 className="mt-4 font-heading text-2xl font-bold">
Bu ödeme iade edilecek Bu ödeme iade edilecek
@@ -77,7 +77,7 @@ export async function OdemeSonucKarti({ siparis }: { siparis?: string }) {
const listeHref = rapor ? "/listem?acildi=1" : null; const listeHref = rapor ? "/listem?acildi=1" : null;
return basarili ? ( return basarili ? (
<div className="rounded-2xl border border-emerald-200 bg-white p-8 shadow-sm"> <div className="rounded-2xl border border-emerald-200 bg-card p-8 shadow-sm">
<CheckCircle2 <CheckCircle2
className="mx-auto size-12 text-emerald-500" className="mx-auto size-12 text-emerald-500"
aria-hidden aria-hidden
@@ -117,7 +117,7 @@ export async function OdemeSonucKarti({ siparis }: { siparis?: string }) {
</div> </div>
</div> </div>
) : ( ) : (
<div className="rounded-2xl border border-red-200 bg-white p-8 shadow-sm"> <div className="rounded-2xl border border-red-200 bg-card p-8 shadow-sm">
<XCircle className="mx-auto size-12 text-red-500" aria-hidden /> <XCircle className="mx-auto size-12 text-red-500" aria-hidden />
<h1 className="mt-4 font-heading text-2xl font-bold"> <h1 className="mt-4 font-heading text-2xl font-bold">
Ödeme tamamlanamadı Ödeme tamamlanamadı
@@ -149,7 +149,7 @@ export function OdemeSonucKartiSkeleton() {
return ( return (
<div <div
aria-live="polite" aria-live="polite"
className="rounded-2xl border border-slate-200 bg-white p-8 shadow-sm" className="rounded-2xl border border-slate-200 bg-card p-8 shadow-sm"
> >
<Skeleton className="mx-auto size-12 rounded-full" /> <Skeleton className="mx-auto size-12 rounded-full" />
<Skeleton className="mx-auto mt-5 h-7 w-2/3" /> <Skeleton className="mx-auto mt-5 h-7 w-2/3" />

View File

@@ -55,10 +55,10 @@ export function PaketSatinAl() {
return ( return (
<Parallax <Parallax
strength={6} strength={6}
className="mt-10 grid gap-6 sm:grid-cols-[1fr_auto]" className="mt-10 grid grid-cols-[minmax(0,1fr)] gap-6 sm:grid-cols-[minmax(0,1fr)_auto]"
> >
{/* Ana paket */} {/* Ana paket */}
<section className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm"> <section className="rounded-2xl border-2 border-orange-500 bg-card p-8 shadow-sm">
<div className="flex items-baseline justify-between"> <div className="flex items-baseline justify-between">
<h2 className="font-heading text-xl font-bold"> <h2 className="font-heading text-xl font-bold">
Tercih Dönemi Paketi Tercih Dönemi Paketi
@@ -88,7 +88,7 @@ export function PaketSatinAl() {
alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme" alt="iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme"
width={429} width={429}
height={32} height={32}
className="mx-auto mt-5 h-5 w-auto" className="kt-acik-logo mx-auto mt-5 h-5 w-auto"
/> />
<p className="mt-3 text-center text-xs text-slate-500"> <p className="mt-3 text-center text-xs text-slate-500">
iyzico güvenli ödeme · Kart bilgilerin bize hiç ulaşmaz ·{" "} iyzico güvenli ödeme · Kart bilgilerin bize hiç ulaşmaz ·{" "}
@@ -102,7 +102,7 @@ export function PaketSatinAl() {
</section> </section>
{/* Top-up */} {/* Top-up */}
<section className="flex h-fit flex-col rounded-2xl border border-slate-200 bg-white p-6 shadow-sm sm:w-56"> <section className="flex h-fit flex-col rounded-2xl border border-slate-200 bg-card p-6 shadow-sm sm:w-56">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Coins className="size-4 text-amber-500" aria-hidden /> <Coins className="size-4 text-amber-500" aria-hidden />
<h2 className="font-heading font-bold">Kredi bitti mi?</h2> <h2 className="font-heading font-bold">Kredi bitti mi?</h2>
@@ -130,7 +130,7 @@ async function PaketCta() {
<div className="space-y-2"> <div className="space-y-2">
<Button <Button
asChild asChild
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600" className="h-auto min-h-12 w-full cursor-pointer bg-orange-500 px-6 py-2 text-center whitespace-normal text-white transition-colors duration-200 hover:bg-orange-600 sm:px-8"
> >
<Link href={`/giris?callback=${encodeURIComponent("/paket")}`}> <Link href={`/giris?callback=${encodeURIComponent("/paket")}`}>
Giriş yap — ilk {ACIK_SATIR} tercihini ücretsiz gör Giriş yap — ilk {ACIK_SATIR} tercihini ücretsiz gör

View File

@@ -264,7 +264,7 @@ export function ListeUretici({
// Paketli kullanıcıya paket satma: onun ürünü top-up. Liste ve sohbet // Paketli kullanıcıya paket satma: onun ürünü top-up. Liste ve sohbet
// geçmişi kalıcı; kredi yükleyince kaldığı yerden devam eder. // geçmişi kalıcı; kredi yükleyince kaldığı yerden devam eder.
return ( return (
<section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-white p-8 text-center sm:p-12"> <section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-card p-8 text-center sm:p-12">
<Lock className="mx-auto size-8 text-slate-400" aria-hidden /> <Lock className="mx-auto size-8 text-slate-400" aria-hidden />
<h1 className="mt-4 font-heading text-xl font-bold"> <h1 className="mt-4 font-heading text-xl font-bold">
Kredin bu liste için yetmiyor Kredin bu liste için yetmiyor
@@ -294,7 +294,7 @@ export function ListeUretici({
if (durum.ad === "hata") { if (durum.ad === "hata") {
return ( return (
<section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-white p-8 text-center sm:p-12"> <section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-card p-8 text-center sm:p-12">
<h1 className="font-heading text-xl font-bold">Liste kurulamadı</h1> <h1 className="font-heading text-xl font-bold">Liste kurulamadı</h1>
<p className="mx-auto mt-2 max-w-md text-sm text-slate-600"> <p className="mx-auto mt-2 max-w-md text-sm text-slate-600">
{durum.mesaj} {durum.mesaj}
@@ -344,7 +344,7 @@ function SunucuYokEkrani() {
} }
return ( return (
<section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-white p-8 text-center sm:p-12"> <section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-card p-8 text-center sm:p-12">
<h1 className="font-heading text-xl font-bold"> <h1 className="font-heading text-xl font-bold">
Listen hazır, sunucuya şu an ulaşamıyoruz Listen hazır, sunucuya şu an ulaşamıyoruz
</h1> </h1>
@@ -375,7 +375,7 @@ function SunucuYokEkrani() {
* "Tekrar dene" yok: tekrar taze requestId üretip ikinci üretimi başlatırdı. */ * "Tekrar dene" yok: tekrar taze requestId üretip ikinci üretimi başlatırdı. */
function SuruyorEkrani() { function SuruyorEkrani() {
return ( return (
<section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-white p-8 text-center sm:p-12"> <section className="mx-auto w-full max-w-2xl rounded-2xl border border-slate-200 bg-card p-8 text-center sm:p-12">
<h1 className="font-heading text-xl font-bold">Listen zaten hazırlanıyor</h1> <h1 className="font-heading text-xl font-bold">Listen zaten hazırlanıyor</h1>
<p className="mx-auto mt-2 max-w-md text-sm text-slate-600"> <p className="mx-auto mt-2 max-w-md text-sm text-slate-600">
Bunu başka bir sekmede başlatmışsın. İki kez kurmayalım — kredin bu Bunu başka bir sekmede başlatmışsın. İki kez kurmayalım — kredin bu
@@ -436,7 +436,7 @@ function UretimGovdesi({ uzunSurdu }: { uzunSurdu: boolean }) {
danışman sağda — üretim biter bitmez ekran aynı yerlere oturur. */} danışman sağda — üretim biter bitmez ekran aynı yerlere oturur. */}
<div className="mt-8 grid grid-cols-[minmax(0,1fr)] items-start gap-6 lg:grid-cols-[minmax(0,1fr)_380px] xl:grid-cols-[minmax(0,1fr)_440px]"> <div className="mt-8 grid grid-cols-[minmax(0,1fr)] items-start gap-6 lg:grid-cols-[minmax(0,1fr)_380px] xl:grid-cols-[minmax(0,1fr)_440px]">
{/* Gelmekte olan tercih listesinin iskeleti */} {/* Gelmekte olan tercih listesinin iskeleti */}
<div className="flex min-w-0 flex-col gap-2 rounded-2xl border border-slate-200 bg-white p-6 sm:p-8"> <div className="flex min-w-0 flex-col gap-2 rounded-2xl border border-slate-200 bg-card p-6 sm:p-8">
<div className="flex items-center justify-between pb-2"> <div className="flex items-center justify-between pb-2">
<Skeleton className="h-6 w-44" /> <Skeleton className="h-6 w-44" />
<Skeleton className="h-6 w-24 rounded-full" /> <Skeleton className="h-6 w-24 rounded-full" />
@@ -453,7 +453,7 @@ function UretimGovdesi({ uzunSurdu }: { uzunSurdu: boolean }) {
gördüğü ilk şey danışmanın çalıştığı olsun. */} gördüğü ilk şey danışmanın çalıştığı olsun. */}
<aside <aside
aria-label="Danışman paneli — listen hazırlanıyor" aria-label="Danışman paneli — listen hazırlanıyor"
className="flex flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white max-lg:order-first lg:sticky lg:top-28" className="flex flex-col overflow-hidden rounded-2xl border border-slate-200 bg-card max-lg:order-first lg:sticky lg:top-28"
> >
{/* SohbetClient başlığıyla aynı ibare/stil: üretim bitince panel {/* SohbetClient başlığıyla aynı ibare/stil: üretim bitince panel
yerini sohbete bırakırken başlık değişmez. */} yerini sohbete bırakırken başlık değişmez. */}

View File

@@ -349,7 +349,7 @@ export function ListemGovde({
<section <section
ref={kilitKartRef} ref={kilitKartRef}
className="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm" className="overflow-hidden rounded-2xl border border-slate-200 bg-card shadow-sm"
> >
<div className="border-b border-slate-100 p-6"> <div className="border-b border-slate-100 p-6">
<h3 className="font-heading text-xl font-bold tracking-tight"> <h3 className="font-heading text-xl font-bold tracking-tight">

View File

@@ -104,13 +104,13 @@ export function RaporSatirDetayi({
) : null} ) : null}
</div> </div>
<dl className="grid gap-3 text-base leading-relaxed sm:grid-cols-2"> <dl className="grid gap-3 text-base leading-relaxed sm:grid-cols-2">
<div className="rounded-xl border border-slate-200 bg-white p-4"> <div className="rounded-xl border border-slate-200 bg-card p-4">
<dt className="text-sm font-semibold text-slate-900"> <dt className="text-sm font-semibold text-slate-900">
Neden listede? Neden listede?
</dt> </dt>
<dd className="mt-1 text-slate-600">{gerekce}</dd> <dd className="mt-1 text-slate-600">{gerekce}</dd>
</div> </div>
<div className="rounded-xl border border-slate-200 bg-white p-4"> <div className="rounded-xl border border-slate-200 bg-card p-4">
<dt className="text-sm font-semibold text-slate-900"> <dt className="text-sm font-semibold text-slate-900">
Risk ve Yapay Zeka yorumu Risk ve Yapay Zeka yorumu
</dt> </dt>
@@ -310,7 +310,7 @@ export function RaporListesi({
e.stopPropagation(); e.stopPropagation();
tiklandi(t.sira); tiklandi(t.sira);
}} }}
className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white text-slate-500 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.92] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`} className={`inline-flex ${SATIR_DUGME_BOYU} cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-card text-slate-500 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.92] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`}
> >
<ChevronDown <ChevronDown
className={`size-4 transition-transform duration-200 ${acikMi ? "rotate-180" : ""}`} className={`size-4 transition-transform duration-200 ${acikMi ? "rotate-180" : ""}`}
@@ -337,7 +337,7 @@ export function RaporListesi({
Kişisel analiz pakette Kişisel analiz pakette
</span> </span>
</div> </div>
<div className="rounded-xl border border-dashed border-slate-300 bg-white p-4"> <div className="rounded-xl border border-dashed border-slate-300 bg-card p-4">
<p className="flex items-center gap-1.5 text-sm font-semibold text-slate-900"> <p className="flex items-center gap-1.5 text-sm font-semibold text-slate-900">
<Lock className="size-4" aria-hidden /> <Lock className="size-4" aria-hidden />
Yapay Zeka karar desteği Yapay Zeka karar desteği
@@ -400,7 +400,7 @@ export function RaporListesi({
</p> </p>
) : null} ) : null}
<div className="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-white"> <div className="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-card">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow className="hover:bg-transparent"> <TableRow className="hover:bg-transparent">

View File

@@ -54,7 +54,7 @@ export async function RaporYazdir() {
}); });
return ( return (
<div className="mx-auto max-w-3xl bg-white p-8 text-slate-900 print:p-[10mm]"> <div className="mx-auto max-w-3xl bg-card p-8 text-slate-900 print:p-[10mm]">
<YazdirButonu /> <YazdirButonu />
<header className="border-b-2 border-slate-900 pb-4"> <header className="border-b-2 border-slate-900 pb-4">
@@ -159,7 +159,7 @@ export async function RaporYazdir() {
// Rapor sorgusu beklenirken belge düzeninde iskelet. // Rapor sorgusu beklenirken belge düzeninde iskelet.
export function RaporYazdirSkeleton() { export function RaporYazdirSkeleton() {
return ( return (
<div aria-live="polite" className="mx-auto w-full max-w-3xl bg-white p-8"> <div aria-live="polite" className="mx-auto w-full max-w-3xl bg-card p-8">
<div className="border-b-2 border-slate-200 pb-4"> <div className="border-b-2 border-slate-200 pb-4">
<Skeleton className="h-8 w-64" /> <Skeleton className="h-8 w-64" />
<Skeleton className="mt-2 h-4 w-40" /> <Skeleton className="mt-2 h-4 w-40" />

View File

@@ -25,7 +25,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
return ( return (
<section <section
id="revizyon" id="revizyon"
className="scroll-mt-24 rounded-2xl border border-slate-200 bg-white p-5" className="scroll-mt-24 rounded-2xl border border-slate-200 bg-card p-5"
> >
<p className="text-sm text-slate-500"> <p className="text-sm text-slate-500">
Revizyon hakların doldu. Danışman sohbetinden listen hakkında soru Revizyon hakların doldu. Danışman sohbetinden listen hakkında soru
@@ -62,7 +62,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
return ( return (
<section <section
id="revizyon" id="revizyon"
className="scroll-mt-24 rounded-2xl border border-slate-200 bg-white p-5" className="scroll-mt-24 rounded-2xl border border-slate-200 bg-card p-5"
> >
<h2 className="font-heading text-base font-bold"> <h2 className="font-heading text-base font-bold">
Listede değişiklik mi istiyorsun? Listede değişiklik mi istiyorsun?
@@ -78,7 +78,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
maxLength={1000} maxLength={1000}
placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, güvenli dilimi genişlet…" placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, güvenli dilimi genişlet…"
disabled={pending} disabled={pending}
className="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50" className="w-full rounded-lg border border-slate-200 bg-card px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
/> />
<div className="mt-3 flex items-center gap-3"> <div className="mt-3 flex items-center gap-3">
<Button <Button

View File

@@ -151,7 +151,7 @@ export function TadimlikSatiri({
</p> </p>
</div> </div>
<div className="mt-6 rounded-2xl border border-slate-200 bg-white p-4 shadow-sm sm:p-6"> <div className="mt-6 rounded-2xl border border-slate-200 bg-card p-4 shadow-sm sm:p-6">
{/* Rapor listesinin satırıyla aynı düzen (§4.15): ad sarar, {/* Rapor listesinin satırıyla aynı düzen (§4.15): ad sarar,
üniversite adı altında, taban sıra sağda iri. */} üniversite adı altında, taban sıra sağda iri. */}
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">

View File

@@ -97,7 +97,7 @@ export function ElCizimiSema({
<div <div
role="img" role="img"
aria-label={ariaLabel} aria-label={ariaLabel}
className={`${elYazisi.className} overflow-x-auto [&_svg]:mx-auto [&_svg]:h-auto [&_svg]:max-w-full`} className={`${elYazisi.className} kt-sema-kagit overflow-x-auto [&_svg]:mx-auto [&_svg]:h-auto [&_svg]:max-w-full`}
dangerouslySetInnerHTML={{ __html: svg }} dangerouslySetInnerHTML={{ __html: svg }}
/> />
) : hata ? null : ( ) : hata ? null : (

View File

@@ -13,7 +13,7 @@ export function RehberListesi() {
<li key={y.slug} className="mb-5 break-inside-avoid"> <li key={y.slug} className="mb-5 break-inside-avoid">
<Link <Link
href={`/rehber/${y.slug}`} href={`/rehber/${y.slug}`}
className="block overflow-hidden rounded-3xl border border-slate-200 bg-white p-2 shadow-sm focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-primary" className="block overflow-hidden rounded-3xl border border-slate-200 bg-card p-2 shadow-sm focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-primary"
> >
<RehberKapak <RehberKapak
baslik={y.baslik} baslik={y.baslik}
@@ -39,7 +39,7 @@ export function RehberListesiSkeleton() {
<ul className="mt-8 columns-1 gap-5 sm:columns-2 lg:columns-3"> <ul className="mt-8 columns-1 gap-5 sm:columns-2 lg:columns-3">
{Array.from({ length: 3 }, (_, i) => ( {Array.from({ length: 3 }, (_, i) => (
<li key={i} className="mb-5 break-inside-avoid"> <li key={i} className="mb-5 break-inside-avoid">
<div className="rounded-3xl border border-slate-200 bg-white p-2 shadow-sm"> <div className="rounded-3xl border border-slate-200 bg-card p-2 shadow-sm">
<Skeleton className="aspect-[1200/630] w-full rounded-[1.15rem]" /> <Skeleton className="aspect-[1200/630] w-full rounded-[1.15rem]" />
<div className="px-3 pb-3 pt-4"> <div className="px-3 pb-3 pt-4">
<Skeleton className="h-5 w-full" /> <Skeleton className="h-5 w-full" />

View File

@@ -251,7 +251,7 @@ export function CtaSiraForm({
className={ className={
tur === t.deger tur === t.deger
? "cursor-pointer rounded-full border border-primary bg-primary px-3 py-1.5 text-xs font-medium text-white transition-colors duration-200" ? "cursor-pointer rounded-full border border-primary bg-primary px-3 py-1.5 text-xs font-medium text-white transition-colors duration-200"
: "cursor-pointer rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50" : "cursor-pointer rounded-full border border-slate-200 bg-card px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50"
} }
> >
{t.etiket} {t.etiket}
@@ -319,7 +319,7 @@ export function CtaSiraForm({
const cekmece = ( const cekmece = (
<Drawer open={acik} onOpenChange={acikDegisti} handleOnly> <Drawer open={acik} onOpenChange={acikDegisti} handleOnly>
<DrawerContent <DrawerContent
className="max-h-[92dvh] bg-white sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl" className="max-h-[92dvh] bg-card sm:mx-auto sm:max-w-2xl sm:border-x sm:border-slate-200 sm:shadow-2xl"
> >
<DrawerClose className="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]"> <DrawerClose className="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]">
<X className="size-4" aria-hidden /> <X className="size-4" aria-hidden />
@@ -386,7 +386,7 @@ export function CtaSiraForm({
aria-labelledby={baslikId} aria-labelledby={baslikId}
className={cn( className={cn(
"relative isolate overflow-hidden rounded-2xl border px-5 py-4 text-left transition-colors duration-200 sm:py-5", "relative isolate overflow-hidden rounded-2xl border px-5 py-4 text-left transition-colors duration-200 sm:py-5",
profil ? "border-transparent bg-primary text-white" : "border-slate-200 bg-white", profil ? "border-transparent bg-primary text-white" : "border-slate-200 bg-card",
)} )}
> >
{profil ? <PikselZemin seed={11} /> : null} {profil ? <PikselZemin seed={11} /> : null}

View File

@@ -155,7 +155,7 @@ export function HeroForm() {
className={ className={
tur === t.deger tur === t.deger
? "cursor-pointer rounded-full border border-primary bg-primary px-3 py-1.5 text-xs font-medium text-white transition-colors duration-200" ? "cursor-pointer rounded-full border border-primary bg-primary px-3 py-1.5 text-xs font-medium text-white transition-colors duration-200"
: "cursor-pointer rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50" : "cursor-pointer rounded-full border border-slate-200 bg-card px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300 hover:bg-slate-50"
} }
> >
{t.etiket} {t.etiket}

View File

@@ -73,9 +73,9 @@ export function IlSecimHaritasi({
? "oklch(0.705 0.213 47.6)" // orange-500 ? "oklch(0.705 0.213 47.6)" // orange-500
: adet : adet
? `oklch(0.623 0.188 259.8 / ${0.25 + 0.65 * yogunluk})` ? `oklch(0.623 0.188 259.8 / ${0.25 + 0.65 * yogunluk})`
: "oklch(0.929 0.013 255.5)" // slate-200 : "var(--color-slate-200)"
} }
stroke={seciliMi ? "oklch(0.553 0.195 38.4)" : "white"} stroke={seciliMi ? "oklch(0.553 0.195 38.4)" : "var(--card)"}
strokeWidth={seciliMi ? 2 : 1} strokeWidth={seciliMi ? 2 : 1}
onClick={adet ? () => onToggle(key) : undefined} onClick={adet ? () => onToggle(key) : undefined}
role={adet ? "button" : undefined} role={adet ? "button" : undefined}

View File

@@ -48,7 +48,7 @@ export function Cip({
className={ className={
secili secili
? `${temel} border-primary bg-primary text-white` ? `${temel} border-primary bg-primary text-white`
: `${temel} border-slate-200 bg-white text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500` : `${temel} border-slate-200 bg-card text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500`
} }
> >
{children} {children}
@@ -345,7 +345,7 @@ export function SihirbazAdimlar({
En fazla 5 il seçebilirsin. İstersen boş bırak, fark etmez. En fazla 5 il seçebilirsin. İstersen boş bırak, fark etmez.
</p> </p>
<div className="mt-4 flex h-11 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 transition-colors focus-within:border-slate-300"> <div className="mt-4 flex h-11 items-center gap-2 rounded-full border border-slate-200 bg-card px-4 transition-colors focus-within:border-slate-300">
<Search className="size-4 shrink-0 text-slate-400" aria-hidden /> <Search className="size-4 shrink-0 text-slate-400" aria-hidden />
<input <input
type="text" type="text"
@@ -354,7 +354,7 @@ export function SihirbazAdimlar({
placeholder="İl ara..." placeholder="İl ara..."
aria-label="İl ara" aria-label="İl ara"
autoComplete="off" autoComplete="off"
className="min-w-0 flex-1 bg-transparent text-base text-slate-950 outline-none placeholder:text-slate-400" className="min-w-0 flex-1 bg-transparent text-base text-slate-900 outline-none placeholder:text-slate-400"
/> />
{ilArama ? ( {ilArama ? (
<button <button
@@ -394,7 +394,7 @@ export function SihirbazAdimlar({
<button <button
type="button" type="button"
onClick={() => setTumIllerAcik(true)} onClick={() => setTumIllerAcik(true)}
className="inline-flex h-10 cursor-pointer items-center rounded-full border border-dashed border-slate-300 bg-white px-3.5 text-sm font-semibold text-slate-500 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]" className="inline-flex h-10 cursor-pointer items-center rounded-full border border-dashed border-slate-300 bg-card px-3.5 text-sm font-semibold text-slate-500 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]"
> >
+{gorunenTurkiyeIlleri.length - IL_ON_IZLEME} il daha +{gorunenTurkiyeIlleri.length - IL_ON_IZLEME} il daha
</button> </button>
@@ -406,7 +406,7 @@ export function SihirbazAdimlar({
<button <button
type="button" type="button"
onClick={() => setTumIllerAcik(false)} onClick={() => setTumIllerAcik(false)}
className="inline-flex h-10 cursor-pointer items-center rounded-full border border-dashed border-slate-300 bg-white px-3.5 text-sm font-semibold text-slate-500 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]" className="inline-flex h-10 cursor-pointer items-center rounded-full border border-dashed border-slate-300 bg-card px-3.5 text-sm font-semibold text-slate-500 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]"
> >
Daha az göster Daha az göster
</button> </button>