/* animations.css — RateTheWork micro-interaction & animation foundation

   KATMANSIZ (@layer YOK) — kasıtlı. Gerekçenin tamamı accessibility.css başlığındadır.
   Özeti: bu dosya app.css'ten SONRA yüklenip ezmek üzere tasarlandı; katmana alınırsa
   `@layer utilities` onu yener. Karşılığındaki sınır da aynı: buraya element seçici veya
   çıplak `*` kuralı EKLENMEZ — seçiciler bu dosyaya özgü sınıf adlarıyla sınırlıdır
   (.page-enter, .sidebar-drawer-*, .toast-*).
   Bekçi: RateTheWork.Tests/Unit/Blazor/Styles/UnlayeredStylesheetScopeTests.cs */

/* ============================================
   Custom Easing Variables
   ============================================ */
:root {
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-smooth: cubic-bezier(0.25, 0.4, 0.25, 1);
    /* Prototipin `--ease` easing'i. `--snap` (0.34,1.56,0.64,1) eklenmedi —
       --ease-spring ile birebir aynı değer, tek truth ilkesi gereği --ease-spring kullanılmalı. */
    --ease-glide: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ============================================
   Button Spring Bounce
   ============================================ */
.btn-spring {
    transition: transform 0.3s var(--ease-spring), filter 0.2s ease;
}

.btn-spring:active {
    transform: scale(0.95);
}

/* ============================================
   Like Pop Animation
   ============================================ */
@keyframes like-pop {
    0% { transform: scale(1); }
    30% { transform: scale(1.35); }
    60% { transform: scale(0.9); }
    100% { transform: scale(1); }
}

.like-active {
    animation: like-pop 0.4s var(--ease-spring);
}

/* ============================================
   Star Rating Ripple
   ============================================ */
@keyframes star-ripple {
    0% { box-shadow: 0 0 0 0 currentColor; opacity: 0.4; }
    100% { box-shadow: 0 0 0 10px transparent; opacity: 0; }
}

.star-click-ripple {
    animation: star-ripple 0.3s ease-out;
}

/* ============================================
   Shimmer Wave (Skeleton)
   ============================================ */
@keyframes shimmer-wave {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

.shimmer {
    background: linear-gradient(
        90deg,
        var(--surface-2) 25%,
        var(--surface-3) 50%,
        var(--surface-2) 75%
    );
    background-size: 200% 100%;
    animation: shimmer-wave 1.8s ease-in-out infinite;
}

/* ============================================
   Blockchain Hash Reveal
   ============================================ */
@keyframes char-glow {
    0% { color: var(--primary); text-shadow: 0 0 8px color-mix(in srgb, var(--primary) 60%, transparent); }
    100% { color: inherit; text-shadow: none; }
}

.char-glow-flash {
    animation: char-glow 0.4s ease-out forwards;
}

@keyframes badge-spring-in {
    0% { transform: scale(0); opacity: 0; }
    60% { transform: scale(1.1); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

.badge-spring-in {
    animation: badge-spring-in 0.5s var(--ease-spring) forwards;
}

/* XPBadge — canlı XP artışında pulse + lime glow (spec §11).
   .badge-spring-in'den SONRA tanımlı: aynı elemanda ikisi de varsa cascade'de bu kazanır. */
@keyframes xp-badge-pulse {
    0%   { transform: scale(1); box-shadow: 0 0 0 0 color-mix(in srgb, var(--ds-lime-400) 60%, transparent); }
    50%  { transform: scale(1.15); box-shadow: 0 0 14px 4px color-mix(in srgb, var(--ds-lime-400) 45%, transparent); }
    100% { transform: scale(1); box-shadow: 0 0 0 0 transparent; }
}
.xp-badge-pulse {
    animation: xp-badge-pulse 0.6s var(--ease-spring) forwards;
}

@keyframes pulse-glow-ring {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 30%, transparent); }
    50% { box-shadow: 0 0 0 8px transparent; }
}

.pulse-glow-ring {
    animation: pulse-glow-ring 2s ease-in-out infinite;
}

/* ============================================
   Page Transition
   ============================================ */
/* Bitiş karesi `translateY(0)` DEĞİL `none` olmak ZORUNDA.
   `.page-enter` MainLayout'ta @Body'yi saran kaptır; `animation-fill-mode: forwards`
   son karenin değerini kalıcı kılar. `translateY(0)` da bir dönüşümdür ve dönüşümü olan
   her öğe, içindeki `position: fixed` torunlar için görüntü penceresinin YERİNE
   içeren blok olur (CSS Transforms L1). Sonuç ölçüldü (2026-09-07, /homefeed):
   modal kökü 958px yerine 4382px yükseklik alıyor, panel görüntü penceresinin
   ~2000px altına, yani ekran dışına düşüyordu — kullanıcı düğmeye basıyor ve
   "popup açılmıyor" görüyordu. Sayfa içindeki HER diyalog, backdrop ve lightbox
   aynı sebeple kayıyordu.
   `none` ile hem kayma animasyonu korunur hem de bitişte içeren blok kalmaz. */
@keyframes page-enter {
    0% { opacity: 0; transform: translateY(8px); }
    100% { opacity: 1; transform: none; }
}

/* `forwards` YOK — bilerek. Doldurma kipi açıkken tarayıcı animasyonun ARA DEĞERİNİ
   kalıcı kılar; son kareye `transform: none` yazılsa bile tutulan değer bir matris olur
   (ölçüldü: `matrix(1, 0, 0, 1, 0, 0)`), yani dönüşüm teknik olarak var sayılmaya devam
   eder. Doldurma olmadan animasyon bitince öğe kendi taban stiline döner: `transform: none`,
   `opacity: 1` — istenen bitiş durumunun zaten aynısı. Kayma animasyonu korunur, kap
   `position: fixed` torunlar için içeren blok OLMAKTAN çıkar. Gerekçe keyframe notunda. */
.page-enter {
    animation: page-enter 0.3s var(--ease-out-expo);
}

/* ============================================
   Word Fade-Up (Typography Stagger)
   ============================================ */
@keyframes word-fade-up {
    0% { opacity: 0; transform: translateY(12px); filter: blur(4px); }
    100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}

.word-fade-up {
    display: inline-block;
    opacity: 0;
    animation: word-fade-up 0.5s var(--ease-out-expo) forwards;
}

/* ============================================
   Toast Animations
   ============================================ */
@keyframes toast-enter {
    0% { opacity: 0; transform: translateX(100%); }
    60% { transform: translateX(-4px); }
    100% { opacity: 1; transform: translateX(0); }
}

@keyframes toast-exit {
    0% { opacity: 1; transform: translateX(0); }
    100% { opacity: 0; transform: translateX(100%); }
}

@keyframes toast-progress {
    0% { width: 100%; }
    100% { width: 0%; }
}

.toast-animate-enter {
    animation: toast-enter 0.4s var(--ease-spring) forwards;
}

.toast-animate-exit {
    animation: toast-exit 0.3s ease-in forwards;
}

.toast-progress-bar {
    animation: toast-progress linear forwards;
}

/* ============================================
   Navigation Progress Bar
   ============================================ */
@keyframes nav-progress-indeterminate {
    0% { left: -30%; width: 30%; }
    50% { left: 50%; width: 30%; }
    100% { left: 100%; width: 0%; }
}

.nav-progress-bar {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    z-index: 99;
    background: linear-gradient(90deg, var(--primary), color-mix(in srgb, var(--primary) 60%, transparent));
    transition: width 0.2s ease, opacity 0.3s ease;
}

/* ============================================
   BottomNavigation — tab press feedback
   ============================================ */
.tab-press {
    transition: transform 120ms ease;
}
.tab-press:active {
    transform: scale(0.97);
}

/* FAB — press feedback */
.fab-press {
    transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.fab-press:active {
    transform: scale(0.96) !important;
}

/* SidebarDrawer — spring enter */
@keyframes sidebarDrawerSlideIn {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}
@keyframes sidebarDrawerOverlayFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
.sidebar-drawer-panel {
    animation: sidebarDrawerSlideIn 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.sidebar-drawer-overlay {
    animation: sidebarDrawerOverlayFadeIn 200ms ease;
}

/* SidebarDrawer — menu items */
.sidebar-menu-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px;
    border-radius: 12px;
    font-size: 17px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    transition: background-color 150ms ease;
}
.sidebar-menu-item:hover {
    background: var(--surface-2);
}
.sidebar-menu-item.active {
    background: var(--primary-bg);
    color: var(--primary);
}

/* Glassmorphism fallback — Safari < 15 and older browsers without backdrop-filter support.
   Yüksek alpha (0.85), blur yok. rgb(var(--ds-rgb-bg-elevated)) tokens.css'te .dark altında
   yeniden tanımlı olduğu için tek kural light/dark ikisini de kapsar — ayrı prefers-color-scheme
   bloğuna gerek yok (site class-bazlı .dark toggle kullanır, sistem tercihine değil). */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .bottom-nav-glass {
        background: rgb(var(--ds-rgb-bg-elevated) / 0.85) !important;
    }
}

/* ============================================
   Reduced Motion — Disable ALL animations
   ============================================ */
@media (prefers-reduced-motion: reduce) {
    .btn-spring,
    .like-active,
    .star-click-ripple,
    .shimmer,
    .char-glow-flash,
    .badge-spring-in,
    .xp-badge-pulse,
    .pulse-glow-ring,
    .page-enter,
    .word-fade-up,
    .toast-animate-enter,
    .toast-animate-exit,
    .toast-progress-bar,
    .nav-progress-bar,
    .tab-press,
    .fab-press,
    .sidebar-drawer-panel,
    .sidebar-drawer-overlay,
    .sidebar-menu-item {
        animation: none !important;
        transition: none !important;
    }

    .word-fade-up {
        opacity: 1;
    }
}

/* ============================================
   OTP hata sallanması — mobil OtpCells ile aynı: ±8/±6/±3 px, 7 adım × 40 ms
   ============================================ */
@keyframes otp-shake {
    0%, 100% { transform: translateX(0); }
    14% { transform: translateX(-8px); }
    28% { transform: translateX(8px); }
    42% { transform: translateX(-6px); }
    57% { transform: translateX(6px); }
    71% { transform: translateX(-3px); }
    85% { transform: translateX(3px); }
}

@media (prefers-reduced-motion: no-preference) {
    .otp-shake {
        animation: otp-shake 280ms linear;
    }
}
