Colophon
Bu site nasıl yapıldı? Kullanılan teknolojiler, verilen kararlar, altyapı ve günlük ölçüm serisinin dürüst, eksiksiz dökümü.
Teknoloji Yığını
Framework
- Next.js16.3.6App Router, standalone SSR, Turbopack
- React19.2.3Server Components + use() hook
- TypeScript5.9.3Strict mode
Styling
- Tailwind CSS4.1.18@theme + @custom-variant dark, OKLCH
- CSS VariablesDesign tokens, runtime theme switch
- Apple HIG colorsCanonical iOS Blue (#007AFF / #0A84FF dark)
Animation
- Motion12.38.0LazyMotion + domAnimation strict
- Lenis Smooth ScrollGPU-accelerated scroll
- GPU-only propertiestransform + opacity, layout reflow yok
State
- Zustand5.0.11Hafif client state
- TanStack Query5.100.10Server state + cache
- nuqs2.8.8Type-safe URL search params
Data
- Prisma6.19.2Type-safe ORM
- PostgreSQL16Engagement + analytics
- ResendNewsletter delivery
Quality
- Vitest4.1.11Unit + integration
- Playwright + axe-core1.58.1WCAG 2.2 AA E2E
- Lighthouse CIPerf / a11y / SEO bütçe denetimi
Deploy
- Hetzner VPSStandalone Node SSR
- CloudflareCDN + Brotli + 0-RTT + HTTP/3
- Let's EncryptTLS 1.3 + HSTS preload
Observability
- PostgreSQL analytics1st party, yalnız onayla, kendi sunucumuzda
- SentryHata izleme, AB bölgesi
- Real User MonitoringCWV via web-vitals lib
Tipografi
Tasarım İlkeleri
Önce Performans
Standalone SSR, ISR, dynamic import, GPU-only animasyon
Amaçlı Hareket
Her animasyon kullanıcıyı yönlendirir, dekoratif değil
Varsayılan Erişilebilirlik
WCAG 2.2 AA, prefers-reduced-motion, 44×44px hedef
Doğal Karanlık Mod
Sistem tercihiyle senkron, custom-variant Tailwind v4
Altyapı
- Origin
- Hetzner VPS (EU)
- Runtime
- Node v22.23.3
- Process
- systemd (portfolio-ssr.service, User=portfolio)
- CDN
- Cloudflare
- Edge cache
- s-maxage=60
- TLS
- 1.3 + HSTS preload
- DB
- PostgreSQL 16
Seçtim / Reddettim
Şu anda bu sunucuda çalışan altı karar: her biri yerine geçtiği seçenek, burada neden gerektiği, neye mal olduğu ve doğrulayabileceğiniz dosya:satır ile birlikte. Hepsi iyi araçlar; bu kartlar sıralama değil, uygunluk anlatıyor.
SeçtimMotion v12
ReddettimGSAP
Sayfaların tamamı React ağacı; animasyon durumunun bileşen yaşam döngüsüyle aynı yerde durması gerekiyordu. `LazyMotion` + `domAnimation` ile özellik kümesi ilk yüklemeden ayrı iniyor, sürükleme gibi ağır özellikler yalnız ihtiyaç duyan bileşende kapsanıyor.
BedeliTimeline tabanlı, kareye kadar kontrollü sahne kurgusunda GSAP hâlâ daha güçlü; böyle bir sahne gerekirse bu karar yeniden açılır.
Dayanak
package.json:64SeçtimSF Pro (self-host, woff2)
ReddettimInter (Google Fonts)
Sitenin tamamı Apple ekosistemi işi anlatıyor; metnin okuyucunun iOS cihazındaki sistem yazısıyla aynı olması içeriğin bir parçası. Dosyalar kendi origin'imizden, `next/font/local` ile geliyor — üçüncü taraf font isteği, dolayısıyla üçüncü taraf bağlantı maliyeti yok.
BedeliApple Personal Use lisansı; ticari bir üründe aynı seçim yapılamaz ve latin-ext dahil iki değişken dosya taşınıyor.
Dayanak
src/app/(main)/layout.tsx:27SeçtimPrisma client → src/generated/prisma
ReddettimVarsayılan node_modules/@prisma/client yolu
Standalone SSR çıktısı yalnız izini sürebildiği dosyaları kopyalar. İstemci depo içinde, `src/` altında durduğunda `next build` onu normal bir modül gibi görüyor ve `.next/standalone` kopyasında eksik kalma sınıfı tamamen ortadan kalkıyor.
BedeliŞema her değiştiğinde `prisma generate` zorunlu ve üretilen dizin depo ağacında duruyor; prebuild zincirinin ilk adımı bu yüzden `prisma generate`.
Dayanak
prisma/schema.prisma:7Seçtimsystemd, User=portfolio (non-root)
Reddettimroot altında pm2
14 Tem 2026'da SSR süreci root'tan çıkarıldı. Unit dosyası `NoNewPrivileges`, `ProtectSystem`, `ProtectHome` ve `PrivateTmp` ile geliyor; `ProtectHome` sayesinde uygulama artık `/root` altındaki dağıtım kimlik bilgilerini okuyamıyor. Yukarıdaki satır bu bilgiyi sabit yazmıyor, her derlemede ünitenin kendisine soruyor.
BedeliDerleme hâlâ root koşuyor, bu yüzden her derlemeden sonra `.next` sahipliği geri verilmek zorunda; `ProtectSystem=strict` ve `MemoryDenyWriteExecute` V8 JIT nedeniyle bilinçli kapalı.
Dayanak
scripts/generate-colophon-stack.ts:63SeçtimTailwind v4 `@theme inline` köprüsü
Reddettimshadcn adlarını ham haliyle kullanmak
Projenin renk sözlüğü kendi semantik tokenları (`--color-bg-primary`, `--color-text-primary`). shadcn'in `bg-muted`/`text-foreground` gibi 19 adı bu tokenlara `@theme inline` ile bağlandı; `inline` şart, çünkü tema `.dark` / `.admin-v2` sınıflarıyla çalışma anında değişiyor.
BedeliYeni bir shadcn adı kullanmak köprüye bir satır eklemeyi ve o satır için açık/koyu kontrast kontrolünü zorunlu kılıyor.
Dayanak
src/app/globals.css:42Seçtimİçerik PostgreSQL'de (Prisma)
ReddettimTypeScript sabit dizileri
İçerik TS dosyalarında dururken her düzeltme bir derleme gerektiriyordu ve admin panelinin gördüğü kayıtla sayfanın bastığı metin ayrışabiliyordu. Artık tek kaynak veritabanı; prebuild adımı okunan kayıtları statik JSON'a dönüştürüyor, sayfa istek anında veritabanına gitmiyor.
Bedeliİçerik değişikliği yayına ancak bir derlemeyle çıkıyor ve yedekleme yükü depo yerine veritabanına geçti.
Dayanak
scripts/generate-content-json.ts:195
Ölçüm Serisi
Bu sunucudaki bir cron, her gece sayfa türü başına bir Lighthouse koşusu ve her sabah bir PageSpeed Insights mobil koşusu biriktiriyor. Aşağıdakiler o dosyaların kendisi: iyi günler de kötü günler de içinde.
Ana sayfa
/
Tablo olarak gör
| Kategori | Son | En düşük | En yüksek | Koşu |
|---|---|---|---|---|
| Performans | 89 | 53 | 93 | 86 |
| Erişilebilirlik | 100 | 100 | 100 | 86 |
| En İyi Uygulamalar | 100 | 100 | 100 | 85 |
| SEO | 100 | 100 | 100 | 86 |
Blog yazısı
/blog/swift-6-neler-yeni/
Tablo olarak gör
| Kategori | Son | En düşük | En yüksek | Koşu |
|---|---|---|---|---|
| Performans | 95 | 93 | 98 | 61 |
| Erişilebilirlik | 100 | 100 | 100 | 63 |
| En İyi Uygulamalar | 100 | 96 | 100 | 62 |
| SEO | 100 | 100 | 100 | 63 |
Karşılaştırma
/comparisons/swiftui-vs-uikit/
Tablo olarak gör
| Kategori | Son | En düşük | En yüksek | Koşu |
|---|---|---|---|---|
| Performans | 96 | 94 | 99 | 63 |
| Erişilebilirlik | 100 | 97 | 100 | 63 |
| En İyi Uygulamalar | 100 | 96 | 100 | 63 |
| SEO | 100 | 100 | 100 | 63 |
Proje
/projects/part-to-time/
Tablo olarak gör
| Kategori | Son | En düşük | En yüksek | Koşu |
|---|---|---|---|---|
| Performans | 98 | 59 | 99 | 62 |
| Erişilebilirlik | 100 | 96 | 100 | 62 |
| En İyi Uygulamalar | 100 | 100 | 100 | 62 |
| SEO | 100 | 100 | 100 | 62 |
Lighthouse CI · 2026-07-09 → 2026-10-06 · 90 günlük dosya
PageSpeed Insights — 28 gün p75 (mobil)
PSI mobil lab, 4× CPU kısıtlı emülasyon; saha CWV değil.
| URL | Skor | LCP | TBT | CLS | n |
|---|---|---|---|---|---|
| / | 84 | 4.44 s | 179 ms | 0.001 | 26 |
| /blog/apple-foundation-models-framework-on-device-llm/ | 83 | 4.43 s | 134 ms | 0.001 | 28 |
| /comparisons/swiftui-vs-uikit/ | 87 | 4.00 s | 257 ms | 0.001 | 24 |
| /quiz/ | 92 | 3.82 s | 160 ms | 0.071 | 27 |
2026-09-09 → 2026-10-06 · 28 günlük dosya
Lisans ve Kaynak
- •Tasarım ve içerik © 2026 Muhittin Çamdalı
- •İkonlar: Lucide (ISC) + SF Symbols (Apple sistem)
- •Fontlar: SF Pro + SF Mono (Apple Personal Use License, self-hosted woff2)
- •Detaylı teşekkür ve referans listesi için /credits/ sayfasına bakın
Altyapı danışmanlığı
Bu yığını ekibinize kurayım
Bu sayfadaki her şey — standalone SSR derlemesi, root olmayan systemd ünitesi, token tabanlı tema köprüsü, her gece biriken ölçüm arşivi — sizin sunucularınıza kurup belgeleyerek devrettiğim bir düzen. Ekibiniz bu yolun ortasında bir yerdeyse, nerede takıldığını yazın; ne yapardım onu anlatayım.
Bu site sevgiyle ve çok fazla ile yapılmıştır.