﻿/* ============================================================
   Nibras — Material & Motion layer
   ============================================================

   Bu dosya YENİ bir tasarım getirmez. Var olan Nibras bileşenlerinin
   üstüne yalnızca "malzeme" (translucency + blur + derinlik) ve
   Apple'ın akışkan arayüz ilkelerinden gelen etkileşim/hareket
   cilasını ekler.

   KURALLAR:
   - Hiçbir renk DEĞİŞTİRİLMEZ. Cam yüzeyler var olan token'ların
     (--paper, --cream, --ink ...) yalnızca ALFA değeriyle türetilir;
     ton/kimlik aynı kalır. color-mix() bunu tema-duyarlı yapar, yani
     _PanelTheme.cshtml yeşil ink ölçeğine kaydırdığında gölgeler ve
     malzemeler de otomatik olarak onu izler.
   - Layout, içerik, ikon, rota, davranış değişmez. Sadece CSS.
   - Her layout'ta EN SON yüklenir (inline <style> bloklarından da
     sonra) ki kaskadda kazansın.
   ============================================================ */


/* ============================================================
   1) TOKENS — motion + material
   Var olan --shadow-* / --ease-out / --dur-* token'ları KORUNUR;
   burada yalnızca yenileri eklenir.
   ============================================================ */

:root {
  /* Kritik sönümlü (damping ~1.0) hissi veren eğri — iOS sheet/menu
     hareketinin web karşılığı. Aşma yok, yumuşak oturma. */
  --ease-material: cubic-bezier(0.32, 0.72, 0, 1);
  /* Basma geri bildirimi: anında başlar, hızlı biter. */
  --ease-press: cubic-bezier(0.2, 0, 0, 1);
  /* Sadece momentum taşıyan (fırlatma/açılma) hareketler için hafif aşma. */
  --ease-spring: cubic-bezier(0.34, 1.22, 0.64, 1);

  --dur-press: 110ms;   /* pointer-down geri bildirimi */
  --dur-mat: 260ms;     /* malzemenin arayüze girip çıkışı */

  /* --- Malzeme: var olan yüzey renklerinin yalnız alfa'sı ---
     Taban değerler token'ların düz (statik) karşılıkları. */
  --mat-paper: rgba(255, 255, 255, 0.82);
  --mat-paper-thick: rgba(255, 255, 255, 0.86);
  --mat-cream: rgba(251, 247, 238, 0.72);
  --mat-cream-thick: rgba(251, 247, 238, 0.92);
  --mat-edge: rgba(255, 255, 255, 0.55);

  /* Yükseklik basamakları: kutuyu çizgiyle değil, ışıkla ayır.
     Hepsi ink tonundan türer — yeni renk yok. */
  --mat-elev-1: 0 1px 2px rgba(11, 16, 32, 0.04), 0 5px 14px rgba(11, 16, 32, 0.06);
  --mat-elev-2: 0 2px 4px rgba(11, 16, 32, 0.05), 0 14px 32px rgba(11, 16, 32, 0.11);

  /* Blur şiddeti yüzey büyüklüğüne göre: büyük yüzey = kalın malzeme */
  --mat-blur-sm: saturate(180%) blur(12px);
  --mat-blur-md: saturate(180%) blur(20px);
  --mat-blur-lg: saturate(180%) blur(30px);

  /* Gölgeler ink tonundan türer (siyah değil) */
  --mat-shadow-rest: 0 1px 2px rgba(11, 16, 32, 0.05);
  --mat-shadow-pop: 0 12px 32px rgba(11, 16, 32, 0.12), 0 2px 6px rgba(11, 16, 32, 0.06);
  --mat-shadow-float: 0 24px 60px rgba(11, 16, 32, 0.14), 0 4px 12px rgba(11, 16, 32, 0.06);
  --mat-veil: rgba(11, 16, 32, 0.06);
}

/* color-mix() varsa aynı token'lar tema-duyarlı hale gelir: _PanelTheme
   ink ölçeğini yeşile kaydırdığında gölgeler de onu izler. Custom
   property'ler ayrıştırma anında doğrulanmadığı için bu blok @supports
   ile korunur — aksi halde desteklemeyen tarayıcıda box-shadow tamamen
   geçersizleşir, üstteki taban değere düşmez. */
@supports (color: color-mix(in srgb, red 50%, transparent)) {
  :root {
    --mat-paper: color-mix(in srgb, var(--paper) 82%, transparent);
    --mat-paper-thick: color-mix(in srgb, var(--paper) 86%, transparent);
    --mat-cream: color-mix(in srgb, var(--cream) 72%, transparent);
    --mat-cream-thick: color-mix(in srgb, var(--cream) 92%, transparent);
    --mat-edge: color-mix(in srgb, var(--paper) 55%, transparent);

    --mat-elev-1:
      0 1px 2px color-mix(in srgb, var(--ink) 4%, transparent),
      0 5px 14px color-mix(in srgb, var(--ink) 6%, transparent);
    --mat-elev-2:
      0 2px 4px color-mix(in srgb, var(--ink) 5%, transparent),
      0 14px 32px color-mix(in srgb, var(--ink) 11%, transparent);

    --mat-shadow-rest: 0 1px 2px color-mix(in srgb, var(--ink) 5%, transparent);
    --mat-shadow-pop:
      0 12px 32px color-mix(in srgb, var(--ink) 12%, transparent),
      0 2px 6px color-mix(in srgb, var(--ink) 6%, transparent);
    --mat-shadow-float:
      0 24px 60px color-mix(in srgb, var(--ink) 14%, transparent),
      0 4px 12px color-mix(in srgb, var(--ink) 6%, transparent);
    --mat-veil: color-mix(in srgb, var(--ink) 6%, transparent);
  }
}

