/* ==========================================================================
   PERA FESTIVAL — HAREKET KATMANI (Revizyon 7)

   Üç bölüm:
     1) Sayfa geçişleri      — giriş/çıkış, 200–450 ms
     2) Mikro etkileşimler   — buton · kart · sekme · onay · anahtar · modal…
     3) Medya                — galeri · lightbox · zaman çizelgesi

   KURAL: Süreler tokens.css'teki --dur-* değişkenlerinden gelir.
   prefers-reduced-motion açıkken o değişkenler .01ms'ye iner ve burada
   tanımlı her şey pratikte anında gerçekleşir. Ek olarak, yalnızca
   dekoratif olan hareketler (stagger, ken burns, kayan hero) reduced-motion
   bloğunda AÇIKÇA kapatılır.
   ========================================================================== */

:root {
  /* FAZ 70.2 §1-§2 — KÖK NEDEN DÜZELTMESİ: FAZ70.1'de gerçek Playwright
     ölçümüyle (ilk boyamadan ~60ms sonra vs. ~2.5s sonra) doğrulandı — bu
     500ms'lik pencerede public sayfa başlığı ~13px dikey / ~2px yatay
     ölçülebilir şekilde kayıyor ("ilk görünen layout ≈ final layout" ilkesini
     ihlal ediyor). FAZ68 §7-§10'un 500ms'ye çektiği değer burada TEKRAR
     düşürülüyor — ama istenen 180ms DEĞİL, 350ms: 180ms (ve denenen
     220-300ms aralığındaki her değer) `qa-faz52-arsiv-arama-donma.js`'nin
     7a kontrolünü ÖLÇÜLEBİLİR ŞEKİLDE, TEKRARLANABİLİR biçimde flaky hâle
     getiriyor (5 tekrardan bazılarında ilk yüklemede 2 yerine 4 yıl grubu
     yükleniyor) — kök neden: `pages.js`'teki arşiv sentinel'i
     (rootMargin:'600px') zincirleme fetchPage() tetikliyor ve bu zincirin
     kaç adım ilerleyeceği, sayfa girişi animasyonunun bitip ana thread'in
     ne zaman "sakinleştiği"yle YARIŞ HÂLİNDE; 500ms güvenli/kararlı
     (5/5 + önceki turlarda hep ✓), 180-300ms bandı KARARSIZ (aynı süre bazen
     geçiyor bazen 4 grup yüklüyor), 350ms/400ms ise 5+/4 tekrarda hep ✓.
     FAZ52'nin 37/37 KORUNMASI kullanıcının açık, tekrarlanan ve öncelikli
     şartı olduğundan, literal "180ms" yerine ÖLÇÜLEREK doğrulanmış en hızlı
     GÜVENLİ değer (350ms) seçildi — bu FAZ52'nin KENDİ mekanizmasına
     (inFlight/ensureAllLoadedChain/debounce/IntersectionObserver) hiç
     dokunulmadan, yalnızca bu dosyadaki süreyi ayarlayarak sağlandı.
     Mekanizmanın KENDİSİ yine DEĞİŞMEDİ, yalnızca süre/mesafe/scale
     değerleri. Admin'in kendi süresi (aşağıda body.admin .a-main > .a-body:
     260ms) ve home/apply'ın kendi süresi (420ms) bu kökten AYRI, kendi
     seçicilerinde AÇIKÇA override edildiği için bu değişiklikten
     ETKİLENMİYOR — kasıtlı, dokunulmadı. */
  --dur-page-in: 350ms;
  --dur-page-out: 180ms;
  --ease-page: cubic-bezier(.22, .61, .36, 1);
  /* FAZ 70.2 — page-entry'nin başlangıç ölçeği artık bir DEĞİŞKEN: public
     sayfalar için varsayılan 1 (yani ölçek animasyonu YOK — yalnızca
     opacity + hafif translateY, tam olarak istenen). Admin panelinin ÖNCEKİ
     (bu fazdan ETKİLENMEMESİ gereken) .995 zoom-in hissi aşağıda kendi
     seçicisinde AÇIKÇA yeniden tanımlanarak KORUNUYOR — paylaşılan
     @keyframes tek kaynak kalmaya devam ediyor, admin için ayrı bir kopya
     keyframe YOK. */
  --page-in-scale: 1;
}

