/* ============================================================
 * piSPOR — ORTAK TEMEL
 * ============================================================
 *
 * piSPOR'un İKİ yüzü var:
 *
 *   panel      includes/header.php kullanan sayfalar (56 adet).
 *              Sol menü, üst çubuk, bildirim kutusu burada.
 *   panel dışı kendi <html>'ini açan sayfalar (28 adet): üye paneli,
 *              raporlar, karneler, başvuru formu, login, ödeme,
 *              yazdırma çıktıları. Velinin gördüğü yüzey büyük ölçüde
 *              burası.
 *
 * `pispor.css` yalnız BİRİNCİ yüze iniyor. Bu dosya İKİSİNE de iner ve
 * ortak temeli taşır.
 *
 * NEDEN GEREKLİ — ölçüldü
 *
 * Renk değişkenleri (--primary-color …) tanımlıydı ama yalnız 1 dosya
 * kullanıyordu. Aynı altı renk panel dışı sayfalara elle yazılmıştı:
 * #4e73df 35 dosyada, #1cc88a 21, #f8f9fc 17, #e74a3b 12. Değişkenler
 * panel dışına hiç inmediği için kullanılamıyordu; bu dosya onları
 * oraya taşıyor.
 *
 * İÇERİĞİ BİLEREK DAR
 *
 * Burada yalnız hiçbir sayfanın görünümünü DEĞİŞTİRMEYEN şeyler var:
 * özel değişkenler (kullanılmadıkça hiçbir etkisi yok) ve yalnız o
 * sınıfı taşıyan öğeyi etkileyen yazdırma yardımcıları.
 *
 * Genel bir `*` sıfırlaması ya da `body` kuralı buraya KONMADI: panel
 * dışı 28 sayfanın 13'ünde zaten kendi `*` kuralı var, 15'inde yok;
 * buraya konsaydı o 15 sayfanın görünümü sessizce değişirdi. Paylaşılan
 * tipografi ve kart/tablo bileşenleri, her ailenin ekran görüntüsü
 * karşılaştırılarak ayrı ayrı taşınacak.
 * ============================================================ */