/* Malzemenin arayüze "girmesi": yalnız solmak yerine ölçek + derinlik. */
@keyframes nb-material-in {
  from { opacity: 0; transform: translateY(-8px) scale(0.965); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes nb-material-rise {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}


/* ============================================================
   2) PUBLIC NAV — yüzen cam şerit
   İçerik altından akar; kenarlık yerine derinlik ipucu.
   ============================================================ */

.nav-wrap {
  transition:
    background var(--dur-mat) var(--ease-material),
    border-color var(--dur-mat) var(--ease-material),
    box-shadow var(--dur-mat) var(--ease-material);
}
.nav-wrap.scrolled {
  background: var(--mat-cream);
  -webkit-backdrop-filter: saturate(180%) blur(36px);
  backdrop-filter: saturate(180%) blur(36px);
  /* üstte ışığı yakalayan ince highlight + altta yumuşak ayrım */
  box-shadow:
    inset 0 1px 0 var(--mat-edge),
    0 8px 28px var(--mat-veil);
}
/* Scroll-edge: sert 1px çizgi yerine, içeriğin şeridin altına girdiği
   yerde kısa bir geçiş. Yüzen kroma ait bir gölge gibi okunur. */
.nav-wrap.scrolled::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 100%;
  height: 14px;
  background: linear-gradient(to bottom, var(--mat-veil), transparent);
  pointer-events: none;
}

/* Marka rozeti: hover'da yükselme aynı, ama malzeme eğrisiyle */
.nav__brand .brand-badge { transition: transform var(--dur-base) var(--ease-material); }
.nav__brand:active .brand-badge { transform: translateY(0) scale(0.97); transition-duration: var(--dur-press); }

/* Alt çizgi göstergesi — jestin gittiği yöne doğru büyür */
.nav__links a::after { transition: transform var(--dur-base) var(--ease-material); }

.nav__toggle { transition:
    background var(--dur-base) var(--ease-material),
    border-color var(--dur-base) var(--ease-material),
    transform var(--dur-press) var(--ease-press); }
.nav__toggle:active { transform: scale(0.93); }

/* Mobil menü paneli: display anahtarı yerine malzeme geçişi.
   (JS yalnızca .is-open sınıfını değiştirir — davranış aynı.) */
@media (max-width: 1240px) {
  .nav__menu {
    display: flex;
    visibility: hidden;
    pointer-events: none;
    opacity: 0;
    transform: translateY(-10px) scale(0.985);
    transform-origin: top center;
    background: var(--mat-cream-thick);
    -webkit-backdrop-filter: var(--mat-blur-lg);
    backdrop-filter: var(--mat-blur-lg);
    box-shadow: var(--mat-shadow-float), inset 0 1px 0 var(--mat-edge);
    transition:
      opacity 200ms var(--ease-material),
      transform var(--dur-mat) var(--ease-material),
      visibility 0s linear var(--dur-mat);
  }
  .nav__menu.is-open {
    display: flex;
    visibility: visible;
    pointer-events: auto;
    opacity: 1;
    transform: translateY(0) scale(1);
    transition-delay: 0s;
  }
  /* Menü açıkken şerit kalınlaşır: altındaki metin okunur kalsın. */
  .nav-wrap.menu-open {
    background: var(--mat-cream-thick);
    -webkit-backdrop-filter: var(--mat-blur-lg);
    backdrop-filter: var(--mat-blur-lg);
  }
  .nav__menu .nav__links a { transition: background var(--dur-press) var(--ease-press), color var(--dur-fast) var(--ease-out); }
  .nav__menu .nav__links a:active { background: var(--cream-2); }

  /* Cam üstüne cam yığılmaz: menü içindeki dil listesi burada yüzen bir
     yüzey değil, panelin bir parçası — opak kalır. */
  .nav__menu .lang-drop__menu {
    background: var(--paper);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
    animation: none;
  }
}


/* ============================================================
   3) APP SHELL — topbar, sidebar, off-canvas sheet
   ============================================================ */

/* Topbar: içerik altından kayar, sert çizgi yerine malzeme + derinlik */
.tb {
  background: var(--mat-cream);
  -webkit-backdrop-filter: saturate(180%) blur(32px);
  backdrop-filter: saturate(180%) blur(32px);
  box-shadow:
    inset 0 1px 0 var(--mat-edge),
    0 8px 24px var(--mat-veil);
}
/* topbar'ın altında da aynı scroll-edge geçişi */
.tb::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 100%;
  height: 14px;
  background: linear-gradient(to bottom, var(--mat-veil), transparent);
  pointer-events: none;
}