/* ==========================================================================
   1 · SAYFA GEÇİŞLERİ
   Giriş: opacity 0→1 + translateY(--page-in-y)→0 + scale(.995)→1
   Çıkış: kısa ve fark edilmez; tıklama ile yeni sayfa arasındaki boşluğu doldurur.

   FAZ 55 §2 — GLOBAL SAYFA GİRİŞ ANİMASYONU. Bu mekanizma (Rev-7'den beri)
   zaten TÜM public sayfalarda (44/44 — tr/ + en/) merkezi olarak devrede;
   her sayfada AYRI bir kopya JS/CSS YOK, tek kaynak burası. Talep edilen
   "20-30px translateY" değeri `--page-in-y` DEĞİŞKENİ üzerinden yalnızca
   PUBLIC sayfalara (`body > main`) uygulanır; admin panelinin (`body.admin
   .a-main > .a-body`) kendi giriş animasyonu bu değişkeni HİÇ TANIMLAMADIĞI
   için keyframe'in orijinal/değişmemiş varsayılanında (10px) kalır — yani
   admin panelinin hareket davranışı bu değişiklikle ETKİLENMEZ (§ "Admin
   panelini etkilememeli"). Header/navigation zaten `<main>`'in DIŞINDA bir
   kardeş öğe olduğundan (bkz. tr/*.html — <header>...</header><main>...) bu
   animasyon hiçbir zaman header'ı da aşağıdan getirmez — ek bir seçici
   gerekmedi. prefers-reduced-motion: hem burada (aşağıdaki media query,
   animation:none) hem de tokens.css'teki genel kuralla (animation-duration
   .01ms !important) ÇİFT KAT kapatılır. */
@keyframes pera-page-in {
  from { opacity: 0; transform: translate3d(0, var(--page-in-y, 10px), 0) scale(var(--page-in-scale, 1)); }
  to   { opacity: 1; transform: none; }
}
@keyframes pera-page-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translate3d(0, -6px, 0) scale(.997); }
}

/* Giriş animasyonu yalnızca JS "hazır" dediğinde başlar; böylece
   betik çalışmayan bir tarayıcıda sayfa görünmez kalmaz. */
html.pera-motion body > main,
html.pera-motion body.admin .a-main > .a-body {
  animation: pera-page-in var(--dur-page-in) var(--ease-page) both;
}
html.pera-motion.is-leaving body > main,
html.pera-motion.is-leaving body.admin .a-main > .a-body {
  animation: pera-page-out var(--dur-page-out) var(--ease-page) both;
}

/* FAZ 70.2 §2 — KÖK NEDEN DÜZELTMESİ: 20px → 6px. Ölçülen ~13px dikey kaymanın
   doğrudan kaynağı buydu; "çok hafif hareket, sayfa yer değiştirdi hissi
   olmamalı" hedefiyle 6px'e çekildi. Aralık artık ~16-24px DEĞİL, kasıtlı
   olarak çok daha küçük. Admin BUNU hâlâ miras almaz (aşağıdaki not). */
html.pera-motion body > main { --page-in-y: 6px; }

/* Bağlama göre küçük varyasyonlar — aynı hareketin her yerde birebir
   tekrarı mekanik durur. FAZ68 — apply/applyForm'un özel olarak DAHA HIZLI
   (form akışında sürtünmeyi azaltmak için) tutulma niyeti KORUNDU, ama
   istenen 400-700ms tabanının altına düşmeyecek şekilde 240ms→420ms'ye
   çekildi; home zaten 420ms ile aralık içindeydi, değişmedi. FAZ70.2
   KAPSAMI DIŞINDA BIRAKILDI (kullanıcının verdiği 3 değer — 180ms/6px/
   scale(1) — yalnızca genel public varsayılanı hedefliyordu; home/apply'ın
   kendi 420ms'si ve admin'in kendi 260ms'si burada AÇIKÇA override edildiği
   için kök değişiklikten zaten etkilenmiyordu, bu faz onlara ayrıca
   dokunmadı — gereksiz kapsam genişletmesi olmasın diye). */
