/* ============================================================================
 * mobile.css — Mektepa mobil deneyim katmanı
 * ============================================================================
 * AMAÇ: Tarayıcıda açılan bir web sayfası gibi değil, YERLEŞİK (native) bir
 * uygulama gibi hissettirmek.
 *
 * ⚠️ MASAÜSTÜ KURALI — BU DOSYADAKİ HER KURAL `lg` KIRILIMININ (1024px) ALTINA
 *    KAPSANMIŞTIR. 1024px ve üzerinde HİÇBİR ŞEY DEĞİŞMEZ. Kapsam dışına
 *    kural yazmayın; masaüstü düzeni bu projede referans tasarımdır.
 *
 * Kapsanan sorunlar (mobile-audit.js ile ÖLÇÜLDÜ):
 *   • 212 sayfada 32px altı dokunma hedefi
 *   • iOS'ta 16px altı input'a dokununca sayfanın otomatik yakınlaşması
 *   • Dokununca çıkan gri flaş (native uygulamada yoktur)
 *   • Yatay kaydırılabilir şeritlerde "devamı var" ipucunun olmaması
 *   • Çentikli cihazlarda alt/üst güvenli alanın yok sayılması
 * ========================================================================= */

@media (max-width: 1023.98px) {

  /* ── 1) Temel dokunma davranışı ─────────────────────────────────────────
     tap-highlight: Android/iOS'ta dokununca beliren gri dikdörtgen web
     hissiyatının en belirgin işaretidir; kaldırılıp yerine gerçek bir
     :active durumu verilir.
     touch-action: manipulation → çift dokunma ile yakınlaştırmayı kapatır,
     böylece 300ms tıklama gecikmesi de ortadan kalkar. */
  a, button, [role="button"], label, summary,
  input, select, textarea {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
  }

  /* Cihaz yatay-dikey döndüğünde iOS yazı boyutunu kendiliğinden büyütür;
     düzen kayar. Kapat. */
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

  /* Basılı tutunca çıkan metin seçimi/mavi vurgu — düğmelerde istenmez. */
  button, [role="button"], .no-select {
    -webkit-user-select: none; user-select: none;
  }

  /* Dokununca anlık geri bildirim (native "press" hissi). */
  button:active, a:active, [role="button"]:active { opacity: .72; }


  /* ── 2) iOS otomatik yakınlaştırma ─────────────────────────────────────
     Safari, yazı boyutu 16px'ten KÜÇÜK bir alana odaklanınca sayfayı
     zorla yakınlaştırır ve geri çıkmaz — uygulamanın "web sitesi" gibi
     hissettiren en büyük tek sebebi budur.
     Tailwind'in text-sm/text-xs sınıfları 14px/12px olduğu için tüm form
     alanları etkileniyordu. Görsel boyutu korumak için transform DEĞİL,
     doğrudan 16px veriyoruz — mobilde zaten daha okunaklı. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
  select,
  textarea {
    font-size: 16px !important;
    line-height: 1.4;
  }


  /* ── 3) Dokunma hedefi büyütme ─────────────────────────────────────────
     WCAG 2.5.8 (AA) asgari 24×24px ister; Apple 44pt, Google 48dp önerir.
     Görsel büyüklüğü şişirmeden hedefi büyütmek için ::after ile görünmez
     bir "dokunma zarfı" serilir — düzen HİÇ kaymaz. */
  .tap-pad { position: relative; }
  .tap-pad::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: max(100%, 44px); height: max(100%, 44px);
  }

  /* İkon-yalnız düğme/bağlantılar → en az 40px.
     ⚠️ YALNIZ KARE olanlar (h-7 VE w-7 / h-8 VE w-8). Sadece `h-8`e bakmak
     metinli sekmeleri de yakalıyordu; min-width:40px onları şişirip sarmayan
     bir flex satırında taşırıyor ve üst üste bindiriyordu
     (/admin/product sekmeleri 5-8px çakışma). */
  main a[class*="h-7"][class*="w-7"],  main button[class*="h-7"][class*="w-7"],
  main a[class*="h-8"][class*="w-8"],  main button[class*="h-8"][class*="w-8"],
  main a[class*="h-9"][class*="w-9"],  main button[class*="h-9"][class*="w-9"] {
    min-width: 40px; min-height: 40px;
  }

  /* Chip "×" gibi çok küçük düğmelerde görünmez dokunma zarfı (düzen kaymaz). */
  main button[class*="h-4"], main button[class*="h-5"],
  main a[class*="h-4"],      main a[class*="h-5"] { position: relative; }
  main button[class*="h-4"]::after, main button[class*="h-5"]::after,
  main a[class*="h-4"]::after,      main a[class*="h-5"]::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: max(100%, 40px); height: max(100%, 40px);
  }

  /* Onay kutusu / radyo: GÖRSEL BOYUT DEĞİŞTİRİLMEZ, yalnız dokunma zarfı büyür.
     DENENDI VE GERİ ALINDI: 16px → 20px yapmak sıkışık listelerde (mesaj alıcı
     ağacı, ders dağıtım seçimi) komşu öğelerle ÇAKIŞMA yarattı — ölçüm:
     çakışan sayfa 8 → 14. Görünmez ::after zarfı ise düzeni hiç bozmadan
     dokunma alanını 44px'e çıkarır; asıl kullanılabilirlik kazancı zaten odur. */
  input[type="checkbox"], input[type="radio"] { position: relative; }
  input[type="checkbox"]::after, input[type="radio"]::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }

  /* Onay kutusunu saran <label> tıklama alanı da rahatlasın. */
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) { min-height: 40px; }

  /* Chip/etiket içindeki "×" kaldır düğmeleri (ölçülen: 8×20px). */
  button[class*="text-"]:not([class*="px-"]):not([class*="w-"]) { min-width: 32px; min-height: 32px; }

  /* Boyut sınıfı HİÇ olmayan çıplak düğmeler (ölçülen 8×20 / 80×15).
     PHP'de Tailwind boyut sınıfı vermek MASAÜSTÜNÜ DE değiştiriyordu
     (desktop-guard.js yakaladı: /admin/service-providers 8x20 → 24x24).
     Bu yüzden şablona yalnız İŞLEVSİZ bir kanca sınıfı eklendi; ölçü
     burada, 1024px altında veriliyor. `chip-x` = çip içindeki kaldır,
     `tap-grow` = dar metin düğmesi. */
  .chip-x {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border-radius: 9999px; line-height: 1;
  }
  .tap-grow { min-height: 24px; padding-top: 4px; padding-bottom: 4px; }


  /* ── 4) Yatay kaydırılabilir şeritler ──────────────────────────────────
     Sekme/filtre şeritleri mobilde yana kaydırılabiliyor ama iOS kaydırma
     çubuğunu gizlediği için kullanıcı DEVAMI OLDUĞUNU ANLAMIYOR.
     Sağ kenara yumuşak bir solma maskesi + parmak bırakınca hizalanan
     kaydırma (snap) eklenir — native sekme şeridi hissi. */
  .overflow-x-auto, .table-scroll {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .overflow-x-auto::-webkit-scrollbar { display: none; }

  /* Solma yalnız GERÇEKTEN taşan şeritlere uygulanır — JS `data-scrollable`
     işaretini koyar (bkz. footer.php initMobileScrollers). */
  [data-scrollable="1"] {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  }
  [data-scrollable="end"] { -webkit-mask-image: none; mask-image: none; }

  [data-snap] { scroll-snap-type: x proximity; }
  [data-snap] > * { scroll-snap-align: start; }


  /* ── 5) Çentik / ev düğmesi güvenli alanı ──────────────────────────────
     Alt sabit çubuklar iPhone'un ana ekran çizgisinin altında kalıyordu. */
  .safe-bottom { padding-bottom: max(env(safe-area-inset-bottom), 0px); }
  .safe-top    { padding-top:    max(env(safe-area-inset-top), 0px); }


  /* ── 6) Yapışkan alt eylem çubuğu ──────────────────────────────────────
     Uzun formlarda "Kaydet" sayfanın en altında kalıyor; kullanıcı her
     seferinde sonuna kadar kaydırmak zorunda. Native uygulamalarda birincil
     eylem hep erişilebilir olur. */
  .mobile-action-bar {
    position: sticky; bottom: 0; z-index: 30;
    margin: 0 -1rem -1.5rem;
    padding: .75rem 1rem calc(.75rem + max(env(safe-area-inset-bottom), 0px));
    background: rgba(255, 255, 255, .92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-top: 1px solid rgb(228 228 231);
  }
  .dark .mobile-action-bar,
  html.dark .mobile-action-bar {
    background: rgba(24, 24, 27, .92);
    border-top-color: rgb(39 39 42);
  }
  .mobile-action-bar > * { width: 100%; justify-content: center; }


  /* ── 6b) Grid/flex çocuklarının daralabilmesi ──────────────────────────
     YATAY TAŞMANIN EN YAYGIN SEBEBİ. Flex ve grid çocukları varsayılan olarak
     `min-width: auto` alır: içeriğinin "min-content" genişliğinin ALTINA
     inemezler. Uzun bir başlık, kırılmayan bir slug ya da sığmayan bir buton
     satırı bu yüzden kapsayıcıyı — dolayısıyla SAYFAYI — yana kaydırır.
     `min-width: 0` bu kilidi açar; içerik sarar, sayfa yerinde kalır.
     (Ölçüldü: /admin/scholarship-scoring +329px, /admin/transport +375px.)

     Yalnız mobilde uygulanır; masaüstünde sütun genişlikleri kasıtlıdır.

     ⚠️ KONTROLLER HARİÇ. Kuralı `.flex > *` diye geniş yazmak, sekme
     bağlantılarını ve filtre kutularını da sıfıra kadar ezdi; kutu küçüldü
     ama İÇİNDEKİ YAZI taştı ve komşunun üstüne bindi (ölçüm: çakışan sayfa
     4 → 8; /admin/product sekmeleri 5-8px üst üste). Bir buton/bağlantı
     satırı sığmıyorsa doğru çözüm `flex-wrap`tır, ezmek değil.

     ⚠️ `li` DE HARİÇ. Sekme/menü şeritlerinde <li> bir sarmalayıcıdır ve
     içindeki <a> daralmaz: <li> 0'a ezilince <a> dışarı taşıp komşunun
     üstüne biner (ölçüldü: <li> 51px iken içindeki <a> 77px → 22px çakışma).
     Şerit zaten `overflow-x-auto` içinde; doğru davranış YANA KAYMAKTIR.

     ⚠️ `min-w-*` YAZILMIŞ öğeler HARİÇ. Yazar oraya bilerek bir alt sınır
     koymuştur; ezmek arama kutusunu 192px'ten 24px'e düşürüyordu
     (/admin/assets filtre çubuğu). */
  main .flex > *:not(a):not(button):not(input):not(select):not(textarea):not(label):not(li):not([class*="min-w-"]),
  main .grid > *:not([class*="min-w-"]) { min-width: 0; }

  /* Tek sütuna düşen düzen ızgaraları gerçekten daralabilsin:
     `auto` iz min-content'e göre büyür, `minmax(0,1fr)` büyümez. */
  main [class*="lg:grid-cols-["],
  main [class*="lg:grid-cols-2"],
  main [class*="lg:grid-cols-3"] { grid-template-columns: minmax(0, 1fr); }

  /* ── 7) Tablolar ───────────────────────────────────────────────────────
     BURAYA `min-width: max-content` YAZMAYIN. Denendi ve GERİ ALINDI:
     tablo doğal genişliğine zorlanınca, kaydırılabilir sarmalayıcı içinde
     bile üst kapsayıcının min-content genişliğini büyütüyor ve sayfa daha
     çok yana kayıyordu (/admin/subscription taşması +193px → +304px).
     Tailwind'in `w-full` + `overflow-x-auto` ikilisi zaten doğru davranıyor.

     `overflow-wrap: anywhere` DENENDI VE GERİ ALINDI: taşmayı çözüyordu ama
     "ERKEK" gibi kısa başlıkları "ER / KE / K" diye kelime ortasından kırıyor,
     tablo okunmaz hâle geliyordu. Doğru çözüm tabloyu EZMEK değil YATAY
     KAYDIRMAKTIR — sarmalayıcı JS ile eklenir (footer.php: wrapTables). */
  main td, main th { overflow-wrap: break-word; }

  /* Otomatik eklenen kaydırma sarmalayıcısı */
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .table-scroll::-webkit-scrollbar { display: none; }
  .table-scroll > table { min-width: max-content; }

  /* TIKLANABİLİR GRAFİK dar ekranda ezilmesin.
     SVG `w-full` ile ölçeklenince sütunlar (her biri bir puan aralığına
     filtreleyen bağlantı) 720 birimden 18px'e iniyordu — WCAG 2.5.8 altı.
     Tablolarla aynı çözüm: grafik doğal ölçeğinde kalır, kap yana kaydırılır. */
  .chart-scroll { -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; }
  .chart-scroll > svg { min-width: 720px; }


  /* ── 8) Diyalog → ALTTAN AÇILAN SAYFA (bottom sheet) ───────────────────
     Native uygulamalarda onay/uyarı ekranın ortasında yüzen küçük bir kutu
     değil, alttan yukarı kayan geniş bir yapraktır. Başparmakla erişilir,
     düğmeleri tam genişliktir. SweetAlert2'nin kendi kabuğu yeniden biçimlenir.
     Masaüstünde SweetAlert varsayılan ortalı kutusu olarak kalır. */
  .swal2-container.swal2-center > .swal2-popup {
    position: fixed; left: 0; right: 0; bottom: 0;
    width: 100%; max-width: 100%;
    margin: 0;
    border-radius: 22px 22px 0 0;
    padding: 20px 18px calc(18px + max(env(safe-area-inset-bottom), 0px));
  }

  /* ⚠️ ANIMASYON DURUMA GÖRE AYRILMALI — YOKSA DIYALOG HIC KAPANMAZ.
     SweetAlert2 kapanirken popup'a `.swal2-hide` ekler ve `animationend`
     BEKLER; olay gelmezse kabi DOM'dan KALDIRMAZ. Animasyon burada
     durumsuz (`.swal2-popup` uzerinde) yazilmisti: ozgullugu (0,3,0)
     SweetAlert'in kendi `.swal2-hide` kuralini (0,1,0) eziyor, animasyon
     ADI DEGISMIYOR, acilista biten `mektepaSheetUp` yeniden tetiklenmiyor →
     `animationend` HIC gelmiyor.
     SONUC: mobilde her onay/uyari penceresi kapanmaz, `body{overflow:hidden}`
     ve tam ekran `.swal2-container` kalir → SAYFA TAMAMEN KILITLENIR.
     (`sweetalert-custom.css` yalnizca tanitim sitesinde yukleniyor; onun
     `!important`li hide kurali uygulamayi KURTARMIYOR.)
     Dogrusu: acilis ve kapanis AYRI animasyon adlariyla. */
  .swal2-container.swal2-center > .swal2-popup.swal2-show {
    animation: mektepaSheetUp .26s cubic-bezier(.32, .72, 0, 1);
  }
  .swal2-container.swal2-center > .swal2-popup.swal2-hide {
    animation: mektepaSheetDown .2s cubic-bezier(.32, 0, .67, 0) forwards;
  }
  @keyframes mektepaSheetUp {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }
  @keyframes mektepaSheetDown {
    from { transform: translateY(0); }
    to   { transform: translateY(100%); }
  }

  /* Üstte tutamaç çizgisi — "yukarı kaydı" işareti (iOS/Android sheet dili). */
  .swal2-container.swal2-center > .swal2-popup::before {
    content: ""; display: block;
    width: 38px; height: 4px; margin: -6px auto 14px;
    border-radius: 999px; background: rgb(212 212 216);
  }
  html.dark .swal2-container.swal2-center > .swal2-popup::before { background: rgb(63 63 70); }

  /* Eylemler tam genişlik ve dikey — başparmak erişimi. Onay ÜSTTE. */
  .swal2-actions {
    width: 100%; flex-direction: column-reverse; gap: 8px; margin-top: 18px;
  }
  .swal2-actions > button { width: 100%; margin: 0 !important; min-height: 46px; }

  .swal2-title { font-size: 1.0625rem; padding: 0 0 4px; }
  .swal2-html-container { margin: 0; font-size: .9375rem; }

  /* İkon küçülür: sayfanın yarısını kaplamasın, metin öne çıksın. */
  .swal2-icon { width: 52px; height: 52px; margin: 4px auto 12px; border-width: 3px; }
  .swal2-icon .swal2-icon-content { font-size: 1.9rem; }
  .swal2-icon.swal2-success [class^='swal2-success-line'] { height: 4px; }


  /* ── 9) Kaydırma performansı ───────────────────────────────────────────
     Gövde aşırı-kaydırma zincirini kes (arka planın da kaymasını önler). */
  body { overscroll-behavior-y: contain; }


  /* ── 10) ALT GEZİNME ÇUBUĞU (bottom tab bar) ───────────────────────────
     Yerleşik uygulama hissinin belirleyici öğesi. Birincil hedefler
     başparmağın doğal eriştiği alt şeritte; hamburger açmaya gerek yok.
     Bkz. app/includes/mobile-nav.php */
  .mobile-tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    display: flex; align-items: stretch;
    background: rgba(255, 255, 255, .94);
    backdrop-filter: blur(14px) saturate(1.4);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    border-top: 1px solid rgb(228 228 231);
    padding-bottom: max(env(safe-area-inset-bottom), 0px);
  }
  html.dark .mobile-tabbar {
    background: rgba(24, 24, 27, .94);
    border-top-color: rgb(39 39 42);
  }

  .mobile-tab {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 3px;
    padding: 8px 2px 7px;
    color: rgb(113 113 122);
    font-size: 10px; font-weight: 800; line-height: 1;
    background: none; border: 0;
    text-decoration: none;
    transition: color .15s;
  }
  html.dark .mobile-tab { color: rgb(161 161 170); }

  .mobile-tab__icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 9px;
    transition: background-color .15s, transform .15s;
  }
  .mobile-tab__icon svg { width: 20px; height: 20px; }
  .mobile-tab__label {
    max-width: 100%; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap;
  }

  /* Aktif sekme: marka rengi + yumuşak arka plan (iOS/Android tab davranışı) */
  .mobile-tab.is-active { color: rgb(79 70 229); }
  html.dark .mobile-tab.is-active { color: rgb(165 180 252); }
  .mobile-tab.is-active .mobile-tab__icon {
    background: rgb(238 242 255);
    transform: translateY(-1px);
  }
  html.dark .mobile-tab.is-active .mobile-tab__icon { background: rgba(67, 56, 202, .28); }

  .mobile-tab:active .mobile-tab__icon { transform: scale(.9); }

  /* İçerik alt çubuğun ARKASINDA kalmasın — yükseklik + güvenli alan kadar boşluk. */
  main { padding-bottom: calc(62px + max(env(safe-area-inset-bottom), 0px)); }

  /* Yapışkan form eylem çubuğu alt gezinmenin ÜSTÜNE otursun. */
  .mobile-action-bar { bottom: calc(62px + max(env(safe-area-inset-bottom), 0px)); }


  /* ── 11) Üst çubuk: kaydırınca inceleşsin ──────────────────────────────
     Native uygulamalarda başlık kaydırma ile daralır ve içeriğe yer açar. */
  header.lg\:hidden {
    transition: box-shadow .2s, background-color .2s;
  }
  body.is-scrolled header.lg\:hidden {
    box-shadow: 0 1px 12px rgb(0 0 0 / .07);
    background: rgba(255, 255, 255, .92);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }
  html.dark body.is-scrolled header.lg\:hidden { background: rgba(9, 9, 11, .92); }


  /* ── 12) Liste satırları: rahat ve dokunulabilir ───────────────────────
     Native listelerde satırlar yüksek, dokunma alanı geniş, ayraç incedir.
     Yalnız GERÇEK liste kalıplarını hedefler (ul.divide-y > li > a). */
  main ul[class*="divide-y"] > li > a,
  main ul[class*="divide-y"] > li > button {
    min-height: 56px;
  }

  /* ÖLÜ KURAL KALDIRILDI (kod taramasıyla bulundu):
       main [class*="sm:grid-cols-2"]:not([class*="grid-cols-2"]) { … }
     `[class*=...]` ham ALT DİZE eşleşmesidir ve "sm:grid-cols-2" dizesi zaten
     "grid-cols-2" içerir → sol tarafı sağlayan her öğe :not() koşulunu da
     sağlar, negasyon ASLA geçmez. Kural hiçbir zaman uygulanmadı.
     `~=` ile canlandırmak KASITLI OLARAK yapılmadı: Tailwind'de `sm:` 640px'tir,
     yani kural yalnız 640-1023px bandında etkir ve oradaki 147 kartlı ızgarayı
     tek sütuna indirirdi — bu bir hata düzeltmesi değil, tasarım kararıdır. */


  /* ── 13) Odaklanan alan klavyenin altında kalmasın ─────────────────────
     Sanal klavye açılınca alan görünür bölgeye kaydırılır (JS: footer.php). */
  main :is(input, select, textarea):focus { scroll-margin-block: 96px; }


  /* ── 14) Görsel/embed taşmasın ─────────────────────────────────────────── */
  main img, main svg, main video, main iframe, main canvas { max-width: 100%; }
  main pre, main code { overflow-x: auto; overflow-wrap: anywhere; }


  /* ── 14b) Yoğun satır kalıpları: dokunulabilir çipler ──────────────────
     ÖLÇÜM (/admin/rooms): tek ekranda 157 adet 32px altı hedef. Satır zaten
     94px yüksek — sorun yükseklik değil, İÇİNDEKİ küçük öğeler:
       oda adı bağlantısı 84×24 · "sınıf ata" 68×21 · "sınav" 64×21
     Satır yapısını değiştirmeden bu üç öğe gerçek dokunma hedefine çıkarılır.
     Kapsam `.room-row` — başka hiçbir yeri etkilemez. */
  main .room-row a,
  main .room-row button:not([class*="w-8"]):not([class*="w-7"]) {
    min-height: 40px;
    display: inline-flex; align-items: center;
  }
  /* ODA ADI TAM GENİŞLİK, tür çipi ALT SATIRA.
     Aşama 1'de `width:100%` denendi → flex satırında çiple yer kavgasına girip
     bağlantıyı 9px'e ezdi. Aşama 2'de `flex:1 1 auto` denendi → bu sefer çip
     yer kapladığı için ad kırpıldı ("Ahşap At…", "R"). Dokunma hedefini
     büyütmek uğruna ADIN OKUNMAMASI kabul edilemez.
     Doğrusu: satır sarsın, ad tek başına tam genişlik alsın. */
  main .room-row a.truncate { min-height: 40px; flex: 1 0 100%; min-width: 0; }
  main .room-row a.truncate + span { margin-top: -.25rem; }

  /* Ad satırı sarabilsin (çip alt satıra insin) */
  main .room-row .items-center.gap-2 { flex-wrap: wrap; }

  /* Meta çipleri: dokunulabilir AMA satır israfı yapmayacak kadar sıkı.
     .5rem/.75rem denendi → "SINAV" alt satıra düştü, satır 180px oldu. */
  main .room-row .rounded-md {
    min-height: 34px;
    padding-top: .3125rem; padding-bottom: .3125rem;
    padding-left: .5rem; padding-right: .5rem;
  }
  main .room-row .gap-x-2\.5 { gap: .375rem .375rem; }
  main .room-row { padding-top: .625rem; padding-bottom: .625rem; }

  /* Yoğun satırda onay kutusu: görünmez zarf komşu bağlantının ALTINDA kalıyor
     (kardeş sonra boyanıyor), o yüzden burada GERÇEK boyut büyütülür.
     24px = WCAG 2.5.8 (AA) asgari dokunma hedefi. */
  main .room-row input[type="checkbox"],
  main summary input[type="checkbox"] {
    width: 24px; height: 24px; margin-right: 4px;
  }

  /* Grup başlığı (bina/kat) satırındaki öğeler de dokunulabilir olsun. */
  main summary a, main summary button { min-height: 40px; min-width: 40px;
    display: inline-flex; align-items: center; justify-content: center; }
  main summary { min-height: 52px; }


  /* ── 14c) Zengin metin editörü (TinyMCE) ──────────────────────────────
     Araç çubuğu düğmeleri 34×28px geliyor. İşaretleme üçüncü tarafın ama
     STİL bizim sayfamızda — dokunma hedefine çıkarılabilir.
     (Düğme SAYISI ayrıca yapılandırmadan 31 → 11'e indirildi; bkz.
      admin-contract-template.php / admin-communications.php) */
  .tox .tox-tbtn { min-height: 40px !important; min-width: 40px !important; }
  .tox .tox-toolbar__group { padding: 2px 4px !important; }

  /* Sözleşme şablonundaki {{değişken}} çipleri (ölçülen 91×25) */
  .placeholder-pill { min-height: 36px; padding: .375rem .625rem; }


  /* ── 15) FİLTRE PANELİ → düğme + alttan açılan sayfa ───────────────────
     ÖLÇÜLEN SORUN: 57 liste sayfasının 21'inde ilk ekranda HİÇ VERİ YOK.
     Başlık + açıklama + buton satırı + filtre formu 750-1400px yer kaplıyor,
     kullanıcı listeyi görmek için kaydırmak zorunda kalıyor. Filtre formları
     tek başına 300-440px.

     Yerleşik uygulama kalıbı: LİSTE ÖNCE gelir, filtre bir düğmenin
     arkasındadır ve kaç filtrenin etkin olduğu rozetle bildirilir.
     (JS: footer.php → initMobileFilters) */

  .mfilter-trigger {
    display: flex; align-items: center; gap: 8px;
    width: 100%; margin-bottom: 12px;
    padding: 11px 14px;
    border: 2px solid rgb(228 228 231); border-radius: 14px;
    background: #fff; color: rgb(63 63 70);
    font-size: 14px; font-weight: 800; text-align: left;
  }
  html.dark .mfilter-trigger { background: rgb(24 24 27); border-color: rgb(39 39 42); color: rgb(228 228 231); }
  /* DİKKAT: `display: inline-flex`, [hidden] özniteliğinin `display:none`
     kuralını EZER. Rozet 0 iken gizlenmiyordu; !important şart. */
  .mfilter-trigger .mfilter-count[hidden] { display: none !important; }
  .mfilter-trigger .mfilter-count {
    margin-left: auto;
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 22px; height: 22px; padding: 0 7px;
    border-radius: 999px; background: rgb(79 70 229); color: #fff;
    font-size: 11px; font-weight: 900;
  }
  .mfilter-trigger .mfilter-chev { margin-left: auto; opacity: .45; }
  .mfilter-trigger .mfilter-count + .mfilter-chev { margin-left: 6px; }

  /* Alttan açılan filtre yaprağı */
  .mfilter-sheet {
    position: fixed; inset: 0; z-index: 60;
    display: none;
  }
  .mfilter-sheet.is-open { display: block; }
  .mfilter-sheet__scrim {
    position: absolute; inset: 0;
    background: rgb(0 0 0 / .42);
    animation: mektepaFade .2s ease;
  }
  @keyframes mektepaFade { from { opacity: 0 } to { opacity: 1 } }

  .mfilter-sheet__panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    max-height: 88vh; overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: #fff;
    border-radius: 22px 22px 0 0;
    padding: 10px 16px calc(16px + max(env(safe-area-inset-bottom), 0px));
    animation: mektepaSheetUp .26s cubic-bezier(.32, .72, 0, 1);
  }
  html.dark .mfilter-sheet__panel { background: rgb(24 24 27); }

  .mfilter-sheet__panel::before {
    content: ""; display: block;
    width: 38px; height: 4px; margin: 0 auto 12px;
    border-radius: 999px; background: rgb(212 212 216);
  }
  html.dark .mfilter-sheet__panel::before { background: rgb(63 63 70); }

  .mfilter-sheet__head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px;
  }
  .mfilter-sheet__title { font-size: 15px; font-weight: 900; }
  .mfilter-sheet__clear {
    font-size: 13px; font-weight: 800; color: rgb(79 70 229);
    background: none; border: 0; padding: 6px 4px;
  }

  /* Yaprağın içindeki form alanları dikey ve tam genişlik — dokunmaya uygun. */
  .mfilter-sheet__panel form { display: block; }
  .mfilter-sheet__panel form > * { width: 100%; margin-bottom: 10px; }
  .mfilter-sheet__panel select,
  .mfilter-sheet__panel input { width: 100%; }

  /* Sayfa arkada kaymasın */
  body.mfilter-open { overflow: hidden; }

  /* ==========================================================================
   * ÖĞRENCİLER — toplu işlem kartı LİSTEDEN SONRAYA
   * ==========================================================================
   * "1.803 filtreye uyan öğrenciyi bir döneme idari olarak kaydet" kartı
   * listeden ÖNCE 136px yiyordu. Yerleşik uygulamalarda toplu/yıkıcı işlem
   * içeriğin ÜSTÜNDE durmaz — kullanıcı önce listeyi görür.
   *
   * DOM TAŞIMASI YAPILMIYOR: form `submit()` ile gönderiliyor ve içindeki
   * gizli alanlar id ile okunuyor; JS ile taşımak kırılgan olurdu. Kapsayıcı
   * `:has()` ile YALNIZ bu sayfada flex kolona çevrilip form en sona alınıyor.
   * `:has()` desteklenmezse kural komple düşer → eski (çalışan) düzen kalır. */
  main div:has(> #enrollAllForm) { display: flex; flex-direction: column; }
  main #enrollAllForm { order: 99; margin: 12px 0 0; }

  /* ==========================================================================
   * ÖĞRENCİ KARTLARI — mobilde GALERİ değil LİSTE SATIRI
   * ==========================================================================
   * ÖLÇÜM: 2 sütunlu foto galerisi kart başına ~215px → ekranda 2 öğrenci.
   * iOS'ta kişi/öğrenci listesi tek sütun "table view" satırıdır
   * (yuvarlak avatar + ad + alt satır + sondaki eylem), ~72px → 8-9 kayıt.
   *
   * TAMAMEN CSS: PHP şablonu değişmiyor, hiçbir düğme kaybolmuyor.
   * Foto kutusunun `position:relative`i devre dışı bırakılıp `article`
   * konumlanma bağlamı yapılıyor; böylece fotoğrafın üstündeki eylem grubu
   * (kamera/kalem/kesin kayıt) satırın SAĞ kenarına geçiyor.
   *
   * NOT: `$classFilter > 0` iken bu kartlar masaüstünde de görünür; sorun
   * değil — tüm kurallar 1024px altına kapsanmış durumda. */
  main [data-stu-cards] {
    display: block;
    padding: 0;
  }
  main [data-stu-cards] > article {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 68px;
    padding: 8px 96px 8px 10px;   /* sağda eylem düğmelerine yer */
    border-width: 0 0 1px 3px;    /* soldaki 3px = cinsiyet rengi şeridi */
    border-radius: 0;
  }
  main [data-stu-cards] > article:last-child { border-bottom-width: 0; }

  /* Foto: 44px genişlik, 3/4 oran korunur (aspect-[3/4] sınıfı sürüyor). */
  main [data-stu-cards] > article > div:first-child {
    position: static;             /* eylem grubu article'a göre konumlansın */
    width: 44px;
    flex: none;
    border-radius: 9px;
    overflow: hidden;
  }
  main [data-stu-cards] > article > div:first-child i { width: 22px; height: 22px; }

  /* Bilgi bloğu: 1. satır ad, 2. satır rozet + sınıf + durum + telefon. */
  main [data-stu-cards] > article > div:last-child {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px 6px;
    padding: 0;
  }
  main [data-stu-cards] > article > div:last-child > a:first-child {
    flex: 1 0 100%;
    min-width: 0;
    padding: 2px 0;
  }
  /* TÜM SATIR dokunulabilir (iOS table view kuralı: hedef satırın kendisidir,
     içindeki 176px'lik ad değil). Ad bağlantısı görünmez bir katmanla satırı
     kaplar; eylem düğmeleri z-index ile üstte kalır. */
  main [data-stu-cards] > article > div:last-child > a:first-child::before {
    content: ""; position: absolute; inset: 0; z-index: 1;
  }
  main [data-stu-cards] > article > div:first-child > div.absolute,
  main [data-stu-cards] > article > div:first-child > button.absolute { z-index: 2; }
  main [data-stu-cards] > article:active { background: rgb(244 244 245); }
  html.dark main [data-stu-cards] > article:active { background: rgb(39 39 42); }
  main [data-stu-cards] > article h3 { font-size: 15px; }
  main [data-stu-cards] > article > div:last-child > p { order: 9; font-size: 11px; }

  /* Eylem grubu: fotoğrafın üstünden satırın sağ kenarına.
     Beyaz+gölge renk fotoğraf üzerinde okunuyordu; satır zemininde
     görünmez olurdu → koyu griye çevriliyor ve dokunma hedefi 40px. */
  main [data-stu-cards] > article > div:first-child > div.absolute,
  main [data-stu-cards] > article > div:first-child > button.absolute {
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    gap: 2px;
  }
  main [data-stu-cards] > article .stu-photo-lbl,
  main [data-stu-cards] > article > div:first-child a[href*="student-edit"],
  main [data-stu-cards] > article > div:first-child a[href*="enrollment-wizard"],
  main [data-stu-cards] > article > div:first-child button.absolute {
    width: 38px; height: 38px;
    border-radius: 11px;
    color: rgb(82 82 91);
    filter: none;
    background: rgb(244 244 245);
  }
  html.dark main [data-stu-cards] > article .stu-photo-lbl,
  html.dark main [data-stu-cards] > article > div:first-child a[href*="student-edit"],
  html.dark main [data-stu-cards] > article > div:first-child a[href*="enrollment-wizard"],
  html.dark main [data-stu-cards] > article > div:first-child button.absolute {
    color: rgb(212 212 216);
    background: rgb(39 39 42);
  }
  /* Anlam taşıyan iki eylem yeşil kalır: "kesin kayda geçir" ve "geri yükle". */
  main [data-stu-cards] > article > div:first-child a[href*="enrollment-wizard"],
  main [data-stu-cards] > article > div:first-child button.absolute {
    color: rgb(4 120 87);
    background: rgb(209 250 229);
  }
  html.dark main [data-stu-cards] > article > div:first-child a[href*="enrollment-wizard"],
  html.dark main [data-stu-cards] > article > div:first-child button.absolute {
    color: rgb(110 231 183);
    background: rgb(6 78 59);
  }

  main [data-stu-cards] > article > div:first-child i[data-lucide="camera"],
  main [data-stu-cards] > article > div:first-child i[data-lucide="pencil"],
  main [data-stu-cards] > article > div:first-child i[data-lucide="file-signature"],
  main [data-stu-cards] > article > div:first-child i[data-lucide="archive-restore"] {
    width: 17px; height: 17px;
  }
}

/* Hareket azaltma tercihi — tüm cihazlarda geçerli (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