/* Sidebar: yapısal, KOYU ve opak kalır — cam üstüne cam yığılmaz.
   Yalnızca yüzeyler arası ayrım için yumuşak bir derinlik ipucu. */
.sb {
  box-shadow: 0 0 40px var(--mat-veil);
  transition: margin var(--dur-mat) var(--ease-material);
}
.sb a { transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    transform var(--dur-press) var(--ease-press); }
.sb a:active { transform: scale(0.985); }
.sb__toggle,
.sb__user button { transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-press); }
.sb__toggle:active,
.sb__user button:active { transform: scale(0.92); }

.sb-open { transition: background var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-press); }
.sb-open:active { transform: scale(0.93); }

@media (max-width: 992px) {
  /* Off-canvas panel bir "sheet": aynı yoldan girer, aynı yoldan çıkar. */
  .sb {
    transition: transform var(--dur-mat) var(--ease-material);
    box-shadow: var(--mat-shadow-float);
  }
  .shell:not(.sb-mobile-open) .sb {
    transition: transform var(--dur-mat) var(--ease-material), visibility 0s linear var(--dur-mat);
  }

  /* Scrim: odaklamak için karartır + arka planı hafifçe geri iter.
     display anahtarı yerine sönümlü geçiş (renk aynı bırakıldı). */
  .sb-backdrop {
    display: block;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    transition: opacity var(--dur-mat) var(--ease-material), visibility 0s linear var(--dur-mat);
  }
  .shell.sb-mobile-open .sb-backdrop {
    display: block;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s;
  }
}

/* Topbar arama kutusu: küçük kontrol → cam DEĞİL, opak kalır
   (açık malzeme üstüne açık malzeme okunabilirliği bozar). */
.tb__search { transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); }
.tb__search:focus-within { border-color: var(--emerald); box-shadow: var(--shadow-focus); }

.tb__icon-btn { transition: background var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-press); }
.tb__icon-btn:active { transform: scale(0.93); }


/* ============================================================
   4) POPOVER / MENÜ / SHEET — kaynağından doğan malzeme
   Menüler tetikleyicilerinden büyür: transform-origin tetikleyiciye
   sabitlenir, böylece buton ile içerik arasındaki uzamsal ilişki
   belli olur.
   ============================================================ */

.lang-drop__menu,
.tb__search-results,
.menu {
  background: var(--mat-paper);
  -webkit-backdrop-filter: var(--mat-blur-md);
  backdrop-filter: var(--mat-blur-md);
  box-shadow: var(--mat-shadow-float), inset 0 1px 0 var(--mat-edge);
}

/* Dil seçici — summary'nin altına, hizalandığı köşeden açılır */
.lang-drop > summary {
  transition:
    border-color var(--dur-base) var(--ease-material),
    color var(--dur-base) var(--ease-material),
    background var(--dur-base) var(--ease-material),
    transform var(--dur-press) var(--ease-press);
}
.lang-drop > summary:active { transform: scale(0.97); }
.lang-drop .lang-drop__chev { transition: transform var(--dur-base) var(--ease-material); }

.lang-drop__menu { transform-origin: top right; }
[dir="rtl"] .lang-drop__menu { transform-origin: top left; }
.lang-drop[open] > .lang-drop__menu { animation: nb-material-in 220ms var(--ease-material) both; }

.lang-drop__opt { transition: background var(--dur-press) var(--ease-press), color var(--dur-press) var(--ease-press); }
.lang-drop__opt:active { transform: scale(0.985); }

/* Global arama önerileri — inputun altından iner */
.tb__search-results { transform-origin: top center; animation: nb-material-in 200ms var(--ease-material) both; }
.tb__search-results a { transition: background var(--dur-press) var(--ease-press); }

/* Admin satır menüsü — sağ üst köşesinden (RTL'de sol üst) büyür */
.menu { transform-origin: top right; animation: none; }
[dir="rtl"] .menu { transform-origin: top left; }
.menu.open { animation: nb-material-in 200ms var(--ease-material) both; }
.menu button { transition: background var(--dur-press) var(--ease-press), color var(--dur-press) var(--ease-press); }

/* SweetAlert2 diyalogları: modal görev → scrim + arkayı geri itme */
.swal2-container.swal2-backdrop-show {
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
}
.swal2-popup {
  border-radius: var(--r-lg);
  box-shadow: var(--mat-shadow-float);
}
.swal2-popup.swal2-show { animation: nb-material-rise 280ms var(--ease-material) both; }

/* KAPANIŞ KENDİ KEYFRAME'İNİ KULLANMAK ZORUNDA — açılışla aynı animation-name
   verilemez (eskiden "nb-material-rise ... reverse" idi ve sayfayı kilitliyordu):
   SweetAlert2 kapanırken .swal2-show yerine .swal2-hide koyar ve popup'ı DOM'dan
   ancak animationend olayında siler. Tarayıcı ise animasyonu yalnızca animation-name
   DEĞİŞİRSE yeniden başlatır; sadece direction/duration değişirse var olan (ve çoktan
   BİTMİŞ) animasyon korunur — yani ikinci bir animationend hiç doğmaz. Sonuç:
   .swal2-container sayfada asılı kalır. O katman tam ekrandır ve pointer-events: auto
   taşır, ayrıca <body> üzerinde overflow:hidden bırakılır; sayfa "donmuş" görünür,
   yalnızca F5 kurtarır. Çoğu ekranda diyalogdan sonra sayfa zaten yenilendiği için
   fark edilmiyordu — kurs erişim yöneticisi gibi AJAX ile yerinde tazelenen
   ekranlarda kilit doğrudan kullanıcının önüne çıkıyordu. */