html.pera-motion body.admin .a-main > .a-body { --dur-page-in: 260ms; }
html.pera-motion body[data-page="home"] > main { --dur-page-in: 420ms; }
html.pera-motion body[data-page="apply"] > main,
html.pera-motion body[data-page="applyForm"] > main { --dur-page-in: 420ms; }

/* FAZ 70.2 — admin panelinin ÖNCEKİ .995 "zoom-in" hissi, paylaşılan
   keyframe'in varsayılanı 1'e (ölçeksiz) çekildikten SONRA da birebir
   KORUNUYOR — yalnızca admin'in kendi seçicisinde eski değer yeniden
   tanımlanıyor. Admin görsel olarak bu fazdan HİÇ etkilenmiyor. */
html.pera-motion body.admin .a-main > .a-body { --page-in-scale: .995; }

/* Panel/adım geçişleri (sihirbaz, sekme içerikleri) */
@keyframes pera-step-in {
  from { opacity: 0; transform: translate3d(8px, 0, 0); }
  to   { opacity: 1; transform: none; }
}
.step-in { animation: pera-step-in var(--dur-medium) var(--ease-out) both; }

/* ==========================================================================
   2 · MİKRO ETKİLEŞİMLER
   ========================================================================== */

/* Buton — hover yükselir, basınca oturur, odak halkası her zaman görünür */
.btn {
  transition:
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}
.btn:not(:disabled):hover { transform: translateY(-1px); }
.btn:not(:disabled):active { transform: translateY(0) scale(.985); transition-duration: var(--dur-instant); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Kart — yükselme + görsel yakınlaşma */
.card, .ev-card, .venue-card, .w-card, .podium-card {
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.card:hover, .ev-card:hover, .venue-card:hover { transform: translateY(-2px); }

/* Sekme — alt çizgi kayarak geçer */
.tabs button { transition: color var(--dur-base) var(--ease-out); }
.tabs button::after { transition: transform var(--dur-medium) var(--ease-out), opacity var(--dur-base); }

/* Onay kutusu — işaret çizilerek gelir */
@keyframes pera-check {
  from { transform: scale(.6); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}
input[type="checkbox"], input[type="radio"] {
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
input[type="checkbox"]:checked { animation: pera-check var(--dur-base) var(--ease-spring); }
.consent { transition: background-color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out); }

/* Anahtar — topuz kayar */
.switch span { transition: background-color var(--dur-base) var(--ease-out); }
.switch span::after { transition: transform var(--dur-base) var(--ease-spring); }

/* Modal — arka plan solar, kart yükselir */
@keyframes pera-overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pera-modal-in {
  from { opacity: 0; transform: translate3d(0, 12px, 0) scale(.97); }
  to   { opacity: 1; transform: none; }
}
.modal-overlay { animation: pera-overlay-in var(--dur-base) var(--ease-out) both; }
.modal-overlay .modal { animation: pera-modal-in var(--dur-medium) var(--ease-out) both; }

/* Çekmece — kenardan kayar */
@keyframes pera-drawer-in {
  from { opacity: 0; transform: translate3d(24px, 0, 0); }
  to   { opacity: 1; transform: none; }
}
.drawer, .nf-center { transition: transform var(--dur-medium) var(--ease-out), opacity var(--dur-base) var(--ease-out); }
body.notif-open .nf-center { animation: pera-drawer-in var(--dur-medium) var(--ease-out) both; }

/* Toast — aşağıdan kayarak gelir */
@keyframes pera-toast-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.toast { animation: pera-toast-in var(--dur-medium) var(--ease-spring) both; }
.toast.is-out { opacity: 0; transform: translate3d(0, 8px, 0); transition: opacity var(--dur-base), transform var(--dur-base); }

/* İlerleme çubuğu ve adım göstergesi */
.wz-progress > i, .progress > i, #wzProgress { transition: width var(--dur-slow) var(--ease-out); }
#wzStepper button { transition: color var(--dur-base), background-color var(--dur-base); }
#wzStepper .num { transition: background-color var(--dur-base) var(--ease-out), color var(--dur-base), transform var(--dur-base) var(--ease-spring); }
#wzStepper .is-current .num { transform: scale(1.08); }

/* Satır vurgusu (grid, liste) */
.table tbody tr, .ct-row, .nf-item, .slot {
  transition: background-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

/* ==========================================================================
   3 · MEDYA
   ========================================================================== */

/* Galeri karesi: blur→net, hafif yakınlaşma */
.gitem img {
  transition: transform var(--dur-slow) var(--ease-out), filter var(--dur-slow) var(--ease-out),
              opacity var(--dur-slow) var(--ease-out);
}
.gitem img[data-loading] { opacity: 0; filter: blur(12px); transform: scale(1.04); }
.gitem img.is-loaded { opacity: 1; filter: none; }

/* Lightbox */
@keyframes pera-lb-in { from { opacity: 0; } to { opacity: 1; } }
.lightbox { animation: pera-lb-in var(--dur-base) var(--ease-out) both; }
.lightbox.is-closing { opacity: 0; transition: opacity var(--dur-base) var(--ease-out); }
.lightbox img {
  transition: opacity var(--dur-medium) var(--ease-out), transform var(--dur-medium) var(--ease-out);
}
.lightbox img.is-enter { opacity: 0; transform: scale(.96); }
.lightbox img.is-left  { opacity: 0; transform: translate3d(-24px, 0, 0); }
.lightbox img.is-right { opacity: 0; transform: translate3d(24px, 0, 0); }
.lightbox .lb-nav, .lightbox .lb-close {
  transition: background-color var(--dur-fast), transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast);
  border-radius: var(--radius-full);
}
.lightbox .lb-nav:hover, .lightbox .lb-close:hover { background: rgba(255,255,255,.14); transform: translateY(-50%) scale(1.08); }
.lightbox .lb-close:hover { transform: scale(1.08); }
.lightbox .lb-count { position: absolute; top: var(--space-5); left: var(--space-5); color: rgba(255,255,255,.72); font-size: var(--fs-caption); font-variant-numeric: tabular-nums; }

/* Görünüme girince beliren öğeler — IntersectionObserver ile sınıf eklenir */
.rise { opacity: 0; transform: translate3d(0, 14px, 0); }
.rise.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--rise-delay, 0ms);
}

/* Zaman çizelgesi */
.tl { position: relative; padding-left: 28px; }
.tl::before {
  content: ''; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 2px;
  background: linear-gradient(var(--border-c), var(--border-c-soft));
  transform-origin: top; transform: scaleY(var(--tl-progress, 1));
  transition: transform 900ms var(--ease-out);
}
.tl-item { position: relative; padding-bottom: var(--space-5); }
.tl-item::before {
  content: ''; position: absolute; left: -25px; top: 6px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--surface); border: 2px solid var(--accent);
  transition: transform var(--dur-medium) var(--ease-spring), background-color var(--dur-base);
}
.tl-item.is-in::before { background: var(--accent); }
.tl-year { font-size: var(--fs-h3); font-weight: 700; margin-bottom: var(--space-4); }
.tl-date { font-weight: 600; }
.tl-media { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }

/* ==========================================================================
   4 · AZALTILMIŞ HAREKET
   Süre token'ları zaten .01ms'ye iniyor. Burada yalnızca dekoratif
   dönüşümler tamamen kapatılır; hiçbir şey görünmez kalmaz.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.pera-motion body > main,
  html.pera-motion body.admin .a-main > .a-body,
  html.pera-motion.is-leaving body > main,
  html.pera-motion.is-leaving body.admin .a-main > .a-body { animation: none; opacity: 1; transform: none; }

  .rise, .rise.is-in { opacity: 1; transform: none; transition: none; }
  .gitem img, .gitem img[data-loading] { opacity: 1; filter: none; transform: none; }
  .gitem:hover img, .jury-card:hover .j-photo img { transform: none; }
  .btn:not(:disabled):hover, .btn:not(:disabled):active,
  .card:hover, .ev-card:hover, .venue-card:hover { transform: none; }
  .lightbox img.is-enter, .lightbox img.is-left, .lightbox img.is-right { opacity: 1; transform: none; }
  .tl::before { transform: none; transition: none; }
  input[type="checkbox"]:checked { animation: none; }
  .hero-video { display: none; }
}
