/* ============================
   Veraius Animation System
   Page transitions, micro-interactions,
   skeleton loading, toast, ripple,
   AI-themed animations
   ============================ */

/* ============================
   Global Motion Tokens
   ============================ */
:root {
    --motion-fast: 120ms;
    --motion-base: 180ms;
    --motion-slow: 280ms;
    --ease-standard: cubic-bezier(0.2, 0, 0, 1);
    --ease-decelerate: cubic-bezier(0, 0, 0, 1);
    --ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
    --motion-distance-sm: 4px;
    --motion-distance-md: 10px;
    --motion-scale-hover: 1.01;
}

/* ============================
   Page Entry Animations
   ============================ */
@keyframes page-enter {
    from { opacity: 0; transform: translateY(8px) scale(0.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.page-enter {
    animation: page-enter var(--motion-slow) var(--ease-decelerate);
}

@keyframes page-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

.page-fade { animation: page-fade var(--transition-page, 150ms) var(--ease-decelerate); }

/* ============================
   Canonical Fade Vocabulary
   Use these in place of locally-redeclared `fadeIn` keyframes.
   - fade-in       : opacity only
   - fade-in-up    : opacity + 8px translateY entrance
   - fade-in-blur  : opacity + 4px filter blur entrance (premium)
   ============================ */
@keyframes fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes fade-in-up {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in-blur {
    from { opacity: 0; filter: blur(4px); }
    to { opacity: 1; filter: blur(0); }
}

/* ============================
   Skeleton Shimmer Loading
   ============================ */
@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

.skeleton {
    background: linear-gradient(
        90deg,
        var(--surface-container) 25%,
        var(--surface-container-high) 37%,
        var(--surface-container) 63%
    );
    background-size: 200% 100%;
    animation: shimmer 1.8s var(--ease-standard) infinite;
    border-radius: var(--card-radius);
}

.skeleton-text {
    height: 0.875rem;
    width: 100%;
    margin-bottom: 0.5rem;
}

.skeleton-text-sm {
    height: 0.75rem;
    width: 75%;
    margin-bottom: 0.375rem;
}

.skeleton-title {
    height: 1.25rem;
    width: 60%;
    margin-bottom: 0.75rem;
}

/* DESIGN.md: Radius-full */
.skeleton-avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
}

.skeleton-card {
    height: 120px;
    width: 100%;
    border-radius: var(--card-radius);
}

.skeleton-stat {
    height: 80px;
    width: 100%;
    border-radius: var(--card-radius);
}

.skeleton-row {
    height: 48px;
    width: 100%;
    border-radius: var(--btn-radius);
    margin-bottom: 0.5rem;
}

/* ============================
   Card Hover Effects
   ============================ */
.card-hover {
    transition: transform var(--transition-card, 150ms) var(--ease-standard),
                box-shadow var(--transition-card, 150ms) var(--ease-standard),
                border-color var(--motion-fast) var(--ease-standard);
    will-change: transform;
}

.card-hover:hover {
    transform: translateY(calc(var(--motion-distance-sm) * -1));
    box-shadow: var(--shadow-lg);
    /* --glass-border-hover hiç tanımlı değildi; yedek `transparent` her zaman
   devreye giriyordu, yani hover kenarlığı HİÇ görünmüyordu (ölçüldü
   2026-09-11). Kanonik --glass-border kullanılır. */
    border-color: var(--glass-border);
}

.card-hover:active {
    transform: translateY(0);
}

/* ============================
   Button Ripple Effect
   ============================ */
.ripple {
    position: relative;
    overflow: hidden;
}

/* DESIGN.md: Radius-full */
.ripple::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    /* Theme-aware ripple tint: light-on-dark, dark-on-light. */
    background: rgba(var(--on-surface-rgb), 0.15);
    border-radius: var(--radius-full);
    transform: translate(-50%, -50%);
    transition: width var(--motion-slow) var(--ease-standard),
                height var(--motion-slow) var(--ease-standard),
                opacity var(--motion-base) var(--ease-standard);
    opacity: 0;
}

.ripple:active::after {
    width: 200%;
    height: 200%;
    opacity: 1;
    transition: 0s;
}

/* ============================
   Expand / Collapse
   ============================ */
.collapse-content {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height var(--motion-slow) var(--ease-standard),
                opacity var(--motion-base) var(--ease-standard);
}

.collapse-content.open {
    max-height: 2000px;
    opacity: 1;
}

/* ============================
   Toast Notifications
   ============================ */
@keyframes toast-in {
    from { transform: translateX(100%); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

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

.toast-enter { animation: toast-in var(--transition-toast, 300ms) var(--ease-decelerate); }
.toast-exit { animation: toast-out var(--transition-toast, 300ms) var(--ease-accelerate) forwards; }

/* ============================
   Slide Animations
   ============================ */
@keyframes slide-up {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

@keyframes slide-down {
    from { transform: translateY(-20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

.slide-up { animation: slide-up var(--motion-slow) var(--ease-decelerate); }
.slide-down { animation: slide-down var(--motion-base) var(--ease-decelerate); }

/* ============================
   Scale Animations
   ============================ */
@keyframes scale-in {
    from { transform: scale(0.95); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.scale-in { animation: scale-in var(--motion-base) var(--ease-decelerate); }

/* ============================
   Spin / Loader
   ============================ */
@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* DESIGN.md: Radius-full */
.spinner {
    display: inline-block;
    width: 20px;
    height: 20px;
    border: 2px solid var(--outline-variant);
    border-top-color: var(--primary);
    border-radius: var(--radius-full);
    animation: spin var(--duration-slow) linear infinite;
}

.spinner-lg {
    width: 40px;
    height: 40px;
    border-width: 3px;
}

/* ============================
   Pulse Dot (Status Indicator)
   ============================ */
@keyframes pulse-dot {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.5); opacity: 0.5; }
}

/* DESIGN.md: Radius-full */
/* SONSUZ NABIZ KALDIRILDI: bu noktanın renk varyantları (-success/-warning/-error)
   durumu zaten söylüyor; ayrıca titremesi bilgi eklemiyordu. Bkz. .pulse-dot-animated
   yanındaki ölçüm notu — /system-status'ta 24 sonsuz animasyon vardı. */
.pulse-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
}



.pulse-dot-success { background: var(--state-success); }
.pulse-dot-warning { background: var(--state-warning); }
/* Hareket YALNIZ hata durumunda ve yavaş: gerçekten müdahale isteyen tek hal. */
.pulse-dot-error {
    background: var(--state-error);
    animation: pulse-dot 2.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .pulse-dot-error { animation: none; }
}

/* ============================
   Tab Underline Animation
   ============================ */
.tab-underline {
    position: relative;
}

.tab-underline::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 2px;
    background: var(--primary);
    transition: width var(--motion-base) var(--ease-standard);
    transform: translateX(-50%);
}

.tab-underline.active::after,
.tab-underline:hover::after {
    width: 100%;
}

/* ============================
   Unified Micro-Interactions
   Buttons & button-likes get the snappy 50ms feel via --transition-btn.
   Inputs / cards / passive controls stay at the longer fast/base timings.
   ============================ */
button,
.btn,
[role="button"] {
    transition: color var(--transition-btn, 50ms) ease,
                background-color var(--transition-btn, 50ms) ease,
                border-color var(--transition-btn, 50ms) ease,
                box-shadow var(--transition-btn, 50ms) ease,
                transform var(--transition-btn, 50ms) ease,
                opacity var(--transition-btn, 50ms) ease;
}

a,
input,
textarea,
select,
.card {
    transition: color var(--motion-fast) var(--ease-standard),
                background-color var(--motion-fast) var(--ease-standard),
                border-color var(--motion-fast) var(--ease-standard),
                box-shadow var(--motion-base) var(--ease-standard),
                transform var(--motion-base) var(--ease-standard),
                opacity var(--motion-fast) var(--ease-standard);
}

button:hover,
.btn:hover,
[role="button"]:hover {
    transform: translateY(-1px);
}

button:active,
.btn:active,
[role="button"]:active {
    transform: translateY(0);
    transition-duration: var(--transition-btn, 50ms);
}

/* ============================
   Staggered List Animation
   ============================ */
.stagger-item {
    opacity: 0;
    animation: page-enter 300ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

/*
 * OLCULDU 2026-09-18: merdiven 8. cocukta KESILIYORDU ve 9.'dan sonrasi
 * "animation-delay" hic almadigi icin 0ms'ye dusuyordu — yani uzun listede
 * ilk sekiz oge sirayla, geri kalan HEPSI ayni anda beliriyordu.
 *
 * Kapsam olculdu: ".stagger-item" markup'ta 471 kez kullaniliyor ve bunlarin
 * 239'u "@foreach"/"@for" ile UretILIYOR — yani cocuk sayisi veriye bagli ve
 * sekizi asmasi kural, istisna degil.
 *
 * Cozum iki katmanli:
 *   1. Merdiven 12'ye uzatildi (olculen ilk-ekran listelerinin cogunu kapsar).
 *   2. 13. ve sonrasi icin SABIT bir taban gecikme: hepsi ayni anda degil,
 *      merdivenin son basamaginda belirir. Boylece cok uzun listede animasyon
 *      sonsuza uzamaz (13. oge 600ms'te, 200. oge de 600ms'te) ama "hepsi
 *      birden patladi" hissi de olusmaz.
 *
 * NEDEN calc(var(--i)) DEGIL: --i'yi markup'tan yazmak 239 dongu yerinin
 * TAMAMINI degistirmeyi gerektirir. Ayni dosyada ReasoningChainTimeline'in
 * "--stage-i" degiskeni tam bu yuzden OLU kaldi (hic atanmiyor, 0'a dusuyor).
 * CSS-only cozum tum cagri yerlerinde kendiliginden calisir.
 */
.stagger-item:nth-child(1) { animation-delay: 0ms; }
.stagger-item:nth-child(2) { animation-delay: 50ms; }
.stagger-item:nth-child(3) { animation-delay: 100ms; }
.stagger-item:nth-child(4) { animation-delay: 150ms; }
.stagger-item:nth-child(5) { animation-delay: 200ms; }
.stagger-item:nth-child(6) { animation-delay: 250ms; }
.stagger-item:nth-child(7) { animation-delay: 300ms; }
.stagger-item:nth-child(8) { animation-delay: 350ms; }
.stagger-item:nth-child(9) { animation-delay: 400ms; }
.stagger-item:nth-child(10) { animation-delay: 450ms; }
.stagger-item:nth-child(11) { animation-delay: 500ms; }
.stagger-item:nth-child(12) { animation-delay: 550ms; }

/* 13. ve sonrasi: merdivenin son basamaginda kalir. */
.stagger-item:nth-child(n+13) { animation-delay: 600ms; }

/* ============================
   Number Counter Animation
   ============================ */
@keyframes count-up {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.count-up {
    animation: count-up 400ms ease-out;
}

/* ============================
   Progress Bar Animation
   ============================ */
@keyframes progress-fill {
    from { width: 0; }
}

.progress-bar {
    height: 4px;
    background: var(--surface-container-high);
    border-radius: var(--radius-full);
    overflow: hidden;
}

.progress-bar-fill {
    height: 100%;
    background: var(--gradient-accent);
    border-radius: var(--radius-full);
    transition: width 600ms ease-out;
    animation: progress-fill 600ms ease-out;
}

/* ============================
   AI-Themed Animations
   ============================ */

/* Scanning line effect — use on loading bars or AI processing indicators */
@keyframes ai-scan {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}

.ai-scan {
    position: relative;
    overflow: hidden;
}

.ai-scan::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, var(--primary-glow), transparent);
    animation: ai-scan var(--duration-cinematic) ease-in-out infinite;
}

/* Pulse glow for AI processing states */
@keyframes ai-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 0%, transparent); }
    50% { box-shadow: 0 0 20px 4px color-mix(in srgb, var(--primary) 20%, transparent); }
}

.ai-pulse {
    animation: ai-pulse var(--duration-cinematic) ease-in-out infinite;
}

/* Breathing border glow — use on active/processing cards */
@keyframes border-breathe {
    0%, 100% { border-color: var(--ghost-border, rgba(255, 255, 255, 0.08)); }
    50% { border-color: color-mix(in srgb, var(--primary) 30%, transparent); }
}

.border-breathe {
    animation: border-breathe 3s ease-in-out infinite;
}

/* Data stream dots — use on data flow indicators */
@keyframes data-flow {
    0% { opacity: 0; transform: translateY(8px); }
    50% { opacity: 1; }
    100% { opacity: 0; transform: translateY(-8px); }
}

/* DESIGN.md: Radius-full */
.data-flow-dot {
    width: 4px;
    height: 4px;
    border-radius: var(--radius-full);
    background: var(--primary);
    animation: data-flow 1.5s ease-in-out infinite;
}

.data-flow-dot:nth-child(2) { animation-delay: 0.2s; }
.data-flow-dot:nth-child(3) { animation-delay: 0.4s; }
.data-flow-dot:nth-child(4) { animation-delay: 0.6s; }

/* Orbital glow — use on AI agent status indicators */
@keyframes orbital {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

.ai-orbital {
    position: relative;
}

.ai-orbital::before {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
    background: conic-gradient(from 0deg, transparent, var(--primary), transparent);
    animation: orbital 3s linear infinite;
    /* stylelint-disable color-no-hex -- mask: siyah/beyaz renk değil, alfa kanalıdır */
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    /* stylelint-enable color-no-hex */
    mask-composite: exclude;
    -webkit-mask-composite: xor;
    padding: 2px;
}

/* ============================
   Error Shake
   ============================ */
@keyframes shake {
    0%, 100% { transform: translateX(0); }
    15% { transform: translateX(-6px); }
    30% { transform: translateX(6px); }
    45% { transform: translateX(-4px); }
    60% { transform: translateX(4px); }
    75% { transform: translateX(-2px); }
    90% { transform: translateX(2px); }
}

.shake {
    animation: shake 400ms ease-out;
}

/* ============================
   Success Checkmark (SVG draw)
   ============================ */
@keyframes checkmark-draw {
    0% { stroke-dashoffset: 24; }
    100% { stroke-dashoffset: 0; }
}

@keyframes success-flash {
    0% { background-color: rgba(var(--state-success-rgb, 76, 175, 80), 0.15); }
    100% { background-color: transparent; }
}

.success-check-svg {
    stroke: var(--state-success);
    stroke-dasharray: 24;
    stroke-dashoffset: 24;
    animation: checkmark-draw 350ms ease-out 100ms forwards;
}

.success-flash {
    animation: success-flash 600ms ease-out;
}

/* ============================
   Typing / Thinking Indicator
   ============================ */
@keyframes typing-bounce {
    0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
    30% { transform: translateY(-6px); opacity: 1; }
}

.typing-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: var(--space-3) var(--space-4);
}

.typing-indicator-dot {
    width: 6px;
    height: 6px;
    border-radius: var(--radius-full);
    background: var(--brand-teal);
    animation: typing-bounce 1.2s ease-in-out infinite;
}

.typing-indicator-dot:nth-child(2) { animation-delay: 0.15s; }
.typing-indicator-dot:nth-child(3) { animation-delay: 0.3s; }

@media (prefers-reduced-motion: reduce) {
    .typing-indicator-dot {
        animation: none;
        opacity: 0.65;
    }
}

/* ============================
   Chat Message Entry
   ============================ */
@keyframes msgSlideUp {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes msgSlideDown {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ============================
   Scroll-Triggered Reveal
   ============================ */
.reveal-hidden {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 400ms ease-out, transform 400ms ease-out;
}

.reveal-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ============================
   Page Route Transition
   ============================ */
@keyframes page-leave {
    from { opacity: 1; transform: scale(1); }
    to { opacity: 0; transform: scale(0.98); }
}

.page-leaving {
    animation: page-leave var(--transition-page, 150ms) ease-in forwards;
    pointer-events: none;
}

/* ============================
   Focus-Visible Ring
   ============================ */
:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Suppress default outline when not keyboard-focused */
:focus:not(:focus-visible) {
    outline: none;
}

/* ============================
   animate.css — REFERANS KATMANI
   ============================

   KARAR 2026-09-18 (kullanici): animate.css REFERANS alinir, kendi
   animasyonlarimiz ONA EK olur — biri digerinin yerine gecmez.

   OLCULEN durum: lib/animate/animate.min.css (71.750 bayt, 105 sinif)
   route-scripts-manifest.json'daki "lottie" bundle'i ile /chat, /onboarding
   ve /onboarding/tour rotalarina yukleniyordu ama markup'ta "animate__"
   kullanimi SIFIRDI. Yani yuk odeniyor, karsiligi alinmiyordu.

   Bizim katmanimiz 28 keyframes tasiyor (page-enter, fade-in-up, shimmer,
   toast-in/out, ai-scan, border-breathe, orbital, checkmark-draw…) ve
   bunlarin hicbirinin animate.css'te karsiligi YOK — urun-ozgu hareketler.
   animate.css ise bizde olmayan aileleri getiriyor: backIn*, bounceIn*,
   flip*, zoom*, lightSpeed*, rotateIn*.

   Iki sistem CAKISMIYOR cunku adlari ayri: onlar ".animate__X", bizimkiler
   anlamsal sinif adlari. Bu blok ikisini TEK hareket diline baglar:

   1. Sure/gecikme animate.css'in kendi degiskenleriyle ayarlanir
      (--animate-duration / --animate-delay), boylece iki sistem ayni
      tempoyu paylasir.
   2. Asagidaki GLOBAL reduced-motion kill switch "*" secicisiyle yazildigi
      icin animate__ sinifllarini ZATEN kapsar — ayri bir dal gerekmez.
      Bu, Motion One'in veremedigi sey: tek kural, 583 keyframes'i birden
      kapatiyor ve audit:reduced-motion:guard onu CI'da donduruyor.
   ============================ */
/* OLCULDU 2026-09-18 tarayicida: bu blok once duz ":root" ile yazildi ve
   KAZANMADI — animate.min.css rota bundle'i ile SONRA yukleniyor (olculen
   sira: bizimki 8, animate 16/19) ve ayni ozgullukte oldugu icin kaynak
   sirasi onu kazandiriyordu. Olculen deger "1s", beklenen "300ms".

   Cozum ozgullugu yukseltmek: ":root:root" (0,2,0) tek sinifli bir kurali
   yener ve tema seciciyle de cakismaz. Ayni ders CLAUDE.md'de ".btn-danger"
   vakasinda yazili — bir tasarim karari kaynak sirasina birakilmaz. */
:root:root {
    /* animate.css'in tempo degiskenlerini KENDI token'larimiza bagla:
       iki sistemden gelen hareket ayni hizda olsun. */
    --animate-duration: var(--duration-normal, 300ms);
    --animate-delay: 0ms;
    --animate-repeat: 1;
}

/* ============================
   Accessibility: Reduced Motion (Canonical Global Guard)
   ----------------------------------------------------------------
   WCAG 2.3.3 (Animation from Interactions) + WCAG 2.2.2 (Pause, Stop, Hide):
   honour the OS-level "Reduce Motion" / "Limit motion" setting by collapsing
   every animation and transition in the document to a near-zero duration
   regardless of the originating stylesheet.

   This rule is the SINGLE source of truth for motion-reduction in Veraius.
   Per-component CSS (razor.css, *.css under wwwroot/css) does not need to
   wrap each individual @keyframes / `transition:` declaration in its own
   `@media (prefers-reduced-motion: reduce)` block — the universal selector
   below catches all of them. Audit `npm run audit:reduced-motion:guard`
   verifies this block has not been deleted or weakened.

   The 0.01ms duration (rather than 0) keeps `transitionend` / `animationend`
   events firing so JS that depends on them (focus restoration, layout
   measurement) still completes its handler chain.

   `scroll-behavior: auto` reverts CSS smooth-scroll to instant jump, which
   is the expected behavior for users with vestibular sensitivities.
   ============================ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