@keyframes nb-material-sink {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(10px) scale(0.98); }
}
.swal2-popup.swal2-hide { animation: nb-material-sink 200ms var(--ease-material) both; }


/* ============================================================
   5) YÜZEN KARTLAR — dokunulabilir her şey basmaya cevap verir
   Hover kalkışları var olan değerlerde bırakıldı; eklenen tek şey
   pointer-down anında hissedilen fiziksel geri bildirim.
   ============================================================ */

.course-card,
.feature,
.news-tile,
.testimonial-card,
.instructor,
.kpi,
.person,
.adm-course,
.teach-course,
.my-course,
.course-list .course-row {
  transition:
    transform var(--dur-base) var(--ease-material),
    box-shadow var(--dur-base) var(--ease-material),
    border-color var(--dur-base) var(--ease-material);
}
.course-card:active,
.feature:active,
.news-tile:active,
.testimonial-card:active,
.instructor:active,
.kpi:active,
.person:active,
.adm-course:active,
.teach-course:active,
.my-course:active,
.course-list .course-row:active {
  transform: translateY(-1px) scale(0.994);
  transition-duration: var(--dur-press);
  transition-timing-function: var(--ease-press);
}

/* --- Durağan yükseklik ---------------------------------------------
   En görünür değişiklik burada. Kartlar daha önce "1px çizgiyle
   çevrelenmiş düz kutu"ydu; artık kâğıt gibi sayfanın üstünde duruyor.
   Çerçeve KALDIRILMADI (hâlâ ince bir kenar okunuyor), sadece ayrımı
   artık çizgi değil ışık taşıyor. Renk/dolgu/konum aynı. */
.card,
.course-card,
.feature,
.news-tile,
.testimonial-card,
.instructor,
.kpi,
.person,
.adm-course,
.teach-course,
.my-course,
.course-list .course-row,
.material-row,
.live-item {
  box-shadow: var(--mat-elev-1);
}
/* Hover'daki kalkış artık gerçekten "yükseliyor" gibi okunuyor.
   translateY değerleri değiştirilmedi — sadece gölge derinleşti. */
.course-card:hover,
.feature:hover,
.news-tile:hover,
.testimonial-card:hover,
.instructor:hover,
.kpi:hover,
.person:hover,
.adm-course:hover,
.teach-course:hover,
.my-course:hover,
.course-list .course-row:hover {
  box-shadow: var(--mat-elev-2);
}
/* Basınca yüzey yere yaklaşır — gölge de onunla birlikte toplanır. */
.course-card:active,
.feature:active,
.news-tile:active,
.testimonial-card:active,
.instructor:active,
.kpi:active,
.person:active,
.adm-course:active,
.teach-course:active,
.my-course:active,
.course-list .course-row:active { box-shadow: var(--mat-elev-1); }

/* Dolu butonlar da durağan halde hafifçe yüzer */
.btn--primary,
.btn--emerald,
.btn--saffron { box-shadow: var(--mat-elev-1); }
.btn--primary:active,
.btn--emerald:active,
.btn--saffron:active { box-shadow: var(--mat-shadow-rest); }

/* --- Hero'daki yüzen istatistik kartları: gerçek cam --------------
   Koyu hero panelinin üstünde duruyorlar; buzlu cam olarak okunmaları
   en doğrusu. Dolgu yine --paper, yalnızca alfa düştü. */
.hero__visual .panel--stat {
  background: rgba(255, 255, 255, 0.86);
  background: var(--mat-paper-thick);
  -webkit-backdrop-filter: var(--mat-blur-md);
  backdrop-filter: var(--mat-blur-md);
  box-shadow: var(--mat-shadow-float), inset 0 1px 0 var(--mat-edge);
}

/* Koyu sidebar'da seçili öğe: ışık yakalayan üst kenar */
.sb a.active { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07); }

/* Kapak üstündeki cam rozet. Not: .cover--cream .level'da blur bilerek
   kapatılmıştı (açık kapak üstünde okunmuyordu) — oraya dokunulmaz. */
.course-card__statuschip {
  -webkit-backdrop-filter: var(--mat-blur-sm);
  backdrop-filter: var(--mat-blur-sm);
}

/* Küçük kontroller: çip, segment, ikon butonu */
.filter-chip,
.seg button,
.view-toggle button,
.iconbtn,
.row-actions button,
.course-tabs button,
.footer__social a,
.tbl-foot .pager button,
.tbl-foot .pager a {
  transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    transform var(--dur-press) var(--ease-press);
}
/* Küçük/ikon hedefler biraz daha derin bastırılır; geniş metin
   kontrolleri az — aynı oran her boyutta doğru hissettirmiyor. */