:root {
    /* Panel iskeletinin ölçüleri pispor.css'te kalır (yalnız orada
       kullanılıyor); renkler her iki yüzeyde de lazım. */
    --primary-color: #4e73df;
    --secondary-color: #858796;
    --success-color: #1cc88a;
    --info-color: #36b9cc;
    --warning-color: #f6c23e;
    --danger-color: #e74a3b;

    /* Yüzey renkleri — panel dışı sayfalar da aynı tonu kullansın */
    --zemin-renk: #f8f9fc;
    --yazi-renk: #212529;
    --kenar-renk: #e3e6f0;

    /* --------------------------------------------------------
       TASARIM JETONLARI (Aşama 3)
       --------------------------------------------------------
       Panelde 1.886 çıplak renk değeri 90 dosyaya dağılmış
       durumda; aynı "gri"nin altı farklı tonu var (#6c757d 54,
       #f8f9fa 55, #e9ecef 27, #dee2e6 39…). Tek tek dolaşmak
       Aşama 2'nin işi; burada ADI KONUYOR: yeni yazılan her kural
       ve girilen her sayfa bu değişkenleri kullanır, çıplak hex
       yazılmaz. Değerler bugünkü kullanımın birebir aynısıdır —
       jetonların eklenmesi hiçbir sayfanın görünümünü değiştirmez.

       Adlandırma Türkçedir (kod tabanının geri kalanı gibi);
       yukarıdaki --*-color adları eski kurallarda kullanıldığı
       için duruyor, yenisi yazılmaz. */

    /* Yazı — panelde Bootstrap'in sistem yığını kullanılıyordu,
       panel dışı sayfaların bir kısmı Arial yazıyordu. Jeton ikisini
       tek yerde toplar. */
    --yazi-ailesi: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                   "Helvetica Neue", Arial, "Noto Sans", sans-serif,
                   "Apple Color Emoji", "Segoe UI Emoji";

    /* Yazı boyları — panelde fiilen kullanılan ölçek.
       Gövde 1rem = 16px; diğerleri buna göredir. Mobil karşılıkları
       ilgili bileşenin @media bloğunda durur (.page-title 1.05rem,
       .page-header .btn 0.72rem). */
    --yazi-baslik:    1.25rem;   /* .page-title */
    --yazi-govde:     1rem;      /* gövde metni */
    --yazi-kucuk:     0.875rem;  /* small, form-control-sm, etiket */
    --yazi-mini:      0.7rem;    /* rozet, kutu etiketi */
    --yazi-buton:     0.8rem;    /* .page-header .btn */
    --yazi-deger:     1.35rem;   /* .metric-value */
    --yazi-deger-sm:  1.05rem;   /* .metric-value-sm */

    /* Metin tonları */
    --yazi-soluk: #6c757d;          /* small.text-muted karşılığı */
    --yazi-koyu:  #1f2937;          /* rozet/kart üzeri koyu metin */

    /* Durum renklerinin OKUNAKLI çifti: açık zemin + koyu yazı.
       Çıplak `--success-color` üzerine beyaz yazı 2,17:1 veriyor; WCAG
       küçük metin için 4,5:1 ister. Aşağıdaki çiftler 5,7–7,4:1 arası.
       Ölçüldü 23.09.2026, bir okul yöneticisi "yeşil üzerindeki beyaz
       yazıyı okuyamıyorum" dedikten sonra. */
    --basari-acik:  #d1f4e5;   --basari-koyu:  #0a6847;   /* 5,77:1 */
    --tehlike-acik: #fde2de;   --tehlike-koyu: #8b1f14;   /* 7,43:1 */
    --uyari-acik:   #fdf3d7;   --uyari-koyu:   #6b4e04;   /* 6,99:1 */

    /* Yüzeyler */
    --kart-zemin:  #ffffff;
    --zemin-alt:   #f8f9fa;         /* şerit, tablo başlığı, pasif satır */
    --kenar-acik:  #e9ecef;
    --secili-zemin: #e7f1ff;        /* seçili/açık satır, seçili menü öğesi */

    /* Gri merdiveni — Bootstrap'in gri ölçeğinden fiilen kullanılanlar.
       Panelde en çok tekrar eden üç ton: #dee2e6 23 dosyada, #adb5bd 8,
       #495057 6. */
    --kenar-orta:  #dee2e6;         /* çizgi ve çerçeve */
    --yazi-orta:   #495057;         /* sekme etiketi, koyu gri metin */
    --simge-soluk: #adb5bd;         /* pasif ikon, sıralama oku */

    /* DURUM ŞERİTLERİ — "ödendi / eksik / ödenmedi" gibi satır ve rozet
       boyamaları. Bootstrap uyarı paletinin zemin+yazı çiftleri; aidat
       tablosu, bekleyen ödemeler ve ürün borçları aynı altı rengi
       4-11 dosyada elle yazıyordu. */
    --durum-olumlu-zemin:  #d4edda;
    --durum-olumlu-yazi:   #155724;
    --durum-uyari-zemin:   #fff3cd;
    --durum-uyari-yazi:    #856404;
    --durum-olumsuz-zemin: #f8d7da;
    --durum-olumsuz-yazi:  #721c24;
    --durum-olumsuz-koyu:  #f5c6cb; /* aynı satırın :hover'ı */
    --durum-bilgi-zemin:   #cff4fc; /* bilgi/bekleyen rozeti */
    --durum-bilgi-yazi:    #055160;
    --durum-notr-zemin:    #e2e3e5; /* pasif/kapsam dışı satır */

    /* Mor — ürün/satış tarafının rengi; Bootstrap paletinde karşılığı yok. */
    --mor-renk: #9c27b0;

    /* KARNE KİMLİĞİ (kullanıcı kararı) — lacivert + altın "belge"
       görünümü. Öğrenci karnesi ve sınav karnesi basılıp imzalanan,
       velinin sakladığı çıktılardır; panelin mavisi yerine bu diplomatik
       tonu kullanırlar ve bu bilinçlidir.
       İki sayfa iki AYRI lacivert yazıyordu (#1a365d ve #0d3b66);
       jeton ikisini birleştirir. Altının panelde karşılığı yoktu. */
    --karne-lacivert:      #1a365d;
    --karne-lacivert-acik: #2c5282;   /* başlık degradesinin açık ucu */
    --karne-altin:         #d69e2e;

    /* Köşe ve gölge — kart, kutu ve rozetlerde tek ölçü */
    --kose:        0.5rem;
    --kose-kucuk:  0.35rem;
    --golge-kart:  0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);

    /* Koyu lacivert yüzey: sol menü, rapor sayfalarının başlık şeridi,
       QR terminali. Aynı iki renk ve aynı degrade 12 dosyada birebir
       tekrarlanıyordu. */
    --koyu-zemin:     #1e2a3b;
    --koyu-zemin-alt: #0f1724;
    --koyu-degrade:   linear-gradient(135deg, #1e2a3b 0%, #0f1724 100%);

    /* Modal başlığındaki degrade (.modal-pispor) */
    --baslik-degrade: linear-gradient(135deg, #4e73df 0%, #224abe 100%);

    /* Birincil/başarı renginin koyu ucu — degradelerde ve :hover'da
       zaten kullanılıyordu, adı şimdi konuyor. */
    --primary-koyu: #224abe;
    --success-koyu: #17a673;
    --info-koyu:    #2c9faf;   /* degradelerin koyu ucu */
    --warning-koyu: #dda20a;
    --danger-koyu:  #be2617;        /* tehlike düğmesinin :hover'ı */
    --primary-acik: #bac8f3;        /* odaklanmış alanın kenarı */
    --primary-cok-acik: #eef2fd;    /* seçili satırın zemini */

    /* Odak halkası — alana tıklandığında/sekmeyle gelindiğinde çıkan
       renkli çerçeve. Panelde dört ayrı maviydi (bkz. .form-control). */
    --odak-halka: 0 0 0 0.2rem rgba(78, 115, 223, 0.25);

    /* GİRİŞ YÜZEYLERİNİN ZEMİNİ (kullanıcı kararı)
       login, şifremi unuttum, online ödeme, ödeme sonucu, PayTR
       yönlendirme ve lisans ekranı. Bu altı sayfa panel kabuğu
       olmadan, ortada tek kartla açılır; düz #f8f9fc zeminde kart
       boşlukta duruyordu ("çok çiğ kaldı"). Zemin modal
       başlıklarıyla aynı degradeye alındı — açık tema korunur,
       sayfa panelin diliyle konuşur. Rapor sayfaları ve veli
       paneli BU KAPSAMDA DEĞİL: onlar belge/içerik yüzeyi,
       --zemin-renk'te kalır. */
    --giris-degrade: linear-gradient(135deg, #4e73df 0%, #224abe 100%);
}

/* Yazdırmada gizlenecek öğeler. 9 sayfaya ayrı ayrı yazılmıştı; kural
   yalnız `.no-print` sınıfı taşıyan öğeyi etkiler, başka hiçbir şeye
   dokunmaz. */
/* ============================================================
 * MOBİLDE OKUNUR TABLO (.tablo-mobil)  —  JS'siz
 * ============================================================
 * Yazdırılabilir rapor sayfaları (öğrenci karnesi, yoklama raporu,
 * finansal rapor) `footer.php` kullanmaz: jQuery ve DataTables orada
 * YOKTUR. Mobil için o sayfalarda tablonun yanına elle ikinci bir kart
 * listesi yazılmıştı — aynı veri iki markup, biri düzeltilince diğeri
 * unutuluyordu.
 *
 * Bu desen tek tabloyu mobilde satır satır okunur hâle getirir: başlık
 * satırı gizlenir, her hücre "Etiket: değer" olarak alt alta dizilir.
 * Etiket hücrenin `data-etiket` özniteliğinden gelir.
 *
 *   <td data-etiket="Tarih">01.09.2026</td>
 *
 * Yazdırmada devre dışıdır (kural yalnız dar ekranda geçerli), çıktı
 * normal tablo olarak basılır.
 * ============================================================ */

@media (max-width: 767.98px) {
    table.tablo-mobil thead {
        /* clip ile gizlenir: display:none başlığı ekran okuyucudan da
           siler, oysa hücre etiketleri data-etiket'ten geliyor. */
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    table.tablo-mobil,
    table.tablo-mobil tbody,
    table.tablo-mobil tr,
    table.tablo-mobil td {
        display: block;
        width: auto;
    }

    table.tablo-mobil tr {
        border: 1px solid var(--kenar-renk, #e5e5e7);
        border-radius: 12px;
        padding: 6px 10px;
        margin-bottom: 10px;
        background: #fff;
    }

    table.tablo-mobil td {
        display: flex;
        /* Hücrede birden çok düğme varsa (sarmalayıcısı olmayan eski
           markup) sığmayan kısım alt satıra sarsın, kesilmesin. */
        flex-wrap: wrap;
        /* SPACE-BETWEEN DEĞİL — ölçüldü (23.09.2026, öğrenci detayı).
           `space-between` hücrede iki çocuk varken doğru çalışıyor
           (etiket solda, değer sağda), ama İŞLEMLER hücresinde yedi
           düğme var ve sarmalayıcıları yok: düğmeler tek tek çocuk
           olduğu için aralarına boşluk dağıtılıyor, alt satıra taşan
           ikisi de biri en solda biri en sağda kalıyordu — dağınık
           görünüyordu.

           Bunun yerine her şey sağa yaslanır, etiketi `margin-right:
           auto` sola iter. İki çocuklu hücrede sonuç aynı; çok düğmeli
           hücrede düğmeler bir arada, sağda toplanır. Alt satıra
           taşanlar da öyle. Markup değişmeden bütün `.tablo-mobil`
           tablolarında düzelir. */
        justify-content: flex-end;
        align-items: baseline;
        gap: 10px;
        border: 0;
        border-bottom: 1px solid #f1f1f3;
        padding: 6px 0;
        text-align: right;
    }

    table.tablo-mobil tr td:last-child {
        border-bottom: 0;
    }

    table.tablo-mobil td::before {
        content: attr(data-etiket);
        flex: 0 0 auto;
        /* Etiketi sola iten şey bu: boş alanı o yutar, kalan her şey
           sağda toplanır (yukarıdaki nota bak). */
        margin-right: auto;
        font-size: 0.72rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.02em;
        color: #86868b;
        text-align: left;
    }

    /* İşlem butonları burada YAZILI durur: bu desende açılır detay satırı
       yok, satırın kendisi zaten açık. Panel tablolarındaki "ana satırda
       kompakt ikon" kuralı (pispor.css) dar ekranda geçersiz kılınır. */
    table.tablo-mobil td .action-buttons {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 6px;
        /* Buton sayısı hücreye sığmazsa alt satıra sarsın: sabit genişlikte
           kalırsa hücreden taşıyor ve son buton kesiliyordu. */
        flex: 1 1 auto;
        min-width: 0;
    }

    table.tablo-mobil td .action-buttons .btn {
        width: auto;
    }

    table.tablo-mobil td .action-buttons .btn-label {
        display: inline !important;
    }

    /* KISA HÜCRELER (.hucre-kisa): çok sayıda dar sütun — aidat tablosundaki
       ay sütunları gibi — mobilde tam satır kaplamaz, yan yana akan rozetlere
       döner. 13 ayı 13 satır yapmak kartı gereksiz uzatıyordu. */
    table.tablo-mobil td.hucre-kisa {
        display: inline-flex;
        width: auto;
        gap: 6px;
        border: 0;
        margin: 2px 4px 2px 0;
        padding: 3px 10px;
        border-radius: 999px;
        background: #f2f2f5;
        font-size: 0.82rem;
        text-align: left;
    }

    /* Rozette yalnız AY-YIL etiketi durur; tutar zaten "Toplam Borç"ta.
       Değeri gizlemenin yolu font-size: 0 — hücrenin metni doğrudan text
       node, ayrıca sarmalayıcısı yok. Durum rengi (ödendi/borçlu) rozetin
       zemininden okunur. */
    table.tablo-mobil td.hucre-kisa {
        font-size: 0;
    }

    table.tablo-mobil td.hucre-kisa::before {
        font-size: 0.68rem;
        opacity: 0.85;
    }

    /* Etiketi olmayan hücre (toplam satırı, "kayıt yok" satırı) tam
       genişlikte ve ortalanmış kalır. */
    table.tablo-mobil td:not([data-etiket]) {
        display: block;
        text-align: center;
    }

    table.tablo-mobil td:not([data-etiket])::before {
        content: none;
    }
}

/* Açılır detay satırındaki KISA hücreler (ay sütunları gibi) rozet olur:
   yan yana akar, yalnız etiketi görünür — tutar zaten toplam sütununda.
   Eski mobil kart da "Eksik Aylar" rozetleri olarak böyle gösteriyordu. */
.dtr-details li.hucre-kisa {
    display: inline-flex;
    width: auto;
    border: 0 !important;
    margin: 2px 4px 2px 0;
    padding: 3px 10px !important;
    border-radius: 999px;
    background: #f2f2f5;
}

.dtr-details li.hucre-kisa .dtr-title {
    font-size: 0.7rem;
    font-weight: 700;
    margin: 0;
}

.dtr-details li.hucre-kisa .dtr-data {
    display: none;
}

/* YAZDIRMA: DataTables kontrolleri kâğıda basılmaz, gizli sütunlar basılır.
   Yazdırılabilir raporlarda tablo DataTables'a bağlandığında arama/sayfalama
   kutuları ve sıralama okları çıktıya karışıyordu; mobilde detay satırına
   düşen sütunlar ise kâğıtta büsbütün kaybolurdu. */
@media print {
    .dataTables_filter, .dataTables_length, .dataTables_paginate, .dataTables_info,
    div.dt-search, div.dt-length, div.dt-paging, div.dt-info {
        display: none !important;
    }

    table.dataTable thead th {
        background-image: none !important;
    }

    table.dataTable th.dtr-hidden,
    table.dataTable td.dtr-hidden {
        display: table-cell !important;
    }

    table.dataTable tr.child {
        display: none !important;
    }
}

@media print {
    .no-print {
        display: none !important;
    }
}

/* ============================================================
 * YAZDIRMA — BELGE GÖRÜNÜMÜ (panel içi ve dışı)
 * ============================================================
 * ÖLÇÜLDÜ (02.10.2026): panelin TÜM CSS katmanında tek bir yazdırma
 * kuralı vardı (`.no-print`) ve o da yalnız o sınıfı taşıyan öğeyi
 * gizliyordu. Sonuç: sol menü, üst çubuk ve alt bilgi HER sayfada kâğıda
 * basılıyor, `.main-content`in 280 px sol boşluğu yazdırmada da duruyor
 * ve kâğıdın sol üçte biri boşa gidiyordu. Kullanıcı devamlılık raporunun
 * PDF'inde bildirdi; tarama 21 sayfada Yazdır düğmesi buldu, yani kusur
 * tek sayfanın değil eksik bir ortak katmanın kusuruydu.
 *
 * KABUĞU GİZLEYEN KURALLAR BURADA DEĞİL `pispor.css`te: `.sidebar`,
 * `.main-header` ve `.footer-wrapper` panel bileşenleridir, bu dosya ise
 * panel dışına da iniyor (veli paneli, karneler, rapor sayfaları).
 * Aşağıdakiler her iki yüzeyde de doğru olanlardır.
 * ============================================================ */
@media print {
    body {
        background: #fff !important;
    }

    /* Gölge kâğıtta gri bir bulanıklık olarak basılır ve mürekkep yer;
       ince çerçeve bilgiyi aynı şekilde taşır. */
    .card {
        border: 1px solid #dee2e6 !important;
        box-shadow: none !important;
    }

    /* BÖLÜNMEYECEK OLAN YALNIZ KÜÇÜK KUTULARDIR.
       İlk yazımda `.card` da bu listedeydi ve kullanıcı bildirdi: uzun
       listede ilk sayfa neredeyse bomboş çıkıyor, tablo 2. sayfadan
       başlıyordu. Sebep ölçüldü — 66 satırlık tabloda kartın yüksekliği
       2830 px, A4 yatay bir sayfa ise ~718 px. Sığmayan bir kutuya
       "bölünme" demek tarayıcıya onu bir sonraki sayfaya İTTİRİR; kutu
       zaten sığmadığı için orada da bölünür, tek kazanç kaybedilen
       sayfadır. Ölçüt: yüksekliği önceden sınırlı olan kutuya avoid
       yazılır, içeriğe göre uzayana YAZILMAZ. */
    .metric-card {
        break-inside: avoid;
    }

    /* Satır bölünmesin — bu güvenli, satır yüksekliği bir sayfayı aşmaz.
       Tablo başlığı da her sayfanın tepesinde tekrar etsin; ikinci
       sayfadaki sütunların ne olduğu yoksa anlaşılmıyor. */
    tr {
        break-inside: avoid;
    }

    thead {
        display: table-header-group;
    }

    /* TARAYICIDA "ARKA PLAN GRAFİKLERİ" VARSAYILAN OLARAK KAPALIDIR.
       Açmadan basan biri ilerleme çubuğunu ve rozeti HİÇ görmez; devamlılık
       raporunda Katılım Oranı sütunu bomboş çıkardı. Bu üç bileşen bilgiyi
       RENKLE taşıdığı için baskıda da zorlanır. */
    .progress,
    .progress-bar,
    .badge {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* Kâğıtta tıklanacak bir bağlantı yok; mavi ve altı çizili metin
       okumayı zorlaştırıyor. */
    a {
        color: #000 !important;
        text-decoration: none !important;
    }
}

/* ============================================================
 * RAPOR SAYFASI KABUĞU
 * ============================================================
 * Panel dışı rapor sayfalarının (kasa, yoklama, rutin ödemeler,
 * bekleyen ödemeler) ortak çerçevesi. Dördünde de BİREBİR aynı yazılmıştı.
 *
 * `.rapor-baslik` eskiden `.page-header` adını taşıyordu — panelin kendi
 * `.page-header`ıyla AYNI AD, FARKLI BİLEŞEN: panelinki başlık satırının
 * flex düzeni, buradaki koyu degrade bir afiş. Panel dışı sayfalar
 * pispor.css yüklemediği için bugüne kadar çakışmıyordu, ama ortak
 * dosyaya taşınınca çakışacaktı. CLAUDE.md görsel standart 1
 * `.page-header`ı başlık satırı olarak tanımlıyor, o yüzden adı panel
 * tarafında bırakıldı ve afiş yeniden adlandırıldı.
 * ============================================================ */

.main-container {
    background-color: white;
    border-radius: 10px;
    box-shadow: 0 0 20px rgba(0,0,0,0.1);
    margin: 0 auto;
    padding: 30px;
}

.rapor-baslik {
    background: linear-gradient(135deg, #1e2a3b 0%, #0f1724 100%);
    border-radius: 10px;
    color: white;
    margin-bottom: 30px;
    padding: 20px;
}


/* ============================================================
 * METRİK KUTULARI (.metric-card)
 * ============================================================
 * Görsel standart 3'ün kutu deseni. pispor.css'ten buraya alındı:
 * panel dışı sayfalar (raporlar, üye paneli) da aynı kutuyu
 * kullanacak, oysa pispor.css oraya inmiyor.
 *
 * Yapı:
 *   .metric-card > .metric-top > (.metric-title + .metric-icon)
 *                > .metric-value
 *                > .metric-sub          (isteğe bağlı alt bilgi)
 * ============================================================ */

/* Metrik kartları - tüm sayfalarda standart kompakt bilgi kutusu */
.metric-card {
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08);
    padding: 10px 14px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    text-decoration: none;
}

.metric-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08), 0 4px 10px rgba(0, 0, 0, 0.05);
}

.metric-card-link {
    cursor: pointer;
}

.metric-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    margin-bottom: 2px;
}

.metric-title {
    /* Esnek kolonda (col-md gibi) kutu, başlığın tek satırlık genişliğinden
       DAR olamıyordu: kolon kendini zorla genişletip son kutuyu alt satıra
       atıyordu. min-width:0 ile başlık daralıp üç noktaya düşer, kutu payına
       sığar. */
    min-width: 0;
    font-size: var(--yazi-mini);
    font-weight: 700;
    color: #86868b;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.metric-icon {
    font-size: 0.85rem;
    opacity: 0.75;
    flex-shrink: 0;
}

/* Bootstrap'te `.text-purple` YOKTUR. Sınıf üç yerde kullanılıyordu
   (yoklama raporu kutu ikonu, bekleyen ödemeler ürün borcu kutusu,
   otomatik mesaj türleri listesi) ama yalnız bekleyen-ödemeler'in kendi
   <style>'ında tanımlıydı — diğer ikisinde ikon sessizce varsayılan
   renkte kalıyordu. Tanım buraya alındı, üçü de mor görünür. */
.text-purple { color: var(--mor-renk) !important; }
.badge.bg-purple {
    background-color: var(--mor-renk) !important;
    color: #fff !important;
}

.metric-value {
    font-size: var(--yazi-deger);
    font-weight: 800;
    letter-spacing: -0.02em;
    color: #1d1d1f;
    line-height: 1.15;
    /* Rakamlar eşit genişlikte: yan yana duran kutularda sayılar hizalanır,
       bir süre/tutar güncellendiğinde değer sağa sola oynamaz. */
    font-variant-numeric: tabular-nums;
}

/* Sayı değil METİN taşıyan kutular (tarih, ad, durum).
   .metric-value 1.35rem/800'dür ve kısa sayılar için ölçülmüştür;
   "01.06.2026" gibi boşluksuz uzun bir değer satır sonu bulamadığı için
   dar kutudan (ör. öğrenci detayındaki col-md-3) taşıyordu. */
.metric-value-sm {
    font-size: var(--yazi-deger-sm);
    font-weight: 700;
}

.metric-sub {
    font-size: 0.68rem;
    color: #aeaeb2;
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 768px) {
    .metric-card {
        padding: 9px 12px;
    }
    .metric-value {
        font-size: 1.15rem;
    }
    .metric-title {
        font-size: 0.62rem;
        letter-spacing: 0;
    }
    .metric-icon {
        display: none;
    }
}

/* ============================================================
   FİLTRE KUTUSU — yazdırılabilir rapor sayfaları
   ============================================================
   Panel sayfalarında filtreler `.card` + `card-header py-2` ile durur
   (görsel standart 6). Kendi <head>'ini yazan rapor sayfalarında panel
   kabuğu yoktur; oradaki gri filtre kutusu bu sınıfla gelir. Kural iki
   sayfada ayrı ayrı yazılıydı, ortak katmana alındı. */
.filter-card {
    background: #f8f9fa;
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 20px;
}

/* Mobil akordiyon açılınca başlıktaki ok yön değiştirir */
.filter-chevron {
    transition: transform 0.3s;
}

[aria-expanded="true"] .filter-chevron {
    transform: rotate(180deg);
}

@media (max-width: 767.98px) {
    .filter-card {
        padding: 12px;
    }
}

/* ============================================================
   KART ÖNİZLEMESİ (öğrenci / personel kart basımı)
   ============================================================
   Kart fiziksel ölçüdedir (85,6 × 54 mm ≈ 323 px) ve AKMAZ — baskıya
   gidecek şey ekranda da aynı ölçüde durmalı. A4 tabakası iki sütundur,
   yani ~647 px: telefonda kutuya sığmaz. Eski hâlinde `justify-content:
   center` + `overflow-x: auto` vardı ve ortalanmış taşma kaydırmayla
   ULAŞILAMAZ: kart iki yanından da kırpılıyordu.

   Çözüm iki adımlı: mobilde tabaka tek sütuna iner (kart okunur boyda
   kalır), sığmayan kalan pay için footer.php'deki kartOnizlemeOlcekle()
   tabakayı küçültür. Ölçek satır içi stil olarak yazıldığı için baskıda
   etkisiz kalması şarttır — aşağıdaki @media print bunu geri alır. */
.kart-onizleme {
    overflow: hidden;
}

.kart-onizleme .kart-tabaka {
    /* Kutu sütunları sarsın: ortalama yüzünden sola taşma olmasın */
    width: max-content;
    justify-content: start;
    transform-origin: top left;
}

@media (max-width: 767.98px) {
    .kart-onizleme {
        padding: 0.5rem;
    }
    .kart-onizleme .kart-tabaka {
        grid-template-columns: 85.6mm;
    }
}

@media print {
    .kart-onizleme {
        height: auto !important;
        overflow: visible;
    }
    .kart-onizleme .kart-tabaka {
        width: auto;
        justify-content: center;
        transform: none !important;
    }
}

/* ============================================================
   ROZET OKUNURLUĞU
   ============================================================
   Bootstrap 5'te `.badge` metni beyazdır; sarı ve açık mavi zeminde
   okunmaz. Panelde 34 rozete elle `text-dark` yazılmış, 29'una
   yazılmamıştı — aynı anlamdaki rozet sayfadan sayfaya farklı
   görünüyordu. Kural ikisini eşitler; `text-dark` yazan rozetler
   `!important` taşıdığı için aynen çalışmaya devam eder. */
.badge.bg-warning,
.badge.bg-info,
.badge.bg-light {
    color: var(--yazi-koyu);
}

/* ============================================================
   BAŞLIK AĞIRLIĞI
   ============================================================
   `.font-weight-bold` Bootstrap 4'ten kalma bir sınıf; Bootstrap 5'te
   TANIMLI DEĞİL, yani panelde 255 yerde yazılı olmasına rağmen hiçbir
   şey yapmıyordu — kart başlıkları h6'nın varsayılanı olan 500'de,
   `fw-bold` yazan 9 başlık ise 700'de duruyordu ve sekiz sayfada ikisi
   yan yana görünüyordu.

   Kullanıcıyla kararlaştırılan ağırlık 600: başlık gövdeden net ayrışır
   ama sayfa başlığıyla (800) yarışmaz. Sınıfın kendisi tanımlanır ki
   255 yerdeki niyet çalışsın; kart başlığı ayrıca bileşen üzerinden
   sabitlenir — `fw-bold` Bootstrap'te `!important` taşıdığı için orada
   da gerekiyor. */
.font-weight-bold {
    font-weight: 600;
}

.card-header h6,
.card-header .fw-bold {
    font-weight: 600 !important;
}

/* ============================================================
   BİLDİRİM KUTUSU (pisporBildir — toastr yoksa)
   ============================================================
   toastr yalnız panel sayfalarına yükleniyor. Veli paneli, ödeme ve
   kendi <head>'ini yazan rapor sayfalarında bildirim ya alert() ile
   veriliyor ya da hiç verilmiyordu. Bu kutu oralarda devreye girer;
   panelde toastr varken hiç çizilmez, yani panelin görünümü değişmez.
   Ölçüler ve renkler panelin jetonlarından gelir. */
.pispor-bildirim-kutu {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 2000;              /* modal 1055; bildirim onun da üstünde */
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: min(22rem, calc(100vw - 2rem));
}

.pispor-bildirim {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .7rem .8rem;
    border-radius: var(--kose);
    border-left: 4px solid var(--secondary-color);
    background: var(--kart-zemin);
    box-shadow: var(--golge-kart);
    color: var(--yazi-renk);
    font-size: var(--yazi-kucuk);
    line-height: 1.35;
}

.pispor-bildirim-ikon {
    font-size: 1rem;
    line-height: 1.35;
    color: var(--secondary-color);
}

.pispor-bildirim-govde {
    flex: 1 1 auto;
    min-width: 0;
    word-break: break-word;
}

.pispor-bildirim-baslik {
    font-weight: 600;
    margin-bottom: .1rem;
}

.pispor-bildirim-kapat {
    flex: 0 0 auto;
    font-size: .6rem;
    margin-top: .15rem;
}

.pispor-bildirim.basarili { border-left-color: var(--success-color); }
.pispor-bildirim.basarili .pispor-bildirim-ikon { color: var(--success-color); }
.pispor-bildirim.hata     { border-left-color: var(--danger-color); }
.pispor-bildirim.hata     .pispor-bildirim-ikon { color: var(--danger-color); }
.pispor-bildirim.uyari    { border-left-color: var(--warning-color); }
.pispor-bildirim.uyari    .pispor-bildirim-ikon { color: #b07d10; }
.pispor-bildirim.bilgi    { border-left-color: var(--info-color); }
.pispor-bildirim.bilgi    .pispor-bildirim-ikon { color: var(--info-color); }

@media (max-width: 575.98px) {
    /* Telefonda üstte tam genişlik: sağ üst köşedeki dar kutu okunmuyor */
    .pispor-bildirim-kutu {
        left: .75rem;
        right: .75rem;
        max-width: none;
    }
}

@media print {
    .pispor-bildirim-kutu { display: none; }
}

/* DataTables detay satırı kutuya sığsın: dört sayfaya ayrı ayrı
   yazılmıştı (başvurular, çekler, ön başvuru, ürün takip). */
table.dataTable .dtr-details {
    width: 100%;
    box-sizing: border-box;
}

/* ------------------------------------------------------------------
   PANELİN KENDİ MOBİL DETAY SATIRI (.detay-satiri)
   ------------------------------------------------------------------
   DataTables kullanmayan rapor tablolarında dar ekranda açılan satır.
   Görünümü DataTables'ın detayıyla AYNI olmalı (aynı .dtr-details /
   .dtr-title / .dtr-data işaretleri) — yoksa aynı panelde iki ayrı
   detay görünümü olur. DataTables'ın kendi CSS'i o sınıfları yalnız
   `table.dataTable` altında biçimlendirdiği için burada tekrarlanıyor.
   İçeriği ELLE YAZILMAZ: gizli hücrelerin kendisinden kurulur
   (yardımcı `raporTablosuMobil`, includes/footer.php). */
.detay-satiri > td {
    background-color: var(--zemin-alt);
    padding: 0;
}

.detay-satiri .dtr-details {
    width: 100%;
    box-sizing: border-box;
    list-style: none;
    margin: 0;
    padding: 0.5rem 0.75rem;
}

/* `:not(.hucre-kisa)` ŞART: yukarıdaki `.dtr-details li.hucre-kisa`
   rozet kuralıyla bu kuralın özgüllüğü EŞİT (0,2,1) ve bu dosyada sonra
   geldiği için onu ezerdi — ay sütunları rozet değil, tam satır olurdu. */
.detay-satiri .dtr-details > li:not(.hucre-kisa) {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--kenar-acik);
}

.detay-satiri .dtr-details > li:not(.hucre-kisa):last-child {
    border-bottom: none;
}

.detay-satiri .dtr-title {
    font-weight: 600;
    color: var(--yazi-soluk);
    flex: 0 0 auto;
}

.detay-satiri .dtr-data {
    text-align: right;
    word-break: break-word;
}

/* ------------------------------------------------------------------
   AYAR SATIRI (.ayar-satir)
   ------------------------------------------------------------------
   Tek satır: ad + (?) ipucu + anahtar. Açıklama satırın ALTINA blok
   metin olarak yazılmaz — sayfa gereksiz uzuyor. Genel Ayarlar'da bir
   kez yaşandı, Özellikler ekranında bir kez daha: 50 anahtarın açıklaması
   blok metin olunca sayfa telefonda 5138 px oluyordu (ölçüldü).
   Açıklama `title` + Bootstrap ipucunda durur.
   İki sayfa birden kullandığı için ortak katmana alındı; renkler
   jetonlardan gelir (eskiden genel-ayarlar.php'de çıplak hex'ti). */
.ayar-satir {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .55rem 0;
}

.ayar-satir + .ayar-satir,
.ayar-satir.border-top {
    border-top: 1px solid var(--kenar-renk);
}

.ayar-ad {
    font-weight: 600;
    font-size: var(--yazi-kucuk);
    color: var(--yazi-koyu);
    min-width: 0;
}

.ayar-ipucu {
    color: var(--simge-soluk);
    cursor: help;
    margin-left: .25rem;
    font-size: var(--yazi-buton);
}

.ayar-ipucu:hover { color: var(--primary-color); }

/* Açılabilir satır dokunulabilir olduğunu belli etsin. */
tr.detay-acar {
    cursor: pointer;
}

tr.detay-acar.acik {
    background-color: var(--secili-zemin);
}

/* ============================================================
   KART (.card)
   ============================================================
   Panelin kart görünümü: çerçevesiz, geniş yumuşak gölge, Bootstrap
   köşesi. On bir sayfa kendi `.card` kuralını yazıyordu ve hiçbiri
   diğerine benzemiyordu — köşe 0.35rem / 8px / 12px / 15px / 22px,
   gölge beş ayrı değer, alt boşluk 1rem / 1.5rem / 20px. Kullanıcıyla
   bugünkü panel kartında birleşildi; kural panel dışı yüzeylere de
   insin diye ortak katmanda durur. */
.card {
    border: none;
    box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);
    margin-bottom: 1.5rem;
}

/* Kart başlığı kartla birlikte gider: açık gri zemin + ince ayraç.
   Altı sayfa kendi başlığını yazıyordu (saydam, beyaz, #f7f7f7,
   degrade…); panel sayfalarında zaten bu kural görünüyordu, veli
   paneli ve beslenme takip kendi tonunu kullanıyordu. */
.card-header {
    background-color: var(--zemin-renk);
    border-bottom: 1px solid var(--kenar-renk);
    font-weight: 700;
    color: var(--primary-color);
}

/* Mobilde tablo yazısı küçülür. Yedi sayfa bunu kendi yazıyordu ve
   yedi ayrı değer kullanıyordu (0,7 / 0,75 / 0,8 / 0,82 / 0,85 /
   0,875 rem): aynı liste telefonda sayfadan sayfaya farklı boyda
   görünüyordu. En yaygın değer olan 0,8rem'de birleşildi. */
@media (max-width: 767.98px) {
    .table {
        font-size: 0.8rem;
    }
}

/* Mobilde rozet sıkışır. Yedi sayfa bunu kendi yazıyordu; üçü
   `!important` ile, üç ayrı yazı boyu ve üç ayrı iç boşlukla. Aynı
   "Aktif" rozeti telefonda sayfadan sayfaya farklı boydaydı. */
@media (max-width: 767.98px) {
    .badge {
        font-size: 0.7rem;
        padding: 0.25rem 0.4rem;
    }
}

/* Mobilde tablo hücreleri sıkışır. Sekiz sayfa bunu kendi yazıyordu ve
   sekiz ayrı değer kullanıyordu; en yaygın olan 0,4rem 0,3rem'de
   birleşildi. Sayfaya özgü davranışlar (nowrap, word-break) yerinde
   kalır — onlar iç boşluk değil, o listenin okunma biçimi. */
@media (max-width: 767.98px) {
    .table th,
    .table td {
        padding: 0.4rem 0.3rem;
        vertical-align: middle;
    }
}

/* Sık listelerde (dashboard satırları gibi) kullanılan küçük rozet.
   Yalnız BOY değiştirir; şekil standart rozetle aynıdır — eskiden
   anasayfada 12px köşeyle hap görünüyordu, panelin geri kalanındaki
   köşeli rozetlerle aynı satırda farklı duruyordu. */
.badge-xs {
    padding: 3px 8px;
    font-size: 0.66rem;
}

/* Yatay kayan tabloda iOS'ta ivmeli kaydırma. Dört sayfaya ayrı ayrı
   yazılmıştı; `.table-responsive` zaten Bootstrap'in sınıfı, kural
   hepsine birden verilir. Sayfaların `overflow-x` kararları (gizle /
   göster) kendilerine özgüdür, onlara dokunulmaz. */
.table-responsive {
    -webkit-overflow-scrolling: touch;
}

/* Grafik sarmalayıcısı: Chart.js tuvali ebeveynine göre ölçekleniyor,
   bu yüzden konum ve genişlik ortak. YÜKSEKLİK sayfada kalır — küçük
   panel grafiği 250 px, rapor grafiği 300 px; ikisi de bilinçli. */
.chart-container {
    position: relative;
    width: 100%;
}

/* ============================================================
   MODAL ORTALAMA
   ============================================================
   Bootstrap modali varsayılanda ekranın ÜSTÜNE yaslar. Panelde 21
   modal markup'ında `modal-dialog-centered` yazıyordu, 130'unda
   yazmıyordu: aynı panelde kimi pencere ortada, kimi tepede
   açılıyordu. Kural `.modal-pispor`a verilir, markup'a dokunmaya
   gerek kalmaz (Bootstrap'in `.modal-dialog-centered`ının yaptığı
   işin aynısı). */
.modal-pispor .modal-dialog {
    display: flex;
    align-items: center;
    min-height: calc(100% - var(--bs-modal-margin, 0.5rem) * 2);
}

.modal-pispor .modal-content {
    width: 100%;
}


/* ============================================================
   MODAL STANDARDI (.modal-pispor) — panel VE panel dışı
   ============================================================
   `pispor.css`'ten taşındı; içerik aynen, tek değişiklik konumu.
   Bu katman kendi <head>'ini yazan sayfalara da iniyor, modal
   markup'ı da oralarda zaten standarda çevrilmişti. */
/* ==================== MODAL STANDARDI (.modal-pispor) ====================
   Tüm panel modallarının ortak görünümü. Kullanımı:
   <div class="modal fade modal-pispor" ...>
     <div class="modal-header">
       <div class="modal-baslik">
         <span class="modal-ikon"><i class="fas fa-..."></i></span>
         <div><h5 class="modal-title">Başlık</h5>
              <small class="modal-alt-baslik">Alt açıklama</small></div>
       </div>
       <button class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
     </div>
   Gövde bölümleri .detay-bolum, bilgi satırları .detay-tablo ile yazılır. */
.modal-pispor .modal-content {
    border: none;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}

/* ------------------------------------------------------------------
   DUYURU MODALI (.modal-duyuru) — standardın ikinci biçimi
   ------------------------------------------------------------------
   `.modal-pispor` VERİ modalidir: degradeli başlık, ikon, başlık,
   alt başlık, gri gövde. Panelde bir de DUYURU modali var: ortada
   tek kart, büyük yuvarlak ikon, iki düğme. Bildirim izni ve bildirim
   detayı böyle.

   Bunlara `.modal-pispor` verilemez — birinin başlığı hiç yok,
   diğerinin ikonu bildirim türüne göre JS'te renkleniyor; degradeli
   başlık ikisini de bozar. O yüzden kendi görünümlerini `style=""`
   ile satır içi yazıyorlardı (üç ayrı yerde, birbirinden farklı
   değerlerle). Adı buraya konuyor.
   ------------------------------------------------------------------ */
.modal-duyuru .modal-content {
    border: none;
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}

.modal-duyuru .modal-header,
.modal-duyuru .modal-footer {
    border: none;
}

.modal-duyuru .modal-body {
    color: var(--yazi-orta);
}

.modal-pispor .modal-header {
    background: linear-gradient(135deg, #4e73df 0%, #224abe 100%);
    color: #fff;
    border-bottom: none;
    padding: 0.75rem 1rem;
    align-items: center;
}

.modal-pispor .modal-baslik {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.modal-pispor .modal-ikon {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    flex-shrink: 0;
}

.modal-pispor .modal-title {
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin: 0;
    line-height: 1.2;
}

.modal-pispor .modal-alt-baslik {
    display: block;
    font-size: 0.72rem;
    opacity: 0.85;
    line-height: 1.2;
}

.modal-pispor .modal-body {
    background: #f8f9fc;
    padding: 1rem;
}

.modal-pispor .modal-footer {
    background: #fff;
    border-top: 1px solid #eef0f5;
    padding: 0.6rem 1rem;
}

/* Gövde bölümü kartı */
.detay-bolum {
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 1px 8px rgba(0, 0, 0, 0.06);
    padding: 0.7rem 0.85rem;
    margin-bottom: 0.75rem;
}

.detay-bolum-baslik {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #86868b;
    padding-bottom: 0.45rem;
    margin-bottom: 0.45rem;
    border-bottom: 1px solid #eef0f5;
}

.detay-bolum-baslik i {
    color: var(--primary-color);
    font-size: 0.8rem;
}

/* Etiket/değer bilgi tablosu (boş satırlar hiç render edilmez) */
.detay-tablo {
    width: 100%;
    margin: 0;
    font-size: 0.85rem;
}

.detay-tablo th,
.detay-tablo td {
    padding: 0.28rem 0;
    vertical-align: top;
    border: none;
}

.detay-tablo tr + tr th,
.detay-tablo tr + tr td {
    border-top: 1px solid #f2f4f8;
}

.detay-tablo th {
    width: 42%;
    font-weight: 700;
    color: #6c757d;
    font-size: 0.8rem;
}

.detay-tablo td {
    color: #1d1d1f;
    font-weight: 600;
    word-break: break-word;
}

/* Para özeti şeridi (Toplam / Alınan / Kalan) */
.detay-ozet {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.detay-ozet-kutu {
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 1px 8px rgba(0, 0, 0, 0.06);
    padding: 0.55rem 0.7rem;
    border-left: 3px solid var(--primary-color);
}

.detay-ozet-kutu.ozet-basarili { border-left-color: var(--success-color); }
.detay-ozet-kutu.ozet-uyari { border-left-color: var(--warning-color); }
.detay-ozet-kutu.ozet-tehlike { border-left-color: var(--danger-color); }

.detay-ozet-baslik {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: #86868b;
}

.detay-ozet-deger {
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: #1d1d1f;
    line-height: 1.2;
}

/* Bölüm içi liste tablosu (taksit planı, çekler, ödeme geçmişi) */
.detay-liste {
    width: 100%;
    font-size: 0.8rem;
    margin: 0;
}

.detay-liste thead th {
    background: #f8f9fc;
    color: #6c757d;
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    border-bottom: 1px solid #eef0f5;
    padding: 0.35rem 0.5rem;
    white-space: nowrap;
}

.detay-liste tbody td {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid #f2f4f8;
    vertical-align: middle;
}

.detay-liste tbody tr:last-child td { border-bottom: none; }

.detay-liste tfoot th {
    padding: 0.35rem 0.5rem;
    background: #f8f9fc;
    font-size: 0.78rem;
    border-top: 1px solid #eef0f5;
}

.detay-liste .badge { font-weight: 700; }

/* Mobil kompakt satır listesi (geniş tablolar yerine — .detay-liste ile
   aynı veriyi gösterir; tablo d-none d-md-table, liste d-md-none) */
.detay-satir {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    padding: 0.45rem 0;
    border-bottom: 1px solid #f2f4f8;
    font-size: 0.82rem;
}

.detay-satir:last-child { border-bottom: none; }

.detay-satir-sol { min-width: 0; }

.detay-satir-baslik {
    font-weight: 700;
    color: #1d1d1f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.detay-satir-alt {
    font-size: 0.72rem;
    color: #86868b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.detay-satir-sag {
    text-align: right;
    white-space: nowrap;
    flex-shrink: 0;
}

.detay-satir-tutar {
    font-weight: 800;
    color: #1d1d1f;
}

.detay-satir-toplam {
    border-top: 1px solid #eef0f5;
    border-bottom: none;
    margin-top: 0.25rem;
    padding-top: 0.5rem;
    font-weight: 800;
}

@media (max-width: 576px) {
    .modal-pispor .modal-body { padding: 0.75rem; }
    .modal-pispor .modal-title { font-size: 0.92rem; }
    .modal-pispor .modal-ikon { width: 30px; height: 30px; font-size: 0.85rem; }
    .detay-tablo { font-size: 0.82rem; }
    .detay-tablo th { font-size: 0.76rem; width: 45%; }
    .detay-ozet { grid-template-columns: repeat(2, 1fr); }
    .detay-ozet-deger { font-size: 0.92rem; }
}


/* ============================================================
   BİRİNCİL BUTON (.btn-primary)
   ============================================================
   `pispor-son.css`'ten taşındı. Orada kaldığı sürece panel dışı
   yüzeyler (veli paneli, rapor sayfaları, ödeme ekranları)
   Bootstrap'in kendi mavisini kullanıyordu. */
.btn-primary {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
}

.btn-primary:hover {
    background-color: #2e59d9;
    border-color: #2653d4;
}


/* ============================================================
   ODAK HALKASI (.form-control / .form-select)
   ============================================================
   `pispor-son.css`'ten taşındı ve .form-select'i de kapsayacak
   şekilde genişletildi. Ölçüldüğünde halka dört ayrı maviydi:
   panelde #4e73df (bu kural), veli panelinde #6366f1 indigo,
   login'de gök mavisi, rapor sayfalarında ise hiç kural yoktu ve
   Bootstrap'in kendi #0d6efd halkası çıkıyordu. Sayfaya odak
   kuralı yazılmaz. */
.form-control:focus,
.form-select:focus {
    border-color: var(--primary-acik);
    box-shadow: var(--odak-halka);
}


/* ============================================================
   ÇOKLU SEÇİM KUTUSU (.custom-select-wrapper)
   ============================================================
   Onay kutulu açılır seçici (şube seçimi). Bileşen üç dosyada
   (branslar, personeller, personel-detay) BİREBİR kopyalanmıştı;
   buraya alındı. Taşınırken üç renk panel diline çekildi:
   kenarlık #ced4da yerine form alanlarıyla aynı --bs-border-color,
   odak halkası Bootstrap'in #86b7fe/#0d6efd'si yerine panelinki,
   seçili etiket zemini #0d6efd yerine --primary-color. Ölçüler
   (38 px kutu, 8/12 px satır) aynen korundu.

   `.dropdown-item` kuralları `.custom-dropdown` altına
   KAPSAMLANDI: sayfalarda çıplak yazılıyordu ve o sayfadaki her
   açılır menüyü etkiliyordu. (Ölçüldü: branslar ve personeller'de
   başka menü yok, bu yüzden kapsamlama hiçbir şeyi değiştirmiyor;
   panelin geri kalanı zaten Bootstrap varsayılanında.) */
.custom-select-wrapper {
    position: relative;
}

.custom-select-display {
    min-height: 38px;
    padding: 6px 12px;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    background-color: var(--kart-zemin);
    cursor: pointer;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
}

.custom-select-display:hover {
    border-color: var(--primary-acik);
}

.custom-select-display:focus {
    border-color: var(--primary-acik);
    outline: 0;
    box-shadow: var(--odak-halka);
}

/* Seçilemez durum: bir önceki seçim yapılmadan açılmaması gereken kutular
   (antrenman programında "önce grup seçiniz"). */
.custom-select-display.disabled {
    background-color: var(--kenar-acik);
    cursor: not-allowed;
    opacity: 0.65;
}

.custom-select-display.disabled:hover {
    border-color: var(--bs-border-color, #dee2e6);
}

.selected-item {
    display: inline-flex;
    align-items: center;
    background-color: var(--primary-color);
    color: #fff;
    padding: 3px 8px;
    border-radius: var(--kose-kucuk);
    font-size: var(--yazi-kucuk);
}

.selected-item .remove {
    margin-left: 8px;
    cursor: pointer;
    font-weight: bold;
}

.selected-item .remove:hover {
    color: var(--warning-color);
}

.select-placeholder {
    color: var(--yazi-soluk);
}

.custom-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--kart-zemin);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-top: none;
    border-radius: 0 0 0.375rem 0.375rem;
    max-height: 200px;
    overflow-y: auto;
    display: none;
    z-index: 1050;
}

.custom-dropdown.show {
    display: block;
}

.custom-dropdown .dropdown-item {
    padding: 8px 12px;
    cursor: pointer;
    display: flex;
    align-items: center;
}

.custom-dropdown .dropdown-item:hover {
    background-color: var(--zemin-alt);
}

.custom-dropdown .dropdown-item.selected {
    background-color: var(--secili-zemin);
}

.custom-dropdown .dropdown-item input[type="checkbox"] {
    margin-right: 8px;
}

/* Menü içinde arama kutusu: liste uzunsa üstte yapışık durur */
.custom-dropdown .secim-ara {
    padding: 6px 10px;
    border-bottom: 1px solid var(--kenar-acik);
    position: sticky;
    top: 0;
    background: var(--kart-zemin);
}

.custom-dropdown .secim-ara input {
    width: 100%;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--kose-kucuk);
    padding: 4px 8px;
    font-size: var(--yazi-kucuk);
}

/* Sonuç yoksa gösterilen satır */
.custom-dropdown .secim-bos {
    padding: 10px 12px;
    color: var(--yazi-soluk);
    font-size: var(--yazi-kucuk);
    text-align: center;
}

/* Telefonda menü kısalır, satırlar parmağa göre büyür */
@media (max-width: 768px) {
    .custom-dropdown {
        max-height: 150px;
    }

    .custom-dropdown .dropdown-item {
        padding: 10px 12px;
        font-size: 0.9rem;
    }

    .custom-select-display {
        min-height: 45px;
        font-size: 0.9rem;
    }
}

/* --- Sabit kaydet çubuğu (.kaydet-cubugu) --------------------------
   Değişiklik yapılınca sağ altta belirir, kaydedilince kaybolur:
   düğme hem elin altında durur hem "kaydedilmemiş değişiklik var"
   demiş olur. Genel Ayarlar'da ölçülmüş desen, kural SAYFADA değil
   burada — ikinci kopya er geç ayrışır.

   Düğmenin `form` özniteliği sayesinde form dışında durabilir;
   içeride olsaydı `position: fixed` sütun düzenini bozardı. */
.kaydet-cubugu {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 1030;
}

/* --- Sipariş sepeti (.siparis-*) ----------------------------------
   `includes/urun-siparis-form.php` iki yüzeyde birden basılır: kök
   dizindeki siparis.php ve üye paneli. Bu yüzden kural sayfaya değil
   ORTAK katmana yazılır — iki kopya er geç ayrışır.
   Renkler jetondan gelir, çıplak hex yazılmaz. */
/* Sipariş satırı: ürün · beden · adet · tutar — hepsi TEK SATIRDA.
   Ekran ürünleri tek tek listelemiyor; veli satır kuruyor. 20 ürünlü
   okulda eski düzen 20 kart basıyordu (kullanıcı kararı). */
.siparis-kalem {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
    border: 1px solid var(--kenar-renk);
    border-radius: var(--kose);
    padding: .5rem .6rem;
    margin-bottom: .5rem;
    background: var(--zemin-alt);
}

.siparis-urun-sec  { flex: 3 1 10rem; min-width: 8rem; }
.siparis-beden-sec { flex: 1 1 5.5rem; min-width: 5rem; max-width: 9rem; }

.siparis-tutar {
    flex: 0 0 auto;
    margin-left: auto;
    font-weight: 700;
    font-size: var(--yazi-kucuk);
    color: var(--yazi-koyu);
    white-space: nowrap;
    min-width: 5.5rem;
    text-align: right;
}

/* Dolu satır belli olsun: uzun sepette veli neyi seçtiğini kaybediyor */
.siparis-kalem.siparis-secili {
    background: var(--primary-cok-acik);
    border-color: var(--primary-color);
    box-shadow: inset 3px 0 0 var(--primary-color);
}

/* Telefonda ürün adı tam satırı alsın, geri kalanı altına insin */
@media (max-width: 575.98px) {
    .siparis-urun-sec { flex: 1 1 100%; }
    .siparis-tutar { min-width: 4.5rem; }
}

/* Adet kutusu: dokunma hedefi 38 px (.action-buttons ile aynı ölçü) */
.siparis-adet {
    display: flex;
    align-items: center;
    gap: .25rem;
    flex: 0 0 auto;
}

.siparis-adet .btn {
    min-width: 38px;
    min-height: 38px;
    line-height: 1;
    font-size: var(--yazi-govde);
}

.siparis-adet .siparis-miktar {
    width: 58px;
    min-height: 38px;
    text-align: center;
}

/* Sayı kutusunun tarayıcı okları dar ekranda rakamı kırpıyor */
.siparis-miktar::-webkit-outer-spin-button,
.siparis-miktar::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.siparis-miktar { -moz-appearance: textfield; appearance: textfield; }

.siparis-toplam {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .6rem .75rem;
    border-radius: var(--kose);
    background: var(--zemin-renk);
    border: 1px solid var(--kenar-renk);
    font-size: var(--yazi-govde);
}

.siparis-toplam strong {
    font-size: var(--yazi-deger-sm);
    color: var(--primary-color);
}

/* ============================================================
   KATLANIR BÖLÜM (.katlanir-*) — mobilde kapalı, masaüstünde açık
   ============================================================

   SORUN, ÖLÇÜLDÜ (23.09.2026): `ogrenci-detay.php` 390px genişlikte
   4909 piksel, yani 5,8 ekran boyu. Yedi bölüm alt alta duruyor ve
   "Geçmiş Satışlar" tek başına 1538 piksel. Aidat takvimine ulaşmak
   için kullanıcının ilgilenmediği üç bölümü kaydırıp geçmesi gerekiyor.

   BUGÜNKÜ ÇÖZÜM YETERSİZDİ: sayfa masaüstü için bir, mobil için ayrı
   bir HTML basıyordu (`d-lg-none` akordiyon). Aynı bilgi iki kez
   yazıldığı için yalnız iki bölüm (Kişisel, Sağlık) kapanıyordu —
   ötekilerin mobil kopyası hiç yazılmamıştı. İki kopya er geç ayrışır.

   BUNUN YERİNE TEK YAZIM, İKİ DAVRANIŞ:

       <div class="card-header katlanir-baslik" data-bs-toggle="collapse"
            data-bs-target="#x" role="button" aria-expanded="false">
           <h6>Başlık</h6>
           <i class="fas fa-chevron-down katlanir-ok d-lg-none"></i>
       </div>
       <div class="collapse katlanir-govde" id="x">
           <div class="card-body">…</div>
       </div>

   Gövde `collapse` ile yazılır, yani mobilde KAPALI doğar. Aşağıdaki
   kural masaüstünde onu zorla açar. Ekran döndürülünce de doğru
   davranır; JS ile sınıf takas etmeye gerek yok.

   KAPANMAMASI GEREKEN BÖLÜM BU SINIFLARI ALMAZ — sayfanın özeti olan
   kart (profil, istatistik, takvim) kapanırsa sayfa boş açılır. */

@media (min-width: 992px) {
    .katlanir-govde {
        display: block !important;
        height: auto !important;
        visibility: visible !important;
    }

    .katlanir-baslik {
        cursor: default !important;
    }

    /* Izgarada duran katlanır kart kolonu doldurur ki yan yana iki
       sütun eşit boyda dursun. `h-100` sınıfı BU İŞİ TELEFONDA DA
       yapıyordu ve bölüm kapalıyken kartın kendi 1,5rem alt boşluğunu
       kartın İÇİNE alıp her başlığın altında 24 px boş beyaz şerit
       bırakıyordu (ölçüldü: başlık 36 px, kart 60 px). */
    .katlanir-kart {
        height: 100%;
    }
}

.katlanir-baslik {
    cursor: pointer;
}

.katlanir-baslik .katlanir-ok {
    transition: transform .2s ease;
}

.katlanir-baslik[aria-expanded="true"] .katlanir-ok {
    transform: rotate(180deg);
}

/* ============================================================
   AİDAT AY KUTULARI (.aidat-kutu-*) — durum renkleri
   ============================================================

   KURAL NEDEN BURADA: bu sınıflar İKİ YÜZEYDE birden basılıyor —
   `ogrenci-detay.php` (personel) ve `uye-panel.php` (veli). İkisinin de
   kendi kopyası vardı ve kopyalar ÇOKTAN AYRIŞMIŞTI: üye panelinde
   "eksik" kutusu sarı zemin üzerine BEYAZ yazıyordu (≈1,8:1), personel
   panelinde koyu (9,3:1). Aynı veri, iki farklı okunurluk.

   ÖLÇÜLDÜ (23.09.2026): yeşil kutu 2,17:1, kırmızı 3,86:1. WCAG küçük
   metin için 4,5:1 ister — yani yeşil, gerekenin yarısıydı. Bir okul
   yöneticisi "yeşil üzerindeki beyaz yazıları okuyamıyorum" dediğinde
   ölçüm onu doğruladı.

   ÇÖZÜM açık zemin + koyu yazı. Renk kodu korunur (yeşil hâlâ yeşil),
   kontrast 5,7–7,4:1'e çıkar. Punto ve kalınlık da artırıldı: az gören
   göz için kontrast kadar boyut da belirleyicidir.

   İKİNCİ TUR (24.09.2026): aynı takvim için "okunmuyor" geri dönüşü bir
   kez daha geldi. Yazı RENKLİ koyuydu (yeşil zeminde koyu yeşil vb.);
   düz koyu metne (`--yazi-renk`) çevrildi ve kontrast 12,6–13,9:1'e
   çıktı. Rengin metinde tekrarlanmasına gerek yok — ZEMİN zaten durumu
   söylüyor, metnin tek işi okunmak. Siyah (15,4:1) ve gri (4,69:1)
   kutular beyaz yazıyla kalır; ikisi de eşiği geçiyor ve renkli
   kutulardan ayrı durmaları isteniyor (kullanıcı kararı).

   DURUM RENKLERİ BURADA, KUTU ÖLÇÜLERİ SAYFADA KALIR: iki yüzeyin kutu
   yüksekliği ve iç boşluğu farklı (54px / 60px) ve öyle kalmalı. Ortak
   olan anlamdır, geometri değil. */

.aidat-kutu-odendi {
    background-color: var(--basari-acik) !important;
    color: var(--yazi-renk) !important;
}

.aidat-kutu-odenmedi {
    background-color: var(--tehlike-acik) !important;
    color: var(--yazi-renk) !important;
}

.aidat-kutu-eksik {
    background-color: var(--uyari-acik) !important;
    color: var(--yazi-renk) !important;
}

/* Tutarı 0 olan ay. Koyu kalır (15,4:1) — eşiği zaten geçiyor ve
   "para yok" durumunu renkli kutulardan ayırır. */
.aidat-kutu-siyah {
    background-color: var(--yazi-renk) !important;
    color: var(--kart-zemin) !important;
}

/* Donuk ya da satış başlamadan önceki ay: tıklanmaz. Gri kalır
   (4,69:1) ve siyahtan ayrı durur — ikisi de griye çevrilseydi iki
   farklı durum tek görünüme düşerdi. */
.aidat-kutu-pasif {
    background-color: var(--yazi-soluk) !important;
    color: var(--kart-zemin) !important;
}

.aidat-kutu-normal {
    background-color: var(--zemin-alt) !important;
    color: var(--yazi-renk) !important;
    border: 1px solid var(--kenar-orta);
}

/* Ay adı ve tutar: punto ve kalınlık. Tutar asıl okunacak veridir. */
.aidat-kutu h6 {
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: 2px;
}

.aidat-kutu p {
    font-size: var(--yazi-kucuk);
    font-weight: 700;
    margin-bottom: 0;
}
