feat(tema): açık / koyu / sistem teması
All checks were successful
Deploy / deploy (push) Successful in 6m23s
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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
114
docs/ekip-raporlari/2026-10-04/koyu-tema-denetimi.md
Normal file
114
docs/ekip-raporlari/2026-10-04/koyu-tema-denetimi.md
Normal 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ı.
|
||||||
@@ -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` |
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
43
src/components/tema-saglayici.tsx
Normal file
43
src/components/tema-saglayici.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
61
src/components/tema-secici.tsx
Normal file
61
src/components/tema-secici.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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}
|
||||||
|
|||||||
@@ -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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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: (
|
||||||
|
|||||||
@@ -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
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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]">
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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. */}
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|||||||
@@ -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 */}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 ? (
|
||||||
|
|||||||
@@ -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ı.
|
||||||
|
|||||||
@@ -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"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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. */}
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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 : (
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user