.iconbtn:active,
.row-actions button:active,
.view-toggle button:active { transform: scale(0.92); }
.seg button:active,
.course-tabs button:active,
.tbl-foot .pager button:active,
.tbl-foot .pager a:active { transform: scale(0.96); }
/* hover'daki translateY iptal edilir, yoksa basınca yukarı zıplıyor */
.filter-chip:active { transform: translateY(0) scale(0.96); }
.footer__social a:active { transform: translateY(0) scale(0.94); }

/* Butonlar: basma anında (bırakışta değil) cevap verir */
.btn {
  transition:
    transform var(--dur-press) var(--ease-press),
    background var(--dur-base) var(--ease-material),
    box-shadow var(--dur-base) var(--ease-material),
    color var(--dur-base) var(--ease-material);
}
.btn:active { transform: translateY(0) scale(0.97); }

/* Ders satırı / oynat düğmesi */
.lesson-row { transition: background var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-press); }
.continue .play { transition: transform var(--dur-base) var(--ease-material), box-shadow var(--dur-base) var(--ease-material); }
.continue .play:active { transform: scale(0.96); transition-duration: var(--dur-press); }


/* ============================================================
   6) BİLDİRİM ŞERİTLERİ — malzeme olarak girip çıkar
   ============================================================ */

/* animation-fill-mode BİLEREK yok: _Layout'taki auto-dismiss betiği
   kapanışta inline opacity/transform yazıyor; "both" olsaydı animasyonun
   son karesi inline stili ezer ve şerit hiç kapanmazdı. */
.flash {
  box-shadow: var(--mat-shadow-pop);
  transition:
    opacity 220ms var(--ease-material),
    transform var(--dur-mat) var(--ease-material);
  animation: nb-material-in var(--dur-mat) var(--ease-material);
}
.flash__close { transition: opacity var(--dur-press) var(--ease-press), background var(--dur-press) var(--ease-press), transform var(--dur-press) var(--ease-press); }
.flash__close:active { transform: scale(0.9); }

.alert-strip { box-shadow: var(--mat-shadow-rest); }

.toast {
  box-shadow: var(--mat-shadow-float);
  animation: nb-material-rise var(--dur-mat) var(--ease-material) both;
}


/* ============================================================
   7) ERİŞİLEBİLİRLİK
   ============================================================ */

/* --- Azaltılmış hareket: kaydırma/yay yerine kısa çapraz geçiş --- */
@media (prefers-reduced-motion: reduce) {
  .lang-drop[open] > .lang-drop__menu,
  .tb__search-results,
  .menu.open,
  .flash,
  .toast,
  .swal2-popup.swal2-show,
  .swal2-popup.swal2-hide {
    animation: none;
  }

  /* Aşağıdakiler mevcut CSS'te prefers-reduced-motion kapsamı DIŞINDA
     kalmıştı. Sonsuz parlama döngüleri ~0.3 Hz salınım üretiyor —
     tam da vestibüler rahatsızlık veren banda düşüyor. */
  .btn--saffron.btn--lg,
  .btn--emerald.btn--lg,
  .day-card .schedule-item,
  .shell__content .pbar .fill,
  .continue .pbar .fill {
    animation: none;
  }

  /* Kayma/ölçek yerine düz çapraz geçiş — konum değişimi kalmaz. */
  .nav__menu {
    transform: none;
    transition: opacity 140ms linear, visibility 0s linear 140ms;
  }
  .nav__menu.is-open { transform: none; transition-delay: 0s; }
  .sb, .sb-backdrop { transition-duration: 140ms; }
  .course-card:active,
  .feature:active,
  .news-tile:active,
  .testimonial-card:active,
  .instructor:active,
  .kpi:active,
  .person:active,
  .adm-course:active,
  .teach-course:active,
  .my-course:active,
  .course-list .course-row:active,
  .btn:active,
  .filter-chip:active,
  .seg button:active,
  .view-toggle button:active,
  .iconbtn:active,
  .row-actions button:active,
  .course-tabs button:active,
  .footer__social a:active,
  .tbl-foot .pager button:active,
  .tbl-foot .pager a:active,
  .tb__icon-btn:active,
  .sb a:active,
  .sb__toggle:active,
  .sb-open:active,
  .nav__toggle:active,
  .lang-drop > summary:active,
  .continue .play:active {
    transform: none;
  }
}

/* --- Azaltılmış saydamlık: malzeme buzlanır, blur kalkar --- */
@media (prefers-reduced-transparency: reduce) {
  .nav-wrap.scrolled,
  .nav-wrap.menu-open,
  .nav__menu,
  .tb {
    background: var(--cream);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .lang-drop__menu,
  .tb__search-results,
  .menu,
  .hero__visual .panel--stat {
    background: var(--paper);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .course-card__statuschip,
  .sb-backdrop,
  .swal2-container.swal2-backdrop-show {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* --- Yüksek kontrast: neredeyse opak yüzey + belirgin kenarlık --- */
@media (prefers-contrast: more) {
  .nav-wrap.scrolled,
  .nav-wrap.menu-open,
  .nav__menu,
  .tb {
    background: var(--cream);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border-color: var(--ink-3);
  }
  .lang-drop__menu,
  .tb__search-results,
  .menu {
    background: var(--paper);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 1px solid var(--ink-3);
  }
}


/* ============================================================
   8) SAHNE AÇILIŞI — içerik sayfaya "gelir"
   ============================================================

   Gizleme sınıflarını (.nb-r / .nb-r-fade) fluid.js ekler; CSS
   kendiliğinden hiçbir şeyi gizlemez. Betik çalışmazsa içerik
   normal görünür — animasyon bir cila, bir bağımlılık değil.

   Public sayfalardaki elle konmuş [data-reveal] bloklarına
   dokunulmaz; onların kuralları marketing.css'te.
   ============================================================ */

/* Sınıf adı BİLEREK iki kez yazıldı (.nb-r.nb-r). Bazı bileşenlerin
   kendi geçişi daha özgül bir seçiciyle tanımlı — örneğin
   marketing.css'teki ".course-grid .course-card" (0,2,0) tek sınıflı
   ".nb-r"yi (0,1,0) ezip sıralı girişin gecikmesini yutuyordu.
   Bu tekrar özgüllüğü 0,2,0'a çıkarır; eşitlikte material.css en son
   yüklendiği için kaskadı kazanır. */
.nb-r.nb-r {
  opacity: 0;
  transform: translateY(16px) scale(0.985);
  transition:
    opacity 520ms var(--ease-material) var(--nb-d, 0ms),
    transform 620ms var(--ease-material) var(--nb-d, 0ms);
  will-change: transform, opacity;
}
.nb-r.nb-r.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Azaltılmış hareket: konum değişmez, yalnız çapraz geçiş. */
.nb-r-fade.nb-r-fade {
  opacity: 0;
  transition: opacity 240ms linear var(--nb-d, 0ms);
}
.nb-r-fade.nb-r-fade.is-in { opacity: 1; }


/* ============================================================
   9) SAYFA GEÇİŞLERİ — View Transitions
   ============================================================

   Gezinme artık "beyaz çakma + zıplama" değil: eski sayfa hafifçe
   geri çekilip solar, yenisi altından yükselir. Krom (üst şerit,
   kenar çubuğu, alt bilgi) ADLANDIRILDIĞI için geçişte yerinde
   kalır — sadece içerik değişir, tıpkı bir uygulamada olduğu gibi.

   Desteklemeyen tarayıcıda (bugün Firefox) hiçbir şey olmaz;
   gezinme eskisi gibi çalışır. Zarif düşüş.
   ============================================================ */

@view-transition { navigation: auto; }

/* Krom yerinde kalsın: kendi adı olan öğe kök geçişten ayrılır. */
.nav-wrap { view-transition-name: nb-nav; }
.footer   { view-transition-name: nb-footer; }
.tb       { view-transition-name: nb-topbar; }
.sb       { view-transition-name: nb-sidebar; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) {
    animation: nb-page-out 200ms var(--ease-material) both;
  }
  ::view-transition-new(root) {
    animation: nb-page-in 340ms var(--ease-material) both;
  }
  /* Krom "yeniden gelmez", olduğu yerde durur.
     Bu YALNIZCA krom her iki sayfada da varken doğrudur. */
  ::view-transition-old(nb-nav),
  ::view-transition-new(nb-nav),
  ::view-transition-old(nb-topbar),
  ::view-transition-new(nb-topbar),
  ::view-transition-old(nb-sidebar),
  ::view-transition-new(nb-sidebar),
  ::view-transition-old(nb-footer),
  ::view-transition-new(nb-footer) {
    animation: none;
    mix-blend-mode: normal;
  }

  /* KROM EŞLEŞMEDİĞİNDE (örn. public sayfadan, üst şeridi olmayan
     giriş ekranına geçiş): yukarıdaki "hiç oynama" kuralı burada
     yanlış sonuç verir — eski başlığın anlık görüntüsü tam
     opaklıkta geçiş boyunca ekranda kalır, sonra birden kaybolur.
     Kullanıcı yeni sayfadayken yarım saniye eski başlığı görür.

     :only-child tam olarak bu durumu yakalar: ad iki belgeden
     yalnız birinde varsa görüntü çiftinin tek çocuğu olur. O zaman
     krom kısa ve net biçimde silinir/gelir. */
  ::view-transition-old(nb-nav):only-child,
  ::view-transition-old(nb-topbar):only-child,
  ::view-transition-old(nb-sidebar):only-child,
  ::view-transition-old(nb-footer):only-child {
    animation: nb-fade-out 90ms linear both;
  }
  ::view-transition-new(nb-nav):only-child,
  ::view-transition-new(nb-topbar):only-child,
  ::view-transition-new(nb-sidebar):only-child,
  ::view-transition-new(nb-footer):only-child {
    animation: nb-fade-in 140ms linear both;
  }
}

@keyframes nb-page-in {
  from { opacity: 0; transform: translateY(12px) scale(0.994); }
  to   { opacity: 1; transform: none; }
}
@keyframes nb-page-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-6px) scale(0.997); }
}

/* Azaltılmış harekette geçiş düz çapraz solmaya iner. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root) { animation: nb-fade-out 120ms linear both; }
  ::view-transition-new(root) { animation: nb-fade-in 120ms linear both; }
}
@keyframes nb-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes nb-fade-out { from { opacity: 1; } to { opacity: 0; } }


/* ============================================================
   10) CAM — malzemenin görünür olduğu yerler
   ============================================================ */

/* Hero'su olmayan sayfalarda üst şerit dinlenme hâlinde de cam.
   (Ana sayfada şerit hero'nun üstünde şeffaf durmalı; orada cam
   fotoğrafı boğardı — bu yüzden :has ile ayrılıyor.) */
body:not(:has(.hero)) .nav-wrap {
  background: var(--mat-cream);
  -webkit-backdrop-filter: saturate(180%) blur(30px);
  backdrop-filter: saturate(180%) blur(30px);
  box-shadow: inset 0 1px 0 var(--mat-edge);
}

/* Fotoğraflı ders kahramanı üstündeki eylem kartı: arkasında
   gerçek bir görüntü var, dolayısıyla cam burada gerçekten cam
   gibi okunur — malzemenin en belirgin olduğu yer. */
.cd-cta-card {
  -webkit-backdrop-filter: saturate(160%) blur(22px);
  backdrop-filter: saturate(160%) blur(22px);
  box-shadow: var(--mat-shadow-float), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* Galeri altyazı şeridi — fotoğrafın üstünde yüzen etiket */
.cl-tile__cap {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* Bildirimler içeriğin üstünde yüzer → cam olmaları doğru */
.flash,
.toast {
  -webkit-backdrop-filter: var(--mat-blur-md);
  backdrop-filter: var(--mat-blur-md);
  box-shadow: var(--mat-shadow-float), inset 0 1px 0 var(--mat-edge);
}

/* Alt bilgide ışığı yakalayan üst kenar — koyu yüzeyi sayfadan
   çizgiyle değil ışıkla ayırır. */
.footer::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
  pointer-events: none;
}

/* Sürükleme sırasında geçiş olmaz: parmak neredeyse yüzey orada.
   (Araya CSS transition girerse 1:1 takip bozulur.) */
.sb.nb-dragging { transition: none !important; }
.shell:has(.sb.nb-dragging) .sb-backdrop { transition: none !important; }


/* ============================================================
   11) TİPOGRAFİ — boyuta göre izleme (tracking)
   ============================================================

   Apple'ın kuralı: büyüyen metin harfleri fazla ayrık gösterir,
   bu yüzden büyük başlıklar NEGATİF izleme ister.

   DİKKAT — bu yalnızca Latin alfabesine uygulanır. Arapça bitişik
   yazılır; letter-spacing harf bağlarını koparıp kelimeyi okunmaz
   hâle getirir. Bu yüzden kural :lang ile sınırlandı ve Arapça
   arayüz (sitenin varsayılanı) kapsam dışında bırakıldı.
   ============================================================ */

html:not([lang="ar"]) h1,
html:not([lang="ar"]) .hero h1,
html:not([lang="ar"]) .cd-hero h1 {
  letter-spacing: -0.022em;
  line-height: 1.08;
}
html:not([lang="ar"]) h2 { letter-spacing: -0.017em; }
html:not([lang="ar"]) h3 { letter-spacing: -0.011em; }

/* Küçük ve büyük harfli etiketler tersine: hafif POZİTİF izleme
   okunurluğu artırır. Bunlar zaten Latin/rakam ağırlıklı. */
.kicker,
.ctx-kicker,
.cd-stat .l,
.badge {
  letter-spacing: 0.14em;
}


/* ============================================================
   12) ERİŞİLEBİLİRLİK — yeni katmanlar için
   ============================================================ */

@media (prefers-reduced-transparency: reduce) {
  body:not(:has(.hero)) .nav-wrap,
  .flash,
  .toast,
  .cd-cta-card,
  .cl-tile__cap {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  body:not(:has(.hero)) .nav-wrap { background: var(--cream); }
}

@media (prefers-reduced-motion: reduce) {
  /* Sürüklenen yüzey yayla değil, anında yerine döner. */
  .sb.nb-dragging { transition: none !important; }
}


/* ============================================================
   13) PANELLER — yönetici · öğretmen · öğrenci
   ============================================================

   Üç panel de aynı iskeleti paylaşır (.shell / .sb / .tb ve
   .card / .btn / .badge). Bu yüzden buradaki kurallar tek yerden
   ÜÇÜNE BİRDEN iner; her panel için ayrı kopya tutulmaz.

   Kural yine aynı: renk kimliği değişmez. Yüzeyler var olan
   token'ların alfasından türer, ayrım çizgiyle değil ışıkla
   yapılır.
   ============================================================ */

/* --- Kenar çubuğu ------------------------------------------
   Burada bir ara saydam koyu malzeme (alfa + blur) ve seçili öğe
   için cam hap denendi; kenar çubuğunun RENGİNİ gözle görülür
   biçimde değiştirdiği için tamamen geri alındı. Kenar çubuğu
   yönetici, öğretmen ve öğrenci panellerinde var olan opak
   rengini korur. Hareket/geçiş tarafı zaten yukarıdaki 3. bölümde
   tanımlı — burada tekrar edilmez. */

/* --- İçerik yüzeyleri --------------------------------------
   Panel kartları artık "1px çizgiyle çevrili kutu" değil, sayfanın
   üstünde duran kâğıt. Üstteki ince highlight ışığın malzemeye
   çarptığı yer. */
.kpi,
.tbl-card,
.ann-card,
.day-card,
.lesson-list-card,
.live-list-card,
.dash-col > .card,
/* öğrenci panosu kendi sd-* sınıflarını kullanıyor — aynı malzeme */
.sd-panel,
.sd-quick-card,
.sd-continue-row {
  box-shadow:
    var(--mat-elev-1),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.kpi:hover,
.ann-card:hover,
.day-card:hover,
.sd-quick-card:hover,
.sd-continue-row:hover {
  box-shadow:
    var(--mat-elev-2),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

/* Dokunulabilir panel kartları basmaya cevap verir */
.sd-quick-card,
.sd-continue-row,
.sd-remind-item {
  transition:
    transform var(--dur-base) var(--ease-material),
    box-shadow var(--dur-base) var(--ease-material),
    background var(--dur-fast) var(--ease-out);
}
.sd-quick-card:active,
.sd-continue-row:active,
.sd-remind-item:active {
  transform: translateY(-1px) scale(0.994);
  transition-duration: var(--dur-press);
  transition-timing-function: var(--ease-press);
}

/* KPI ikon kutusu: küçük yüzey, hafif iç ışık */
.kpi .ico { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45); }

/* --- Tablolar: satırlar dokunulabilir hissetmeli ------------ */
.tbl tbody tr {
  transition:
    background var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}
.tbl tbody tr:hover { background: var(--cream); }
/* Basma anında satır yüzeye yaklaşır */
.tbl tbody tr:active { background: var(--cream-2); }

/* Tablo başlığı gövdeden ışıkla ayrılır */
.tbl thead { box-shadow: inset 0 -1px 0 var(--mat-veil); }

/* --- Durum şeritleri ---------------------------------------- */
.alert-strip {
  box-shadow: var(--mat-shadow-pop), inset 0 1px 0 rgba(255, 255, 255, 0.5);
}

@media (prefers-reduced-motion: reduce) {
  .sd-quick-card:active,
  .sd-continue-row:active,
  .sd-remind-item:active { transform: none; }
}

/* ============================================================
   EKRAN OKUYUCUYA OZEL METIN — .nb-sr-only
   ============================================================
   Bu kural components.css'ten BURAYA tasindi.

   Sebep: _Pager.cshtml paylasilan bir partial'dir ve tanitim sitesinde de
   (Home/Courses, Home/News, Home/Teachers) kullanilir. components.css'i ise
   yalnizca panel duzenleri yukler — tanitim sitesi bilerek yuklemez, cunku
   kendi .course-card'i marketing.css'te tanimli ve iki dosya carpisirdi.

   Sonuc: kuralin bulunmadigi tanitim sitesinde sayfalayicinin "daha fazla
   sayfa" aciklamasi GORUNUR metin olarak ciziliyor ve ziyaretci sayfa
   numaralarinin arasinda "صفحات أخرى" yazisini okuyordu.

   material.css BES duzenin de (tanitim, auth, admin, ogrenci, ogretmen)
   yukledigi tek dosyadir; paylasilan bir partial'in kurali da orada durmali.
   ============================================================ */
.nb-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   GORSEL ON IZLEMESI (algilanan hiz)
   <img nb-media> -> MediaImageTagHelper sunucuda su ikisini basar:
     style="background-color:#.."  gorselin ORTALAMA rengi
     data-bh="..."                 28 karakterlik BlurHash

   Birincisi JavaScript olmadan da calisir: tarayici HTML'i okur okumaz
   kutu gorselin kendi renginde dolar, boz gri dikdortgen kalmaz.
   Ikincisini media.js bir canvas uzerinde cozup ayni <img>'in arka plan
   GORSELI yapar; asagidaki kurallar o arka planin nasil yerlesecegini
   soyler. Renk satir ici yazilir (her gorselde farklidir), yerlesim
   kurallari burada (hepsinde aynidir).

   Gorsel indiginde kendi pikselleri arka planin ustunu orter; media.js
   de arka plani birakir.

   material.css BES duzenin de yukledigi tek dosyadir — kural burada.
   ============================================================ */
img.nb-ph {
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

/* ============================================================
   Profil fotografi (Helpers/AvatarHtml)
   ============================================================
   Baş harf dairesinin (her ekranda kendi sinifi/rengi/olcusu olan kap)
   ICINE fotograf konunca kabi doldurur ve kabin yuvarlak kenarini izler.
   Kabin kendisi degismez; bu yuzden kural kap sinifina degil <img>'e bagli. */
img.av-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

/* Kucuk yuvarlak fotograf (satir ici, "Ogretmen: ad" gibi satirlarin basinda). */
.nb-mini-av {
  display: inline-block;
  width: 26px; height: 26px; flex-shrink: 0;
  vertical-align: middle;
  border-radius: 50%;
  overflow: hidden;
}
