/* EduLive cihaz katmanı: web ve MAUI aynı responsive kuralları kullanır.
   Personel üst barı cihazda 56px; öğrenci görünümü korunur.
   Cihaz bantları yanında erişilebilirlik/konum tabanları da bulunur. */


/* ===========================================================================
   1 · TELEFON BANDI  —  @media (max-width: 640px)
   TASARIM-MOBIL bölüm 5.1 tablosu + 6.1
   ========================================================================= */

@media (max-width: 640px) {

/* --- Dikey süs bütçesi ------------------------------------------------
     ÖLÇÜM (360x780, kart öncesi çerçeve): topbar 70 + .wrap 30 + .au-page 10
     + hero ~140 = ~250 px. Ekranın üçte biri kart göstermeden gidiyordu. */

  /* aurora.css:590 — padding: clamp(30px,5vw,56px) ...; 5vw@360 = 18 -> 30 */
  body.edulive-cihaz .wrap {
    padding-top: 12px;
  }

  /* admin-users.css:11 — padding: 10px 8px 48px; 327 .razor bu sınıfı kullanıyor */
  body.edulive-cihaz .au-page {
    padding-top: 8px;
  }

  body.edulive-cihaz {
    --akn-yan-dolgu: clamp(24px, 4.5vw, 72px);
    --akn-ust-cekme: -12px;
  }

  /* --- Hero (Home.razor.css:4-45) --------------------------------------- */
  /* :5 margin 6px 0 28px */
  body.edulive-cihaz .home-hero {
    margin: 4px 0 12px;
  }/* :16 margin 0 0 12px — kurum + rol bağlamı KORUNUR (çok-kurumlu kullanıcı) */





  /* :25 clamp(28px,4.5vw,42px) -> 4.5vw@360 = 16,2 -> alt sınır 28 px */
  body.edulive-cihaz .home-hero__title {
    font-size: 22px;
    line-height: 1.15;
    margin-bottom: 6px;
  }/* "Çalışma alanınıza hoş geldiniz. Bir bölüm seçerek başlayın." — telefonda
     iki satır yer kaplayan, bilgi taşımayan cümle. */


  /* --- Izgara: TEK SÜTUN -> İKİ SÜTUN -----------------------------------
     KÖK NEDEN (ölçüldü): HubGrid.razor.css:13-17 telefonda
     `grid-template-columns: 1fr` EMREDİYOR. Masaüstü değeri
     `repeat(auto-fill, minmax(360px,1fr))` iki sütunu engellemiyor — kural
     onu bilerek kapatıyor.
     `minmax(0, 1fr)` ŞART: `1fr`in taban değeri `auto`dur; "Planlama ve
     operasyon" gibi uzun bir başlık sütunu genişletip yatay taşma üretir (K2).
     YAN ETKİ (kasıtlı, bedava): `.hub-grid--compact` de bu seçiciyle eşleşir
     (HubGrid.razor:4 iki sınıfı birlikte basar) -> 10 alt hub sayfası da iki
     sütuna geçer. TASARIM-MOBIL P4 madde 1 erken iner. */
  body.edulive-cihaz .hub-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  /* --- Kart (HubCard.razor.css) -----------------------------------------
     ÖLÇÜM: 360 px ekranda kullanılabilir genişlik
       360 - .wrap 2x24 (aurora.css:590) - .au-page 2x8 (admin-users.css:11) = 296
     İki sütun + 10 px boşluk -> sütun = (296-10)/2 = 143 px.
     143 px'lik sütunda 28 px dolgu içeriğe 87 px bırakıyordu. */
  body.edulive-cihaz .hub-card {
    /* :9 min-height 140 -> içerik (başlık 2 satır 37,5 + dolgu 24) = 61,5 */
    min-height: 72px;
    /* :10 padding 28px 28px */
    padding: 12px;
    gap: 8px;
    /* SATIR düzeni (P4/K14): HubCard.razor.css:5-7 sütun + ortalanmış.
       Rota ikonu (bant 7) sütun düzeninde başlığın ÜSTÜNE binerdi ve kartı
       72 -> ~85 px'e çıkarırdı; ölçüm: satır adımı 82 -> 95, ilk ekranda
       tam görünen döşeme 12 -> 10, yani K1'in "modül girişi >= 12" eşiği
       DÜŞERDİ. Satır düzeninde ikon 20 px, başlık 2 satır 37,5 px yan yana:
       içerik yüksekliği değişmez, kart 72 px'te KALIR (ölçüldü). */
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
  }

  /* Satır düzeninde başlık kalan genişliği alır; `min-width: 0` olmadan
     flex öğesinin taban genişliği `auto`dur ve uzun başlık kartı taşırırdı
     (K2 — bölüm 6.2'nin kart içindeki karşılığı). */
  body.edulive-cihaz .hub-card__title {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* :68-75 — 20px/1.25. 15 px başlık 143 px sütunda iki satıra sığar. */
  body.edulive-cihaz .hub-card__title {
    font-size: 15px;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    /* Bölünemeyen uzun bir kelime sütunu taşırmasın (K2 savunması). */
    overflow-wrap: anywhere;
  }

  /* :77-85 — 13,5px x 2 satır. Ekranın dörtte biri açıklama taşıyordu. */
  body.edulive-cihaz .hub-card__desc {
    display: none;
  }

  /* --- Süs: ambient bloblar KAPALI --------------------------------------
     ÖLÇÜM (360 px, bu tur): b1 [-80..483] 203 px · b2 [-142..340] 142 px ·
     b3 [221..635] 275 px taşıyor. Taşan şey içerik değil SÜS.
     `body { overflow-x: hidden }` yetmez — o kural yalnız gövdenin kendi
     taşmasını gizler, taşıran öğe düzeni genişletmeye devam eder.
     Tek seçici hem MainLayout.razor:14-16 hem StudentLayout.razor:18-19'u
     kapatır. Kazanç iki yönlü: taşma biter VE aurora.css:174 `blur(100px)`
     + :178 `will-change: transform` + :190/:198/:210 sonsuz `drift`
     animasyonu her kareden çıkar. Kabul kriterleri K2 + K11. */
  body.edulive-cihaz .blob {
    display: none;
  }
}


/* ===========================================================================
   2 · DOKUNMATİK BANDI  —  @media (hover: none) and (pointer: coarse)
   TASARIM-MOBIL bölüm 6.3 + 6.4
   Dokunmatikte imleç YOKTUR: hover animasyonu hiç oynamaz ama bedeli ödenir.
   ========================================================================= */

@media (hover: none) and (pointer: coarse) {

  /* --- Giriş alanı punto TABANI (K4) -------------------------------------
     iOS, 16 px'in altındaki bir alana odaklanınca sayfayı yakınlaştırır ve
     düzen kayar. Tarayıcının form denetimi varsayılanı 13,33 px'tir ve
     KALITSAL DEĞİLDİR — bu yüzden hiçbir kural yazmayan her input tetikler.
     `:where()` gerekçesi dosya başında (TABAN'dır, TAVAN değil). */
  :where(body.edulive-cihaz) input,
  :where(body.edulive-cihaz) select,
  :where(body.edulive-cihaz) textarea {
    font-size: max(16px, 1rem);
  }

  /* Yukarıdaki TABAN, kural yazmayan alanları kurtarır ama ölçüm gösterdi ki
     uygulamanın ASIL girdi stili ondan güçlü:
       AppField.razor.css:46  ->  `.app-field[b-msg4o1o3ge] .app-input`  (0,3,0)
       font-size: 14.5px  —  giriş ekranı dahil her AppTextField/AppSelect.
     Sıfır özgüllüklü taban (0,0,1) bunu YENEMEZ; canlı ölçümde giriş ekranı
     cihaz katmanına rağmen 14,5 px kalıyordu (iOS odaklanınca yakınlaştırır).
     (0,3,1) ile bilinçli ve YALNIZ bu bilinen-küçük değer yükseltilir:
     14,5 -> 16. Kutu yüksekliği sabit 46 px (AppField.razor.css:52), taşma yok. */
  body.edulive-cihaz .app-field .app-input {
    font-size: max(16px, 1rem);
  }

  /* --- Hover bedeli ------------------------------------------------------
     HubCard.razor.css:21-25 üç özellikli geçiş + :48-56 translateY(-5px).
     Dokunmatikte :hover tıklamadan sonra YAPIŞIR (WebKit) — kart havada kalır. */
  body.edulive-cihaz .hub-card {
    transition: none;
  }

  body.edulive-cihaz .hub-card:hover {
    transform: none;
    border-color: color-mix(in srgb, var(--hub-ton) 34%, transparent);
    box-shadow: none;
  }

  /* :28-46 — iki radial-gradient katman, yalnız hover'da görünür. */
  body.edulive-cihaz .hub-card__glow {
    display: none;
  }

  body.edulive-cihaz .topbar-tenant:hover {
    transform: none;
  }

  /* Blob'un kapatılmadığı TEK dokunmatik hâl: >= 1280 px dokunmatik ekran
     (büyük dokunmatik monitör / 12,9 inç iPad manzarası 1366 px). Orada web
     düzeni çizilir ve blob görünür kalır — ama animasyon bedeli ödenmez.
     `will-change` tarayıcıya "ayrı katmana al" der; imleç olmayan ekranda
     `drift` hiç oynamaz, katman yine de bellekte durur.
     Telefon (bant 1) ve tablet (bant 3) zaten `display: none` yazar; bu kural
     onlar için ölü değildir, sadece etkisizdir — kaldırılırsa 1280+ dokunmatik
     ekran animasyonu geri kazanır. */
  body.edulive-cihaz .blob {
    animation: none;
    will-change: auto;
  }

  /* --- Dokunma hedefi tabanı (K3) ----------------------------------------
     ÖLÇÜM (360x780 ana ekran): .brand 38x38 (aurora.css:253-255 .brand-logo),
     .icon-btn 42x42 (:432-433), .avatar 42x42 (:461-462),
     .topbar-tenant yükseklik 42 (:385). Dördü de 44 px eşiğinin altında.
     56 px'lik personel üst barında 44 px sığar. (TASARIM-MOBIL P3 madde 3'ün ana ekranı
     ilgilendiren kısmı; kalan 410 ekranlık süpürme P3'te.) */
  body.edulive-cihaz .brand,
  body.edulive-cihaz .avatar,
  body.edulive-cihaz .topbar-tenant {
    min-width: 44px;
    min-height: 44px;
  }
}


/* ===========================================================================
   3 · TABLET BANDI  —  641-1023px  +  1024-1279px YALNIZ dokunmatik
   TASARIM-MOBIL bölüm 5.4 (paket P3) — kabul kriteri K8

   NEDEN İKİ SORGULU
   Tablet bir GENİŞLİK değil, bir CİHAZ SINIFIDIR. 1024 ve 1194 px'in ikisi de
   iPad'dir (12,9 inç portre / 11 inç manzara) ama eski tek-sorgulu bant onları
   masaüstü sayıyordu. İkinci sorgu yalnız `pointer: coarse` ile açılır: aynı
   genişlikteki bir Mac Catalyst penceresi fare taşır, eşleşmez. Tavan 1279 —
   gerekçesi dosya başındaki masaüstü sözleşmesinde.

   ÖLÇÜM (P3 öncesi, 834x1112, dokunmatik):
     ızgara `361px 361px` = 2 sütun · kart 361x140 · taşan öğe 2 · K1 20/11
   ÖLÇÜLEN kullanılabilir genişlik (aurora.css:590 `.wrap` yanları
   clamp(24px,4.5vw,72px) + admin-users.css:11 `.au-page` yanları 8px):
     744 -> 661 px · 834 -> 743 px · 1024 -> 906 px · 1194 -> 1066 px
   ========================================================================= */

@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- Izgara: 2 -> 3 sütun ----------------------------------------------
     HubGrid.razor.css:5 masaüstü değeri `minmax(360px, 1fr)`; 743 px'lik bir
     iPad portresinde `floor((743+20)/380) = 2` sütun verir — spec bölüm 5.4'ün
     aritmetiği. `minmax(210px,1fr)` + 12 px boşlukla aynı genişlik
     `floor((743+12)/222) = 3` sütun verir.
     `auto-fill` KORUNDU (sabit `repeat(3,...)` DEĞİL): kart genişliği sabit
     kalır, sütun sayısı ekranla büyür — 641 px'te 2, 744'te 3, 1024/1194'te 4.
     Sabit 3 yazılsaydı 641 px'te sütun 200 px'in altına inip açıklama satırını
     ezerdi (tablette açıklama GÖRÜNÜR kalıyor, bölüm 5.4).
     210 px alt sınırı ölçümle seçildi, yuvarlak sayı olduğu için değil:
     744 px'in 3 sütunu için gereken tavan (661-24)/3 = 212,3 px.
     `.hub-grid--compact` de bu seçiciyle eşleşir (HubGrid.razor:4 iki sınıfı
     birlikte basar) -> 10 alt hub sayfası tablette de yoğunlaşır. */
  body.edulive-cihaz .hub-grid {
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 12px;
  }

  /* HubCard.razor.css:9-10 — 140 px / 28 px dolgu, 361 px'lik sütun içindi.
     ~215 px'lik sütunda 28 px dolgu içeriğe 159 px bırakıyor; 18 px bırakır
     179. min-height 110: başlık 2 satır (42) + boşluk 8 + açıklama 2 satır
     (34) + dolgu 36 = 120 -> min-height bağlayıcı değil, TABAN'dır. */
  body.edulive-cihaz .hub-card {
    min-height: 110px;
    padding: 18px;
  }

  /* :68-75 — 20px/1.25. 20 px başlık 179 px'lik içerik kutusunda "Planlama ve
     operasyon"u 3 satıra kırıyordu; 17 px 2 satıra sığdırır. Açıklama
     KAPATILMAZ (telefonun aksine) — tablette dikey bütçe var. */
  body.edulive-cihaz .hub-card__title {
    font-size: 17px;
    line-height: 1.25;
    overflow-wrap: anywhere;
  }

  /* --- Süs: bloblar tablette de KAPALI (P1'den beri açık olan K2 borcu) ---
     ÖLÇÜM (834x1112, bu tur): b1 [394..954] 120 px, b2 [-140..340] 140 px
     taşıyor; üç blob da `filter: blur(100px)` ile canlı (aurora.css:174).
     P1 bunları yalnız telefonda kapatmıştı, tablet bandı hiç yazılmamıştı;
     spec bölüm 5.4 "tablette görünür kalır" diyordu ama gerekçesi
     ölçülmemişti. Ölçüldü: kazanç telefondakiyle AYNI (K2 2 -> 0, üç
     blur katmanı kalkıyor), bedel aynı süs. Masaüstünde (>= 1280) blob
     GÖRÜNÜR kalır — orası web'in kendi tasarımıdır, dokunulmaz (K9). */
  body.edulive-cihaz .blob {
    display: none;
  }
}


/* ===========================================================================
   4 · ÇUBUK BANDI  —  <= 1023px  +  1024-1279px YALNIZ dokunmatik
   ALT GEZİNME ÇUBUĞU + "Diğer" sayfası — TASARIM-MOBIL bölüm 4 (paket P2)

   NEDEN AYRI BİR BANT
   Çubuk hem telefonda hem tablette görünür (bölüm 3.3 tablosu: iki bandın da
   kapsamında "sekme çubuğu" yazılı), masaüstünde GÖRÜNMEZ.

   P3 DÜZELTMESİ — ölçülen kusur: sorgu yalnız `max-width: 1023px` iken 11 inç
   iPad portrede (834) çubuğu gösterip MANZARADA (1194) gizliyordu; kullanıcı
   tableti çevirince gezinme kayboluyordu. İkinci sorgu bunu kapatır ve YALNIZ
   dokunmatikte açılır: aynı genişlikteki fareli pencere (Mac Catalyst,
   masaüstü tarayıcı) eşleşmez. >= 1280 px'te blok imleç türünden bağımsız
   olarak HİÇ eşleşmez — K9 korunur (kanıt: 1280/1920 ölçümü hem fare hem
   dokunmatik öykünmesiyle `display: none`).

   TABANI BURADA DEĞİL: `.cihaz-sekme{display:none}` css/app.css'tedir
   (gerekçe orada). Bu blok yalnız AÇAR ve biçimlendirir.

   ÖLÇÜM (360x780, TASARIM-MOBIL 7.1 sonrası durum): P1 sonunda ızgaraya kalan
   dikey alan 629 px'ti. Çubuk 56 px + iPhone ev çubuğu 34 px = 90 px alınca
   539 px kalır; satır adımı 82 px (kart 72 + boşluk 10) ->
   floor((539+10)/82) = 6 satır x 2 sütun = 12 döşeme. K1 = 12 döşeme
   + 5 sekme + 4 üst-bar öğesi = 21 (eşik >= 16 toplam / >= 12 modül girişi).
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- Ölçü sözleşmesi ---------------------------------------------------
     Tek yerden değişsin diye özel özellik. `--sekme-alt` GÜVENLİ ALAN'dır
     (kabul kriteri K6): iOS'ta ev çubuğu 34 px, Android jest çubuğunda
     WebView'ın bildirdiği kadar, ikisi de yoksa 0. Yedek değer ŞART —
     env() desteklenmezse `calc()` tamamen geçersiz olur ve çubuk yüksekliğini
     kaybederdi. */
  body.edulive-cihaz {
    --sekme-h: 56px;
    --sekme-alt: env(safe-area-inset-bottom, 0px);
  }

  /* --- Çubuk -------------------------------------------------------------
     z-index 65 SEÇİLMİŞ bir sayıdır, uydurma değil (bu turda tüm CSS tarandı):
       topbar 50 · sayfa içi açılırlar 55-61 · hesap menüsü 70 ·
       modal/diyalog 80-92 · toast 1000.
     65: içeriğin ve açılırların ÜSTÜNDE (çubuk kromdur, kaybolmamalı),
     menü ve diyalogların ALTINDA (tam ekran bir diyalog çubuğu örtmeli).

     backdrop-filter KULLANILMADI (M10): üst bar zaten blur(22px) taşıyor,
     ekranın altına ikinci bir bulanıklık katmanı eklemek dokunmatikte her
     karede yeniden hesap demekti. Opak zemin aynı işi bedelsiz yapıyor. */
  body.edulive-cihaz .cihaz-sekme {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 65;
    height: calc(var(--sekme-h) + var(--sekme-alt));
    padding-bottom: var(--sekme-alt);
    background: var(--yuzey);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 22px -12px var(--scrim);
  }

  /* Yuva: 5 eşit parça. `minmax(0,...)` yerine `min-width: 0` — flex öğesinin
     taban genişliği `auto`dur ve uzun bir etiket ("Planlama") satırı taşırırdı
     (K2, bölüm 6.2'nin ızgaradaki karşılığı).
     360 px'te yuva = 72 px; yükseklik 56 px -> dokunma hedefi 72x56, K3 eşiği
     44 px'in üstünde. */
  body.edulive-cihaz .cihaz-sekme__yuva {
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 0 2px;
    border: 0;
    background: transparent;
    color: var(--muted);
    text-decoration: none;
    font-family: var(--font-body);
    font-size: var(--yazi-sekme, 10.5px);
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    position: relative;
  }

  body.edulive-cihaz .cihaz-sekme__ikon {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
  }

  body.edulive-cihaz .cihaz-sekme__ikon svg {
    width: 22px;
    height: 22px;
    display: block;
  }

  /* Tek satır, taşarsa kısaltılır — "Planlama" 72 px'e sığar, sığmayan bir
     etiket gelirse sütunu genişletmek yerine üç nokta ile kesilir. */
  body.edulive-cihaz .cihaz-sekme__etiket {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* --- Aktif yuva göstergesi (K6) ----------------------------------------
     İKİ kanal birden: renk + üstte 3 px'lik çizgi. Yalnız renk bırakılsaydı
     renk körlüğünde tek ayırt edici kalmazdı; yalnız çizgi bırakılsaydı
     22 px'lik ikonun yanında zayıf kalırdı. */
  body.edulive-cihaz .cihaz-sekme__yuva.is-etkin {
    color: var(--marka-600);
    font-weight: 700;
  }

  body.edulive-cihaz .cihaz-sekme__yuva.is-etkin::before {
    content: "";
    position: absolute;
    top: 0;
    left: calc(50% - 14px);
    width: 28px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--basari);
  }

  /* --- İçeriğin altına çubuk kadar pay ------------------------------------
     ÖLÇÜM: aurora.css:590 `.wrap` alt dolgusu 80 px, StudentLayout.razor.css:142
     `.student-wrap` 64 px. İkisi de 90 px'lik çubuğun altında kalırdı; sayfanın
     son satırı çubuğun arkasına girer ve dokunulamazdı. */
  body.edulive-cihaz .wrap,
  body.edulive-cihaz .student-wrap {
    padding-bottom: calc(var(--sekme-h) + var(--sekme-alt) + 16px);
  }

  /* =========================================================================
     "DİĞER" SAYFASI (sheet) — TASARIM-MOBIL bölüm 4.5
     13 kart + 5 kısayol tek dokunuş uzağa iner (K7).
     ======================================================================= */

  body.edulive-cihaz .cihaz-sheet__perde {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 78;
    background: var(--scrim);
  }

  /* 78/79: çubuğun (65) ve hesap menüsünün (70) ÜSTÜNDE, kurum değiştirme
     modalinin (80) ALTINDA. Kendi kromumuz başkasının modalini örtmemeli. */
  @keyframes cihazSekmeSayfa {
    from { opacity: 0; transform: translateY(16px); }
    to { opacity: 1; transform: translateY(0); }
  }

  body.edulive-cihaz .cihaz-sheet {
    display: flex;
    flex-direction: column;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 79;
    max-height: 76dvh;
    padding: 8px 14px calc(var(--sekme-h) + var(--sekme-alt) + 14px);
    background: var(--yuzey);
    border-radius: var(--kose-sayfa);
    box-shadow: 0 -18px 44px -16px var(--scrim);
    animation: cihazSekmeSayfa 0.2s var(--ease-smooth);
  }

  body.edulive-cihaz .cihaz-sheet__tut {
    width: 38px;
    height: 4px;
    margin: 2px auto 8px;
    border-radius: 999px;
    background: var(--n-300);
  }

  body.edulive-cihaz .cihaz-sheet__bas {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 0 0 auto;
    padding: 4px 0 12px;
    margin-bottom: 8px;
    border-bottom: 3px solid var(--basari);
  }

  body.edulive-cihaz .cihaz-sheet__baslik {
    margin: 0;
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 700;
    color: var(--marka-700);
  }

  /* Kapat: 36 px görsel kutu, çevresinde 44 px dokunma alanı. */
  body.edulive-cihaz .cihaz-sheet__kapat {
    position: relative;
    height: 36px;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    border: 1px solid var(--hat-girdi);
    border-radius: var(--kose-dugme);
    background: var(--yuzey);
    color: var(--marka-600);
    font: 600 13px var(--font-body);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  body.edulive-cihaz .cihaz-sheet__kapat::after {
    content: "";
    position: absolute;
    inset: -4px;
  }

  /* Tek liste; uzun bölüm adları satır içinde sarılır. */
  body.edulive-cihaz .cihaz-sheet__izgara {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  body.edulive-cihaz .cihaz-sheet__giris {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 48px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--hat-kart);
    border-left: 3px solid transparent;
    background: var(--yuzey);
    color: var(--fg);
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
    overflow-wrap: anywhere;
  }

  body.edulive-cihaz .cihaz-sheet__ikon {
    display: grid;
    place-items: center;
    flex: 0 0 18px;
    color: inherit;
  }

  body.edulive-cihaz .cihaz-sheet__ikon svg {
    width: 18px;
    height: 18px;
    display: block;
  }

  body.edulive-cihaz .cihaz-sheet__etiket {
    flex: 1;
    min-width: 0;
  }

  body.edulive-cihaz .cihaz-sheet__giris.is-etkin {
    color: var(--marka-600);
    font-weight: 700;
    border-left-color: var(--basari);
    background: color-mix(in srgb, var(--marka-500) 6%, var(--yuzey));
  }

  body.edulive-cihaz .cihaz-sheet__secili {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
  }

}


@media (prefers-reduced-motion: reduce) {
  body.edulive-cihaz .cihaz-sheet {
    animation: none;
  }
}

/* ===========================================================================
   5 · DOKUNMATİK BANDI — ÇUBUĞA ÖZGÜ EK
   Bant 2 ile aynı sorgu; ayrı blok çünkü P2'nin işi ve gerekçesi ayrı.
   ========================================================================= */

@media (hover: none) and (pointer: coarse) {

  /* Bu iki öğeye HİÇ :hover kuralı yazılmadı — dokunmatikte imleç yoktur ve
     WebKit'te :hover tıklamadan sonra yapışır, aktif göstergesiyle (K6)
     yarışırdı. Geri bildirim :active ile verilir; doğru olay odur. */
  body.edulive-cihaz .cihaz-sekme__yuva:active,
  body.edulive-cihaz .cihaz-sheet__giris:active {
    opacity: 0.6;
  }
}

/* ===========================================================================
   6 · DOKUNMA HEDEFİ SÜPÜRMESİ  —  @media (hover: none) and (pointer: coarse)
   TASARIM-MOBIL bölüm 7 / kabul kriteri K3 (paket P3, 3. madde)

   NEDEN AYRI BİR BLOK
   Bant 2 üst barın DÖRT öğesini elle 44 px'e çekmişti. Burada kalan 410 ekran
   var; tek tek gezmek mümkün değil, bu yüzden SINIF BAZLI süpürüldü.

   ÖLÇÜM (P3, 360 px, dokunmatik; yöntem: 508 .razor dosyasındaki her
   <button>/<a>/<summary> ögesi ailelere kümelendi -> 253 aile / 1966 markup
   örneği; her ailenin gerçek örneği kapsam özniteliğiyle birlikte gerçek
   dağıtım CSS'inde çizildi ve ölçüldü):
     44 px'in ALTINDA olan aile        : 173  (markup örneği 1820 = %92,6)
     en kalabalık üçü:
       button.au-btn      996 örnek  114,6 x 36     (admin-users.css:66 · 9px dolgu)
       a.au-btn           300 örnek   99,6 x 38,3
       a.au-breadcrumb    267 örnek   65,1 x 19,5   (admin-users.css:51 · dolgusuz)
   Bu üç aile tek başına tüm etkileşimli işaretlemenin %79,5'i.

   NEDEN GENEL SEÇİCİ, NEDEN 173 AİLE TEK TEK DEĞİL
   173 aileyi elle yazmak 173 satırlık bir sapma kaynağıdır: yarın eklenen
   174. aile kapsam dışı kalır. `min-height` YÜKSELTİR, asla düşürmez —
   zaten 44'ün üstünde olan hiçbir öge etkilenmez (ölçüldü: 80 aile
   değişmedi). Genişliğe DOKUNULMAZ: `min-width` yatay taşma üretebilirdi
   (K2), o yüzden yalnız ölçülmüş dar ikon düğmelerine verilir.

   `min-height` SATIR İÇİ (inline) bağlantılara UYGULANMAZ — CSS'in kendi
   kuralı: "applies to: all elements but non-replaced inline elements".
   Bu bir kayıp değil kazanç: paragraf içindeki metin bağlantısını 44 px'e
   şişirmek metni bozardı ve WCAG 2.5.8 zaten "inline" istisnası tanır.
   Düğme gibi davranan bağlantılar (inline-flex/block) kuralı ALIR.
   ========================================================================= */

@media (hover: none) and (pointer: coarse) {

  /* --- Genel taban: dikey ------------------------------------------------
     `a[href]`: yalnız gerçekten gidilebilir bağlantılar. `<a>` ismi çıpa
     olarak da kullanılır (href'siz), onun dokunma hedefi yoktur.

     `:where()` ZORUNLU — ölçüm bir gerileme yakaladı (tahminle kaçardı):
     ilk yazımı `body.edulive-cihaz a[href]` idi ve bu (0,2,2) özgüllüktedir
     (öznitelik seçicisi SINIF ağırlığındadır: .edulive-cihaz + [href] = 2
     sınıf, body + a = 2 öge). O da `body.edulive-cihaz .hub-card` (0,2,1) ve
     `.hub-card[b-…]` (0,2,0) kurallarını EZDİ:
        telefonda kart 143x72 -> 143x45  ·  tablette 110 -> 108
        1280 px DOKUNMATİK ekranda 370x140 -> 370x111  = K9 ihlali
     `:where()` içeriği 0 sayar; kural (0,1,1)'e iner: kendi bileşen kuralları
     (0,2,0) ve cihaz katmanının kendi kararları (0,2,1) korunur, yalnız
     hiçbir yükseklik yazmayan düğmeler yükselir. TABAN'dır, TAVAN değil —
     dosya başındaki `:where()` istisnasının ikinci uygulaması. */
  body.edulive-cihaz :where(button, a[href], summary, [role="button"]) {
    min-height: 44px;
  }

  body.edulive-cihaz a.au-breadcrumb--dugme {
    min-height: 0;
  }

  body.edulive-cihaz .az-sayfa .au-head .ar-ac {
    min-width: 0;
    min-height: 0;
  }
  /* SINIRI (Tur 33'te ölçüldü): `min-height` SATIR İÇİ (`display:inline`)
     öğede ETKİSİZDİR — kural uygulanır ama kutu büyümez. Örnek:
     /akademik/seviye-sistemleri'nde sınıfsız bir `a` 335x38 ölçüldü,
     computed `min-height: 44px` olmasına rağmen. Buraya `display:inline-flex`
     EKLENMEDİ: bu bant tüm bağlantıları kapsar ve satır içi metin
     bağlantılarını bloklaştırmak metin akışını bozardı (§13.12 zaten satır
     içi metin bağlantısını "kusur değil" saymıştı). Bir bağlantı GERÇEKTEN
     dokunma hedefiyse kendi bandında `display:inline-flex` ile yükseltilir —
     BANT 14.1 ve 15.1 bunu böyle yapar. */

  /* --- Kendi `min-height`ını yazan İKİ aile (özgüllük) --------------------
     Genel taban (0,1,1) kapsamlı bir bileşen kuralına (0,2,0) yenilir.
     Tüm CSS tarandı: etkileşimli bir seçiciye 44'ün ALTINDA `min-height`
     yazan yalnız şunlar var (geri kalanlar zaten `var(--st-touch, 44px)`):
       .bbt-arac      calc(var(--bbt-u) * 2.1) -> 360 px'te --bbt-u 16px
                      (clamp(16px, .9rem+.35vw, 24px)) => 33,6 px
       .td-revise-btn 32px
     Kalan üçü IZGARA HÜCRESİ'dir ve burada DÜZELTİLMEZ — gerekçe aşağıda. */
  body.edulive-cihaz .bbt-arac,
  body.edulive-cihaz .td-revise-btn {
    min-height: 44px;
  }

  /* --- Dar İKON düğmeleri: yatay taban -----------------------------------
     Yalnız ÖLÇÜLMÜŞ ailelere verilir (genel `min-width` dar ekranda yatay
     taşma üretirdi — K2). Yukarıdaki dikey taban bunların yüksekliğini
     zaten 44'e çekti; kalan kusur GENİŞLİK. Ölçülen değerler (360 px,
     dokunmatik, kapsam öznitelikleriyle): hepsi ikon ya da tek karakter
     taşıyan düğmelerdir, metin genişliği yoktur.
       .at-ipucu__ac 14 · .app-toggle 16,7 · .pf-chip__x 16 · .cp__chip-x 18
       .ks__chip-x 18 · .me-imglink 18,8 · .app-tree__chev 20 · .aa-rozet__kapat 20,2
       .ks__toggle 22 · .as-satir__sil 24 · .toast__close 26 · .ag-buyut 28
       .aa-ikon 28 · .as-kapat 28 · .lre-ico 30 · .sde-ico 30 · .ctw-remove 30
       .aa-panel__kapat 30 · .sum-close 30 · .aas__sifirla 32,3 · .au-chip 33,6
       .ts-modal__close 34 · .aa-gonder 36 · .bbt-tkv-x 36 · .nbell__btn 38
       .grid-pager__btn 38 · .qh-pager__btn 38 · .bbt-kartvizit__link 40,3
       .ahs-yenile 41,9 · .bbt-kartvizit__kapat 32 · .nc-pager__btn 33 */
  body.edulive-cihaz .aa-gonder,
  body.edulive-cihaz .aa-ikon,
  body.edulive-cihaz .aa-panel__kapat,
  body.edulive-cihaz .aa-rozet__kapat,
  body.edulive-cihaz .aas__sifirla,
  body.edulive-cihaz .ag-buyut,
  body.edulive-cihaz .ahs-yenile,
  body.edulive-cihaz .app-ms__x,
  body.edulive-cihaz .app-toggle,
  body.edulive-cihaz .app-tree__chev,
  body.edulive-cihaz .ar-ac,
  body.edulive-cihaz .as-kapat,
  body.edulive-cihaz .as-satir__sil,
  body.edulive-cihaz .at-ipucu__ac,
  body.edulive-cihaz .au-chip,
  body.edulive-cihaz .bbt-kartvizit__kapat,
  body.edulive-cihaz .bbt-kartvizit__link,
  body.edulive-cihaz .bbt-tkv-x,
  body.edulive-cihaz .cp__chip-x,
  body.edulive-cihaz .ctw-remove,
  body.edulive-cihaz .grid-pager__btn,
  body.edulive-cihaz .ks__chip-x,
  body.edulive-cihaz .ks__toggle,
  body.edulive-cihaz .lre-ico,
  body.edulive-cihaz .me-imglink,
  body.edulive-cihaz .nbell__btn,
  body.edulive-cihaz .nc-pager__btn,
  body.edulive-cihaz .pf-chip__x,
  body.edulive-cihaz .qh-pager__btn,
  body.edulive-cihaz .sde-ico,
  body.edulive-cihaz .sum-close,
  body.edulive-cihaz .toast__close,
  body.edulive-cihaz .ts-modal__close {
    min-width: 44px;
  }

  /* --- Sekme şeridi bağlantısı: satır içi -> inline-flex ------------------
     `.cd-tab` bir <nav class="cd-tabs"> içindeki sekme bağlantısıdır
     (CourseDetail.razor:74-76) ama `display: inline` kalmış; ölçüldü 116,8x37
     ve satır içi olduğu için `min-height` ona UYGULANMIYORDU. Metin bağlantısı
     değil, sekme — bu yüzden istisna listesine değil buraya yazıldı.
     `inline-flex` düzeni değiştirmez (kap zaten flex şerit), yalnız
     yüksekliği bağlayıcı yapar. */
  body.edulive-cihaz .cd-tab {
    display: inline-flex;
    align-items: center;
  }

  /* --- SÜPÜRÜLMEYENLER (bilerek; kararı frontend-3'ün) --------------------
     ⚠ 1. MADDE ARTIK GEÇERSİZ — 9. bant onu ÖLÇÜMLE kapattı (2026-08-24).
     Aşağıdaki gerekçe tarihsel kayıt olarak duruyor; çürüyen kısmı şudur:
     `.av-cell` ve `.jft-cell`in kabı ZATEN kayıyormuş (`.av-grid-wrap` /
     `.jft-grid-wrap` `overflow-x: auto`), `.sis-togrid__cell`e kabını da
     8. bant verdi. Üçü de 44 px'e çıktı, yatay taşma 0 kaldı.
     1) IZGARA HÜCRELERİ — `.sis-togrid__cell` 26x22 (SisTimeoffGrid, haftalık
        müsaitlik tablosu) · `.av-cell` min-height 40 (planlama.css) ·
        `.jft-cell` 42. Bunlar bir TABLONUN hücresidir: 44 px'e çekmek sütun
        sayısı kadar çarpılır (10 periyot x 44 = 440 px > 360) ve K2'yi
        ihlal eden yatay taşma üretir. Doğru çözüm hücreyi büyütmek değil,
        tabloyu KENDİ KABINDA kaydırılabilir yapmaktır — bu bir işaretleme
        değişikliğidir, CSS ezmesiyle güvenle yapılamaz. frontend-3 onayı
        gerekir; burada YAPILMADI.
     2) SATIR İÇİ METİN BAĞLANTILARI — ölçümde kalan 69 ailenin 46'sı
        `display: inline` (`a.xx-link` biçiminde tablo hücresi bağlantıları,
        aile başına 1-2 örnek). CSS'in kendi kuralı gereği `min-height`
        onlara uygulanmaz; uygulanabilseydi bile satır kutusunu şişirip
        metni bozardı. WCAG 2.5.8 bu hâl için "inline" istisnası tanır. */
}

/* ===========================================================================
   7 · ROTA İKONLARI  —  <= 1023px  +  1024-1279px YALNIZ dokunmatik
   TASARIM-MOBIL bölüm 5.3 (paket P4) — kabul kriteri K14

   NEDEN
   İkonlar HubCard'dan 2026-07-13'te kaldırılmış (`HubCard.razor:1-4`) ve
   `ChildContent` render EDİLMİYOR (`:26`). İki sütunlu, açıklamasız,
   ikonsuz bir ızgara bir METİN DUVARIDIR. Bileşen salt-okunur (K-1), ama
   `HubCard.razor:6` `href`'i DOM'a birebir yazıyor -> öznitelik seçicisi
   çalışır. Bu saf CSS'tir: DOM'a dokunmaz, Blazor'un fark hesabıyla
   çakışmaz, frontend-3 istisnası GEREKTİRMEZ.

   TUTARLILIK (görevin şartı): 13 glifin SEKİZİ alt gezinme çubuğundan
   BİREBİR alındı — aynı rota, aynı çizim. Kalan beşin sekmede karşılığı yok,
   bu turda aynı dille yazıldı (24x24 kutu, stroke 1.8, yuvarlak uç).
   Kaynak her kuralın üstünde yazılı; sekme ikonu değişirse burası da elle
   güncellenir (tek doğruluk kaynağı `SekmeCubugu.razor` sabitleridir).

   NEDEN MASKE, NEDEN DIŞ DOSYA DEĞİL
   `mask-image` + `background-color: currentColor` glifi metin rengiyle
   boyar: aktif/pasif durum, tema değişimi bedava gelir. Her glif `--rota-ikon`
   özel özelliğinde BİR KEZ durur, `-webkit-` ve öneksiz biçim onu var() ile
   okur (aksi hâlde 13 URI iki kez yazılırdı: 7,4 KB -> 3,7 KB). Dış dosya
   eklenmedi,
   ağ isteği 0, emoji kullanılmadı (platforma göre değişir, kurumsal
   dilimizde yeri yok).

   RİSK (dürüstçe): rota yeniden adlandırılırsa ikon SESSİZCE kaybolur,
   kart çalışmaya devam eder (güvenli başarısızlık). K14 bunu yakalar:
   13 seçicinin 13'ü eşleşmeli.

   ÖLÇÜM: telefonda kart 143x72'de KALDI (satır düzeni, aşağıdaki gerekçe),
   tablette 110 -> 119 px.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* Taban YALNIZ bu 12 rotaya verilir. `.hub-card[href]` gibi genel bir
     seçici yazılsaydı, ikonu olmayan 10 alt hub sayfasının kartlarında
     20 px'lik BOŞ bir kutu açardı (ölçülmeden fark edilmezdi). */
  body.edulive-cihaz .hub-card[href="/yonetim"]::before,
  body.edulive-cihaz .hub-card[href="/akademik"]::before,
  body.edulive-cihaz .hub-card[href="/mufredat"]::before,
  body.edulive-cihaz .hub-card[href="/analiz"]::before,
  body.edulive-cihaz .hub-card[href="/planlama"]::before,
  body.edulive-cihaz .hub-card[href="/content-studio"]::before,
  body.edulive-cihaz .hub-card[href="/medya-studyo"]::before,
  body.edulive-cihaz .hub-card[href="/sosyal-medya"]::before,
  body.edulive-cihaz .hub-card[href="/yayinci"]::before,
  body.edulive-cihaz .hub-card[href="/gorev-onay"]::before,
  body.edulive-cihaz .hub-card[href="/finans"]::before,
  body.edulive-cihaz .hub-card[href="/ogrenci"]::before {
    content: "";
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    background-color: currentColor;
    opacity: 0.85;
    -webkit-mask-image: var(--rota-ikon);
    mask-image: var(--rota-ikon);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
  }

  /* P3'te yazıldı — sekmede karşılığı yok */
  body.edulive-cihaz .hub-card[href="/yonetim"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8.4' r='3.4'/%3E%3Cpath d='M2.8 20.2c0-3.4 3-5.2 6.2-5.2s6.2 1.8 6.2 5.2'/%3E%3Cpath d='M16.4 5.4a3.4 3.4 0 0 1 0 6.8'/%3E%3Cpath d='M17.8 15.4c2.1.6 3.4 2 3.4 4.6'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:331 IkonAkademik */
  body.edulive-cihaz .hub-card[href="/akademik"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 4 9 4.3-9 4.3-9-4.3z'/%3E%3Cpath d='M7 11v4.4c0 1.2 2.2 2.2 5 2.2s5-1 5-2.2V11'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:332 IkonMufredat */
  body.edulive-cihaz .hub-card[href="/mufredat"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 4.6A1.6 1.6 0 0 1 6.6 3H19v18H6.6A1.6 1.6 0 0 1 5 19.4z'/%3E%3Cpath d='M9 3v18'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:333 IkonAnaliz */
  body.edulive-cihaz .hub-card[href="/analiz"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 20v-7'/%3E%3Cpath d='M12 20V4.5'/%3E%3Cpath d='M19.5 20v-10'/%3E%3Cpath d='M3 20h18'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:334 IkonPlanlama */
  body.edulive-cihaz .hub-card[href="/planlama"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5' width='17' height='15.5' rx='2.2'/%3E%3Cpath d='M8 3.2v3.6M16 3.2v3.6M3.5 10.4h17'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:330 IkonStudyo */
  body.edulive-cihaz .hub-card[href="/content-studio"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 3.2 2.2 5.1 5.1 2.2-5.1 2.2L12 17.8l-2.2-5.1-5.1-2.2 5.1-2.2z'/%3E%3Cpath d='M18.5 16.5 19 18l1.5.5L19 19l-.5 1.5L18 19l-1.5-.5L18 18z'/%3E%3C/svg%3E");
  }

  /* P3'te yazıldı */
  body.edulive-cihaz .hub-card[href="/medya-studyo"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2.2'/%3E%3Ccircle cx='8.6' cy='10' r='1.7'/%3E%3Cpath d='m4.2 17.6 4.8-4.5 3.4 3 3-2.4 4.4 3.9'/%3E%3C/svg%3E");
  }

  /* P3'te yazıldı */
  body.edulive-cihaz .hub-card[href="/sosyal-medya"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='17.4' cy='5.8' r='2.6'/%3E%3Ccircle cx='6.6' cy='12' r='2.6'/%3E%3Ccircle cx='17.4' cy='18.2' r='2.6'/%3E%3Cpath d='m8.9 10.7 6.2-3.6M8.9 13.3l6.2 3.6'/%3E%3C/svg%3E");
  }

  /* P3'te yazıldı */
  body.edulive-cihaz .hub-card[href="/yayinci"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9.6 5.3 4.6h13.4L20 9.6'/%3E%3Cpath d='M4.6 9.6v9.8h14.8V9.6'/%3E%3Cpath d='M9.8 19.4v-5.2h4.4v5.2'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:336 IkonGorev */
  body.edulive-cihaz .hub-card[href="/gorev-onay"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='4.2' width='17' height='16.4' rx='2.2'/%3E%3Cpath d='m8.2 12.4 2.7 2.7 5-5.6'/%3E%3C/svg%3E");
  }

  /* P3'te yazıldı */
  body.edulive-cihaz .hub-card[href="/finans"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5.8' width='18' height='12.6' rx='2.4'/%3E%3Cpath d='M3 10.2h18'/%3E%3Ccircle cx='16.8' cy='14.6' r='1.2'/%3E%3C/svg%3E");
  }

  /* SekmeCubugu.razor:335 IkonOgrenci */
  body.edulive-cihaz .hub-card[href="/ogrenci"]::before {
    --rota-ikon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8.2' r='3.9'/%3E%3Cpath d='M4.6 20.6c0-3.7 3.6-5.6 7.4-5.6s7.4 1.9 7.4 5.6'/%3E%3C/svg%3E");
  }}


/* ===========================================================================
   8 · ÇALIŞMA EKRANLARI: VERİ TABLOLARI + IZGARA HÜCRELERİ
   TASARIM-MOBIL bölüm 11 (paket P4b) — kabul kriteri K2 · K16 · K17

   NEDEN BU BANT VAR (ölçüm, 2026-08-24)
   -------------------------------------
   P1-P4 ana ekranı ve 13 hub sayfasını ölçüp düzeltti. Kullanıcı zamanını
   ORADA geçirmiyor. Bu turda gerçek çalışma ekranları ilk kez ölçüldü
   (360x780, dokunmatik, gerçek dağıtım CSS'i + birebir DOM):

     12 tablo ekranının 9'u YATAY TAŞIYORDU — toplam 848 px
       SorularList 176 · AiModelsList 148 · WalletTransactions 143
       OrgList 123 · AuditLog 92 · IcerikIsleri 69 · GorevKuyrugu 41
       OnayKuyrugu 31 · ComplianceMonitor 25
     13 hub sayfasının taşması: 0.  Yani kusur ızgarada değil TABLODA.

   KÖK NEDEN: `.au-result-table` (64 .razor dosyası) `width: 100%` +
   `border-collapse: collapse` ile yazılmış ve HİÇBİR kaydırma kabı yok
   (admin-users.css:430). Bir tablonun kullanılan genişliği
   `max(belirtilen, min-content)`tur — 5-8 sütun 360 px'e sığmaz, tablo
   sayfayı genişletir. Depoda 79 .razor'da <table> var; sarmalayıcısı
   olan yalnız 4'ü (etl-scroll · bi-scroll · ci-scroll · pm-table-wrap).

   NEDEN SAYFA DEĞİL TABLO KAYAR
   Görev sözleşmesi: "taşan içerik kendi kabında kaymalı, sayfa değil."
   `<table>` `display: table` iken `overflow` ÇALIŞMAZ (Blink yok sayar).
   `display: block` tablonun içini anonim bir tablo kutusuna sarar, kutu
   scroll konteyneri olur. ÖLÇÜLDÜ: thead <-> tbody sütun hizası sapması
   12 ekranın 12'sinde **0 px** (aynı anonim tabloya girdikleri için).
   Denenip ELENEN: `display: grid` — aynı kaydırmayı verdi ama hiza
   sapması 19-88 px (thead/tbody ayrı ızgara öğesi oluyor).

   BEDELİ AÇIKÇA (ölçüldü, gizlenmedi)
   Zaten SIĞAN bir tabloda anonim tablo kutusu shrink-to-fit olur ve
   satır 296 -> 282 px'e iner; metin bir satır fazla sarar. Ham ölçümde
   PlansList ilk ekranda 19 -> 14 öğeye düşmüştü. Bu yüzden yatay hücre
   dolgusu 10 -> 6 px'e indi (aşağıda): kayıp geri alındı (19 -> 18) ve
   taşan tablolar da 8 px x sütun kadar daralarak daha az kaydı.
   Net: 12 ekranda ilk-ekran öğesi 132 -> 131, taşma 848 px -> 0.

   NEDEN YALNIZ TELEFON BANDI
   744/834/1024/1194 px'te aynı 12 ekran ölçüldü: taşan tablo **0**.
   Kural tablette gereksiz, orada bedeli (dar satır) ödemeye değmez.
   ========================================================================= */

@media (max-width: 640px) {

  /* Tüm veri tabloları kendi kabında kayar. Depodaki 79 <table>'ın 79'u
     VERİ tablosudur (düzen tablosu yok — tarandı), bu yüzden sınıf sınıf
     değil öge seçicisiyle yazıldı: yarın eklenen 80. tablo da kapsanır.
     Özgüllük (0,1,2); tarandı, hiçbir kapsamlı kural bir <table> ögesine
     `display` yazmıyor -> ezme riski yok, `!important` gerekmiyor.

     `position: relative` — kökeni: SorularList'te `.ql-visually-hidden`
     (SorularList.razor.css:29-39) konumsuz `position: absolute` olduğu için
     `main.wrap`e bağlanıyor, tablonun kırpmasından KAÇIYOR ve sayfayı
     genişletiyordu. Tabloyu konumlandırmak onu içeri alıyordu (116 -> 0).

     ARTIK ASIL İŞİ YAPAN O DEĞİL: kök neden 11. bantta kapatıldı (F5).
     Ölçüldü — `position: static`e çekilmiş tabloyla, yalnız 11. bant açıkken
     belge taşması **0** (bant kapalıyken 137 px). Bu satır bugün bir
     GENEL SİPER olarak duruyor: 79 tablonun herhangi birinde yarın konumsuz
     bir `position: absolute` doğarsa sayfayı değil tabloyu genişletsin.
     Bedeli yok (yalnız kapsayıcı blok kurar), ölçümle boş yere durmuyor. */
  body.edulive-cihaz table {
    display: block;
    position: relative;
    overflow-x: auto;
    max-width: 100%;
  }

  /* Yatay hücre dolgusu 10 -> 6 px (admin-users.css:437 `padding: 8px 10px`;
     DİKEY dolguya dokunulmuyor — satır yüksekliği dokunma hedefidir).
     Kazanç sütun başına 8 px: 6 sütunlu bir tabloda 48 px. Yukarıdaki
     "bedel" paragrafının karşılığı budur. */
  body.edulive-cihaz .au-result-table th,
  body.edulive-cihaz .au-result-table td {
    padding-left: 6px;
    padding-right: 6px;
  }

  /* Izgara/flex ögesinin OTOMATİK EN KÜÇÜK BOYUTU (auto minimum size)
     `min-content`tur: `grid-template-columns: 1fr` yazan bir mobil kural
     kabından GENİŞ bir iz üretir. Canlı örnek: ComplianceMonitorPage
     `.cmm-grid` 768 px altında `1fr` diyor, ölçülen iz 344,8 px / kap
     296 px -> 25 px taşma. Aynı hata sınıfı bu dosyanın 1. bandında
     `.hub-grid` için `minmax(0,1fr)` ile önlenmişti; burada ögenin
     kendisinden çözülüyor. `min-width: 0` yalnız İZİN verir, hiçbir şeyi
     büyütmez — 327 .razor'un taşıdığı `.au-card` için güvenli taban.
     Ölçüldü: ComplianceMonitor 25 -> 0, öteki 11 ekranda değişiklik yok. */
  body.edulive-cihaz .au-card {
    min-width: 0;
  }

  /* İçerik Stüdyosu hub'ı `.hub-grid` DEĞİL kendi `.csh-grid`ini kullanıyor
     (ContentStudioHub.razor.css:5 `minmax(240px,1fr)`) — 1. banttaki iki
     sütun kuralı ona İNMİYORDU. Kartları (`a.au-card.csh-card`) yapı olarak
     HubCard'ın aynısı: başlık + tek satır açıklama, tamamı bağlantı.
     Ölçüldü: tek sütun K15 1,97 / ilk ekran 6 öğe -> iki sütun K15 1,69 /
     9 öğe, taşma 0. `/content-studio` alt gezinme çubuğunun bir YUVASI —
     kullanıcının en sık indiği üç ekrandan biri.
     KAPSAM DIŞI bırakılanlar (ölçümle): `.acd-grid` · `.crd-grid` içindeki
     kartlar bağlantı değil KPI panelidir (`<section>`), iki sütunda sayı
     bloğu eziliyor; `.op-grid` iki AYRI sayfada aynı adı taşıyor ve
     OgrenciPanel'de iki sütun 52 px taşma üretti (ölçüldü). */
  body.edulive-cihaz .csh-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
}


/* ===========================================================================
   9 · DOKUNMA HEDEFİ — IZGARA HÜCRELERİ VE TABLO SATIRLARI
   6. bandın "SÜPÜRÜLMEYENLER" notunun kapanışı (P3'te frontend-3 onayına
   bırakılmıştı) — TASARIM-MOBIL bölüm 11.4 · kabul kriteri K3

   P3 NEDEN BIRAKMIŞTI, NEDEN ARTIK GEREKMİYOR
   -------------------------------------------
   Gerekçe şuydu: "44 px sütun sayısıyla çarpılır ve K2'yi ihlal eder;
   doğrusu tabloyu kendi kabında kaydırmaktır = işaretleme işi."
   Bu turda ÖLÇÜLDÜ ve gerekçenin üçte ikisi ÇÜRÜDÜ:
     .av-cell   -> `.av-grid-wrap { overflow-x: auto }` + `.av-grid
                   { min-width: 560px }` ZATEN VAR (planlama.css:139-146)
     .jft-cell  -> `.jft-grid-wrap { overflow-x: auto }` ZATEN VAR
                   (OrtakBosZaman.razor.css:50-58)
   Bu ikisinde değişen tek şey YÜKSEKLİKTİR; yatay bedel SIFIRDIR.
   Üçüncüsü (`.sis-togrid__cell`) gerçekten kapsız duruyordu — 8. bandın
   `table { overflow-x: auto }` kuralı ona kabını verdi; genişlik artık
   sayfayı değil tablonun kendi kaydırmasını büyütüyor.
   Ölçüm (SisTimeoffGrid, 360 px): 44 px altı hedef **49 -> 0**,
   sayfa taşması 4 -> 0 px. İşaretlemeye tek bayt yazılmadı.
   ========================================================================= */

@media (hover: none) and (pointer: coarse) {

  /* SisTimeoffGrid.razor.css:23-25 — 26x22 px. Haftalık müsaitlik ızgarası;
     tek dokunuşla bir ders saatini açıp kapatıyor. 7 periyot x 44 = 308 px
     + gün etiketi; tablo kendi kabında kaydığı için sayfa taşmıyor. */
  body.edulive-cihaz .sis-togrid__cell {
    width: 44px;
    height: 44px;
  }

  /* planlama.css:168 — 40 px (OgretmenMusaitligi). Kabı zaten kayıyor. */
  body.edulive-cihaz .av-cell {
    min-height: 44px;
  }

  /* OrtakBosZaman.razor.css:80 — 42 px. Kabı zaten kayıyor. */
  body.edulive-cihaz .jft-cell {
    min-height: 44px;
  }

  /* TIKLANABİLİR TABLO SATIRI — ölçülen üç aile:
       tr.gk-row 41,8 (GorevKuyrugu.razor:54) · tr.cl-row 36,5
       (CardsList.razor:63) · tr.pl-row 36,5 (PlansList)
     Üçü de `tabindex="0"` + `role="button"|"link"` taşır, yani gerçek
     dokunma hedefidir. `min-height` tablo satırına UYGULANMAZ; tablo
     düzeninde `height` bir TABANDIR — hücreye yazılır, satır onu izler.
     Seçici yalnız etkileşimli satırı tutar: salt-okunur satırlar 36,5
     px'te kalır, K15 boşuna büyümez. Ölçüldü: 3 ekranda 44 px altı
     hedef 18 -> 0, K15 değişimi <= 0,05. */
  body.edulive-cihaz tr[tabindex] > td,
  body.edulive-cihaz tr[role="button"] > td,
  body.edulive-cihaz tr[role="link"] > td {
    height: 44px;
  }

  /* Tablo hücresindeki ikon düğmeleri (AuditLog 8 örnek 26 px ·
     WalletTransactions 34 px). 6. bandın yatay tabanı yalnız ÖLÇÜLMÜŞ 31
     sınıfa veriliyordu ve `.au-btn`in kendisi listede YOKTU — genel bir
     `.au-btn { min-width: 44px }` araç çubuklarında yatay taşma üretirdi
     (K2). Hücre içinde bu risk 8. bant sayesinde kalktı: kap zaten kayıyor.
     Ölçüldü: AuditLog 8 -> 0, sayfa taşması 0'da kaldı. */
  body.edulive-cihaz td .au-btn,
  body.edulive-cihaz th .au-btn {
    min-width: 44px;
  }
}


/* ===========================================================================
   10 · GPU BÜTÇESİ: TELEFONDA `backdrop-filter` KAPALI
   Karar K-6 (uygulama/ILERLEME.md) — kabul kriteri K11
   YALNIZ TELEFON BANDI. Tablet ve masaüstü BİLEREK dokunulmadan bırakıldı.

   ÖLÇÜM 1 — KAÇ TANE VAR (360x780, dokunmatik, gerçek dağıtım CSS'i)
   ------------------------------------------------------------------
   Ana ekranda aynı anda **14** ayrı `backdrop-filter` geçişi ölçüldü:
     header.topbar   blur(22px)                 x1
     a.hub-card      blur(14px) saturate(1.5)   x13
   Her biri GPU'da ayrı bir arka-plan örnekleme geçişidir; öğe kaydırma ile
   yer değiştirdiği için arkasındaki kompozit her karede yeniden okunur.
   Kullanıcının Faz B şikayeti buydu: "mobilin gücünden faydalanmıyoruz",
   "web'dekinden yavaş".

   ÖLÇÜM ARACI KUSURU DA BURADA ÇIKTI (düzeltildi)
   -----------------------------------------------
   `js/tasma-tani.js`'in K11 işlevi YALNIZ `filter`e bakıyordu; bu yüzden
   `.blob`un `blur(100px)`ini görüp `.hub-card`ın `backdrop-filter`ını
   GÖRMÜYORDU ve telefonda "görünür blur 0" diye rapor ediyordu. İşlev
   `backdrop-filter` + `-webkit-backdrop-filter`i de sayacak biçimde
   düzeltildi; bu bandın öncesi/sonrası onunla ölçüldü.

   ÖLÇÜM 2 — KARTTA BULANIKLIK NE KAZANDIRIYOR?  CEVAP: HİÇBİR ŞEY
   ----------------------------------------------------------------
   Ekran görüntüsünden piksel örneklendi (360x780, cihaz ölçek 1):
     backdrop-filter AÇIK  -> kart içi rgb(250, 251, 255)
     backdrop-filter KAPALI-> kart içi rgb(250, 251, 255)     fark 0/255
   Sebep ölçülebilir: 1. bant `.blob`ları zaten `display: none` yapıyor
   (P1). Arkada bulanıklaştırılacak bir DESEN kalmadı — geriye yalnız
   `--page-bg` gradyanı kaldı ve bir gradyanın bulanığı kendisidir.
   `saturate(1.5)` de kroması sıfıra yakın bir zemini doyuruyordu.
   Yani 13 kartta ödenen bedelin karşılığı 0/255'ti.

   ÖLÇÜM 3 — ÜST BARDA BULANIKLIK GERÇEKTEN İŞ YAPIYOR
   ---------------------------------------------------
   Üst bar `position: sticky`tir; ARKASINDAN içerik geçer. Barın arkasına
   `--fg` (#0f172a) koyu metin konup bar şeridinin en açık/en koyu pikseli
   ölçüldü ("hayalet" = metnin bardan sızma miktarı):
     A  bugünkü blur(22px), zemin --glass-strong (.85)  ->   2/255
     B  blur kapalı, zemin --glass-strong (.85) KALIR   ->  34/255  ✗
     C  blur kapalı, zemin --glass-hover (.92)          ->  19/255  ✗
     D  blur kapalı, zemin OPAK #ffffff                 ->   0/255  ✓
   B ve C görünür bir gerilemedir: kaydırılan koyu metin barın altından
   okunacak kadar sızar. Bu yüzden bulanıklığı kaldırılan her YAPIŞIK
   yüzeye OPAK zemin verilir — bulanıktan bile temiz çıkar ve bedavadır.
   Aynı seçim alt gezinme çubuğunda P2'de zaten yapılmıştı
   (4. bant: `.cihaz-sekme { background: #ffffff }`), iki krom eşitlendi.

   ÖLÇÜM 4 — KART "KATTAN AYRIŞMA"SI VE METİN KONTRASTI
   -----------------------------------------------------
   Karta OPAK zemin verilmedi: kartın arkasından içerik geçmiyor (sayfayla
   birlikte kayar), o yüzden hayalet riski yok ve saydamlığı korumak
   gradyanın kart üzerinde yaşamasını sürdürür ("görünüm düzleşmesin").
   Zemin `--glass` (.6) -> `--glass-strong` (.85) yükseltildi; ölçülen:
     zemin        kart rgb        sayfa rgb        ayrışma     metin(--fg)
     --glass .6   (250,251,255)   (238,241,250)    1.092:1     17.26:1
     --glass-str  (253,254,255)   (238,241,250)    1.118:1     17.68:1
   Ayrışma DÜŞMEDİ, yükseldi (1.092 -> 1.118) — kaldırılan `saturate(1.5)`in
   yerini fazlasıyla dolduruyor. Metin kontrastı 17.68:1, WCAG AA eşiği
   4.5:1'in ~3.9 katı (AAA 7:1'in 2.5 katı). Sabit renk YAZILMADI: ikisi de
   aurora.css'in kendi belirteci, palet değişirse kart takip eder.

   NE KAPATILMADI, NEDEN
   ---------------------
   Kapatılanlar: KAYDIRMA SIRASINDA ekranda duran yüzeyler (yapışık/sabit
   kromlar) + aynı anda 13-25 kopya çıkan kart. Kapatılmayanlar: dokunuşla
   açılan TEKİL katmanlar — `.menu`, `.ou-switch__menu`, bildirim açılırı,
   `AppMultiSelect` açılırı, modal perdeleri. Onlar tek geçiştir, açıkken
   sayfa kaymaz, camsı görünüm orada bedelini hak ediyor.
   `Bbt*` ekranlarının kendi bulanıklıklarına DOKUNULMADI (kullanıcının
   öteki ajanının işi) — bu bandın seçicileri onların sınıflarını tutmaz.

   GERİ ALMA: bu bandın tamamı silinirse telefon camsı görünümüne döner.
   ========================================================================= */

@media (max-width: 640px) {

  /* --- 1) Kart: 13-25 kopya, bulanıklığın ölçülen katkısı 0/255 ---------- */
  body.edulive-cihaz .hub-card {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    /* Ölçüm 4: ayrışma 1.092 -> 1.118, metin 17.68:1. Belirteç, sabit değil. */
    background: var(--glass-strong);
  }

  /* --- 2) Yapışık kromlar: bulanık YERİNE opak (Ölçüm 3) -----------------
     `.topbar`         aurora.css:224-237  — personel düzeni, her ekranda
     `.student-topbar` StudentLayout:36-49 — öğrenci düzeni, her ekranda
     `.toast`          ToastHost:14-30     — sabit, kayan içeriğin üstünde
     Üçünün de zemini `--glass-strong`tı; opak beyaz onun tam doygun hâli,
     bu yüzden renk sıçraması yok (ölçüldü: bar rgb(253,254,255) ->
     rgb(255,255,255), 2/255). Alt gezinme çubuğu zaten #ffffff. */
  body.edulive-cihaz .student-topbar,
  body.edulive-cihaz .toast {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: #ffffff;
  }

  /* Kimliğe bürünme şeridi de yapışıktır (z-index 80, üst barın da üstünde).
     Zemini `color-mix(--amber-500 %16, --glass-strong)` idi; opak karşılığı
     aynı karışımın beyaz üzerine alınmışıdır — kehribar tonu korunur,
     saydamlık gider. Uyarı şeridinin okunurluğu şartlı değil. */
  body.edulive-cihaz .imp-banner {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: color-mix(in srgb, var(--amber-500) 16%, #ffffff);
  }
}


/* ===========================================================================
   11 · ORTAK "GÖRSEL OLARAK GİZLİ" DESENİ  (F-listesi · F5)
   YALNIZ TELEFON BANDI — kabul kriteri K2 · K18

   SORUN (Tur 20'de yakalandı, orada YAMAYLA kapatılmıştı)
   -------------------------------------------------------
   frontend-3'te ekran-okuyucu-için-gizli metin deseni ortak bir yardımcı
   sınıf olarak DEĞİL, sayfa başına kopyalanarak yazılmış: 12 ayrı sınıf adı
   (`ql-` `au-` `bs-` `al-` `wl-` `pg-` `mtp-` `dc-` `tm-` `ts-` `wd-` ...),
   14 kullanım. On dördü de aynı gövdeyi taşıyor:
       position: absolute;  width/height: 1px;  overflow: hidden;
       clip: rect(0,0,0,0);  margin: -1px;  white-space: nowrap;
   `clip` 2011'den beri terk edilmiş; asıl kusur ise `position: absolute`in
   KONUMSUZ olması. Konumsuz mutlak öge, DOM'da nerede olursa olsun en yakın
   KONUMLANMIŞ ataya bağlanır. 8. bant tabloları kaydırma kabı yapınca bu öge
   tablonun içinde kalıp kapsayıcı bloğu dışarıda oldu: tablonun kırpmasından
   kaçtı ve sayfayı genişletti.
   ÖLÇÜLDÜ (SorularList yapısal DOM'u, 360x780, tablo `position: static`):
       belge 497 px / görünüm 360 px  ->  137 px taşma, kaçan öge tek: o.

   ÇÖZÜM VE NEDEN BU BİÇİM
   ------------------------
   Desen bir kez, cihaz katmanında yeniden tanımlanır (frontend-3'e tek bayt
   yazılmaz). İki değişiklik var, ikisi de gerekçeli:
     1. `clip: rect(...)` -> `clip-path: inset(50%)`  — güncel karşılığı.
     2. `position: absolute` -> `static`  — öge akışta kalır, kapsayıcı blok
        diye bir sorun kalmaz, hiçbir kaptan KAÇAMAZ. Kaçağı kapatan budur.
   ÖLÇÜLDÜ: aynı DOM, tablo `position: static` iken bile belge taşması
   **137 -> 0 px**; thead/tbody hiza sapması 0,00 px; K15 değişmedi (1,35).

   `display` NEDEN AYRI SEÇİCİDE (ölçüldü — körü körüne verilseydi gerileme)
   -------------------------------------------------------------------------
   Akışa dönen öge, satır-içi (`inline`) ise `width/height/overflow` ona
   UYGULANMAZ: `<span>` 38x15 kalıp metni GÖRÜNÜR kılıyordu. Çözüm
   `inline-block`. Ama aynı ilan `<caption>`a verilirse caption tablo-içi
   olmaktan çıkar, Blink onu anonim bir hücreye sarar:
       display'e dokunulmayan   : caption `table-caption`, tablo 97 px
       herkese `inline-block`   : caption `inline-block`,  tablo 115,5 px  ✗
   Bu bir DÜZEN sorunu değil ERİŞİLEBİLİRLİK gerilemesidir — tablo başlığı
   başlık olarak değil veri hücresi olarak duyurulur. Bu yüzden `inline-block`
   YALNIZ `<span>` ve `<label>`a verilir. Depodaki 14 kullanım: span 8 ·
   caption 3 · label 2 · dl 1. Ölçüldü: dördü de 1x1, caption `table-caption`
   kaldı, belge taşması 0.

   EKRAN OKUYUCU ERİŞİMİ NEDEN BOZULMAZ
   -------------------------------------
   Erişilebilirlik ağacı geometriden değil DOM + `display`/`visibility`den
   kurulur. Bu kural hiçbir ögeyi `display: none` ya da `visibility: hidden`
   yapmaz, `aria-hidden` eklemez, metni DOM'dan çıkarmaz (ölçüldü: dört ögenin
   dördünde de `textContent` yerinde, `visibility: visible`). Kutu 1x1 +
   `overflow: hidden` + `clip-path: inset(50%)` — "görsel olarak gizli"nin
   standart tarifi zaten budur. Konumlandırma şemasının erişilebilirlik ağacına
   etkisi YOKTUR; değişen tek şey ögenin hangi kaptan kırpıldığıdır.
   Odakta görünür olması gereken bir kullanım (atlama bağlantısı) yok: 14
   kullanımın tamamı odaklanamayan öge (span/caption/dl) ya da `<label>`.

   ÖZGÜLLÜK: `body.edulive-cihaz [class*="-visually-hidden"]` = (0,2,1);
   kapsamlı kural `.ql-visually-hidden[b-1iv9njt4zs]` = (0,2,0). Ezer,
   `!important` gerekmez. Seçici sınıf adına değil DESENE bağlandığı için
   yarın açılacak 13. kopya da kapsanır.
   ========================================================================= */

@media (max-width: 640px) {

  body.edulive-cihaz [class*="-visually-hidden"] {
    position: static;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
    /* Kaynaktaki terk edilmiş `clip: rect(0,0,0,0)` geri alınır: `clip` yalnız
       mutlak konumlu ögede çalışır, akışa dönen ögede ölü bir ilan olurdu. */
    clip: auto;
  }

  /* Satır-içi ögelerde kutu modeli yok; ölçüsüz kalırsa metin GÖRÜNÜR olur.
     `<caption>` ve `<dl>` BİLEREK dışarıda — gerekçe ve ölçüm yukarıda. */
  body.edulive-cihaz span[class*="-visually-hidden"],
  body.edulive-cihaz label[class*="-visually-hidden"] {
    display: inline-block;
  }
}


/* ===========================================================================
   12 · ANALİZ ASİSTANI (CHATBOT)  —  /analiz/asistan
   Kullanıcının EN ESKİ şikayeti ("Chatbot'ta grafikler falan mobile uyumlu
   değil", Faz B / Flutter dönemi). Kabul kriteri K2 · K3 · K4 · K9

   ÖLÇÜM ORTAMI (uydurma yok — hepsi cihazda okundu)
   -------------------------------------------------
   Emülatör `vibe_coder_pixel` 1080x2400 @420dpi -> görünüm **412 x 839 CSS px**,
   dpr 2,625. Debug APK `-t:Install` ile kuruldu, gerçek oturumla giriş yapıldı,
   4 mesajlık GERÇEK bir sohbet açıldı; üstüne Tur 21'in sentetik ağır içerik
   yöntemi uygulandı (uzun kelime · uzun URL · 7 sütunlu tablo · JSON `<pre>` ·
   açık `<details>` düşünce bloğu · 7 kategori x 3 seri ECharts grafiği).
   Ölçüm CDP `Runtime.evaluate` ile WebView'in içinden yapıldı.

   ÖNCE ÖLÇÜLEN KUSURLAR (BANT 12 bunları kapatır)
   ------------------------------------------------
   1) BESTECİ ALT ÇUBUĞUN ALTINDA KALIYOR — **47 px**.
        `.aa-alt`      665,2 -> 830,5
        `.cihaz-sekme` 783,2 -> 839,2 (z-index 65, `.aa-yan` 60'ın üstünde)
        `.aa-dipnot`   786,0 -> 820,0  => **%100 görünmez** (ekran görüntüsüyle
                                          de doğrulandı: yazı hiç çizilmiyor)
        `.aa-kompozer` 680,0 -> 778,0  => çubuğa yalnız 5 px kala duruyor
      KÖK NEDEN: `AnalizAsistan.razor.css:@media(max-width:900px)`
        `.aa-kabuk { height: calc(100vh - var(--topbar-h) - 28px) }`
      Bu GÖRÜNÜM yüksekliğidir; alt gezinme çubuğu ise `position: fixed` ile
      görünümün son 56 px'ini kaplar. 4. bandın `.wrap { padding-bottom }`
      telafisi buraya İŞLEMEZ: telafi akıştaki içeriği iter, `100vh`'lik bir
      kutuyu kısaltmaz. Ölçüm: 72 + 759,238 = 831,2 > 783,2.
   2) ÇEKMECE'NİN ALT **60 px**'İ ÇUBUĞUN ALTINDA.
        `.aa-yan` 64 -> 843,2 · `.aa-liste` 287,8 -> 842,5 · çubuk 783,2
      Sohbet listesinin son öğesi seçilemiyor. (Not: `.aa-yan` `position: fixed`
      olmasına rağmen kutusu görünümün 4 px DIŞINA taşıyor — ölçüldü, bu yüzden
      aşağıdaki `bottom` hesabına 8 px pay kondu.)
   3) GRAFİK OKUNMUYOR (asıl şikayet). `.aa-grafik` 277x260, tuval **265x244**.
      İçinde 7 kategori x 3 seri = **21 çubuk**; kategori başına 37,8 px, çubuk
      başına 12,6 px düşüyor ve `MAT.9.1.1` gibi eksen etiketleri okunmuyor.
      Tuval kabından TAŞAMAZ (`.aa-kart { overflow: hidden }`), bu yüzden ortada
      ölçülebilir bir "taşma" yok — kusur GENİŞLİK, adı okunaksızlık.
   4) DOKUNMATİKTE ERİŞİLEMEYEN 14 HEDEF.
        `.aa-og__eylemler` `display: none` x4 satır = **8 düğme** (Arşivle/Sil)
        `.aa-eylemler`     `opacity: 0`   x3 mesaj = **6 düğme** (Kopyala/Oy/
                           Yeniden üret; yalnız SON mesajda görünüyor)
      İkisi de `:hover`/`:focus-within` ile açılıyor; dokunmatikte imleç yoktur.
      Düğmelerin BOYUTU sorun değil: 6. bandın süpürmesi `.aa-ikon`u zaten
      44x44 yapıyor (ölçüldü: görünür 11 örneğin 11'i 44x44). Sorun GÖRÜNÜRLÜK.
   5) GİRİŞ ALANI PUNTOSU K4'ün ALTINDA.
        `.aa-girdi` **15 px** · `.aa-arama input` **13 px**
      2. bandın `:where()` TABANI (0,0,1) bunları kurtaramaz; kapsamlı kural
      `.aa-girdi[b-3qvbjssspy]` (0,2,0) daha güçlü. Ayrıca `.aa-girdi`
      28,5 px yüksek (min-height 24 px) -> K3'ün 44 px'inin altında.
   6) İÇ İÇE KAYDIRICI. `.aa-dusunce__govde` `max-height: 220px; overflow: auto`
      ve ölçülen iç taşma **29 px**. Zaten kayan `.aa-akis`ın içinde ikinci bir
      kaydırma tuzağı; dokunmatikte hangi kabın kaydığı belirsizleşiyor.
   7) KROM ORANI %38. `.aa-akis` 145 -> 665 = **520 px** (görünümün %62'si).
      Çubuğun 56 px'i düşülünce bu daha da azalacak; aşağıdaki dolgu
      kısıntıları o kaybı geri almak içindir (hesap kuralların yanında).

   ÖLÇÜLDÜ AMA KUSUR ÇIKMADI -> KURAL YAZILMADI
   ---------------------------------------------
   • Belge yatay taşması **0**; kırpılmayan taşan öge **0**. Uzun kelime ve
     uzun URL zaten sarıyor -> `overflow-wrap` kuralı GEREKMİYOR, yazılmadı.
   • Tablo (279 / 878, iç kayma 599 px) ve `<pre>` (279 / 1160, 883 px) kendi
     kaplarında kayıyor (`.aa-md table{display:block;overflow-x:auto}` ·
     `.aa-md pre{overflow-x:auto}` kaynakta VAR). Görev sözleşmesinin istediği
     davranış bu -> 8. bandın `table` kuralına ek gerekmiyor.
   • Öneri kartları `.aa-oneri` 294,7 x 62, taşma 0 -> dokunulmadı.
   • Çekmecenin AÇILIŞI doğru: `.aa-yan` `position: fixed`, `.aa-kabuk` tek
     sütun (348,2 px). Yalnız alt kenarı hatalı (madde 2).

   CSS İLE ÇÖZÜLEMEYEN (F-listesi, raporda frontend-3/kabuk onayına gidiyor)
   -------------------------------------------------------------------------
   • [KAPANDI — Android: Tur 30 · iOS: Tur 31. Aşağıdaki teşhis DOĞRUYDU ama
     "CSS ile çözülemez" hükmü artık geçerli değil; kayıt tarihsel olarak
     bırakıldı, aksiyon gerekmiyor. Android'de kök konak katmanındaydı
     (Platforms/Android/MainActivity.cs, IME inseti -> dolgu). iOS'ta kök
     viewport ikiliğiydi ve BANT 13 + js/klavye-ortu.js ile çözüldü. iOS
     ölçümü aşağıdaki Android ölçümünden FARKLIDIR: orada innerHeight ile
     visualViewport BİRLİKTE sabit kalıyordu, iOS'ta yalnız visualViewport
     iniyor (874 -> 471) -> fark ölçülebilir, --klavye-ortu ondan doğuyor.]
     YAZILIM KLAVYESİ AÇIKKEN BESTECİ TAMAMEN GÖRÜNMEZ. Ölçüldü (IME açık,
     `mInputShown=true`): `innerHeight` 839 -> **839** (değişmedi),
     `visualViewport.height` 839,2 -> **839,2** (değişmedi). Klavye sayfayı ne
     yeniden boyutlandırıyor ne kaydırıyor; üstüne biniyor. Ekran görüntüsü:
     klavyenin üst kenarı ~503 CSS px, besteci 680-778 -> **177 px altta kaldı**.
     Bunu CSS göremez: `dvh` de `visualViewport` da değişmiyor. Çözüm kabuğun
     `index.html` viewport meta'sında (`interactive-widget=resizes-content`)
     ya da Android Activity'nin `windowSoftInputMode` ayarındadır — ikisi de
     bu dosyanın dışında. NOT: `100dvh` aşağıda yine de kullanıldı, çünkü
     bedeli sıfır (bu WebView'de `dvh == vh == 839,238`) ve iOS/WKWebView'de
     doğru olan odur.
   • `.aa-ust__alt` (188,1 px kutu / 242 px içerik) ve rapor kartı başlığı
     (201 px) üç nokta ile kırpılıyor — bilgi kaybı işaretleme işidir.

   NEDEN TELEFON BANDI + ≤1023 px DOKUNMATİK (K9)
   ----------------------------------------------
   Düzen kuralları `max-width: 640px` bandındadır; 1280/1920'de eşleşmez.
   Hover-açığa-çıkarma kuralları dokunmatik bandındadır AMA ek olarak
   `max-width: 1023px` ile sınırlandı: dokunmatik bir 1920 px masaüstü
   monitöründe kenar çubuğunun Arşivle/Sil düğmelerini kalıcı görünür yapmak
   masaüstü görünümünü DEĞİŞTİRİRDİ; K9 bunu yasaklıyor. Kaynağın kendi
   çekmece eşiği 900 px'tir, 1023 onu güvenle kapsar.
   ========================================================================= */

@media (max-width: 640px) {

  /* (1) Kabuğun yüksekliğinden alt gezinme çubuğu DA düşülür.
     Eski: calc(100vh - 52 - 28)            = 759,238 -> alt kenar 831,2 (ÇAKIŞMA)
     Yeni: calc(100dvh - 52 - 56 - 0 - 28)  = 703,238 -> alt kenar 775,2
     Çubuk üstü 783,2 => 8 px pay kalır, `.aa-dipnot` ilk kez görünür olur.
     `--sekme-h`/`--sekme-alt` 4. bandın sözleşmesidir (56 px + güvenli alan);
     `.aa-kabuk` `body.edulive-cihaz`ın soyundan olduğu için ikisini de miras
     alır. `min-height` sıfırlanıyor: kaynaktaki 520 px taban, telefon
     manzarasında (görünüm yüksekliği ~412 px) çakışmayı geri getirirdi. */
  body.edulive-cihaz .aa-kabuk {
    height: calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 28px);
    min-height: 0;
  }

  /* (7) Kabuk 56 px kısaldı; kaybı KROMDAN geri alıyoruz, akıştan değil.
     `.aa-ust` dolgusu 10 -> 6 px  (-8 px)  · yükseklik 72,4 -> ~64
     `.aa-ust__alt` gizlenir       (-18 px) : zaten 54 px'i üç noktayla
       kırpılıyordu, yani ekranda taşıdığı bilgi kısmi. Sohbet ADI
       (`.aa-ust__ad`) yerinde kalıyor — kimlik onda.
     `.aa-alt` dolgusu 6/10 -> 4/6 (-6 px)
     `.aa-kompozer` dolgusu 10/8 -> 8/6 (-4 px)
     Toplam geri kazanım 36 px; net kayıp 56 - 36 = 20 px + girdi yüksekliği. */
  body.edulive-cihaz .aa-ust {
    padding-top: 6px;
    padding-bottom: 6px;
  }

  body.edulive-cihaz .aa-ust__alt {
    display: none;
  }

  body.edulive-cihaz .aa-alt {
    padding: 4px 12px 6px;
  }

  body.edulive-cihaz .aa-kompozer {
    padding: 8px 12px 6px;
  }

  /* Akışın İÇ dolgusu 18/10 -> 12/6. Bu krom değil İÇERİK alanıdır: kaydırıcının
     içinde olduğu için ekran başına 10 px daha fazla mesaj metni çizilir —
     yukarıdaki 20 px'lik net kaybın yarısı böyle telafi edilir. */
  body.edulive-cihaz .aa-akis__ic {
    padding: 12px 14px 6px;
  }

  /* (2) Çekmece de çubuğun üstünde biter. ÖNCE: `.aa-yan` 64 -> 843,2, sohbet
     listesinin alt 60 px'i çubuğun arkasında kalıyordu (son sohbet seçilemez).
     Pay yalnız 12 px: `.aa-yan` `position: fixed` OLMASINA rağmen sabit
     kapsayıcısı görünüm DEĞİL — cihazda ölçüldü: `.aa-kabuk` içine konan boş
     bir `fixed` kardeş `top:0;bottom:0` ile 64 -> 787,2 veriyor, `body`ye
     konan aynı kutu 0 -> 839,2. Yani kapsayıcı `.aa-kabuk` kutusunu izliyor;
     çubuk payı yukarıdaki (1) numaralı yükseklik kuralında ZATEN düşülmüş,
     burada tekrar düşülürse 52 px liste boşa gider (ölçüldü: alt 723,2).
     12 px, kapsayıcının kutu dışına taştığı 4 px'i (787,2 > çubuk üstü 783,2)
     kapatır ve 8 px görsel pay bırakır. Beklenen: `.aa-yan` alt ~775,2. */
  body.edulive-cihaz .aa-yan {
    bottom: 12px;
  }

  /* (3) GRAFİK — asıl şikayet. Tuval 265 px'te 21 çubuk taşıyor. Kart artık
     KENDİ KABINDA yatay kayar (görev sözleşmesi: "taşan içerik kendi kabında
     kaymalı, sayfa değil") ve grafiğe 560 px'lik bir taban verilir:
     kategori başına 80 px, çubuk başına ~22 px, eksen etiketi okunur.
     560 px bu dosyada keyfî değil: 9. bandın atıf yaptığı `.av-grid`
     (planlama.css:139-146) de aynı tabanı kullanıyor — aynı ev ölçüsü.
     `overflow-y: hidden` şart: `overflow-x: auto` tek başına yazılırsa
     tarayıcı `overflow-y`yi de `auto`ya çevirir ve dikey bir kaydırıcı belirir.
     ÇİZİM KENDİLİĞİNDEN TAZELENİR: `AnalizAsistan.razor.js:269 grafikCiz`
     her grafiği ortak bir `ResizeObserver`a bağlıyor ve `resize()` çağırıyor;
     kabın genişlemesi ECharts'ı yeniden çizdirir, JS'e tek bayt yazılmaz.
     `overscroll-behavior-x: contain` — kart sonuna gelince yatay hareket
     `.aa-akis`a ZİNCİRLENMESİN (dokunmatikte sohbet kaymaya başlıyordu). */
  body.edulive-cihaz .aa-kart--grafik {
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
  }

  body.edulive-cihaz .aa-kart--grafik .aa-grafik {
    min-width: 560px;
  }

  /* (6) İç içe kaydırıcı kaldırılır: düşünce bloğu `<details>` zaten kapalı
     gelir, açan kullanıcı tamamını görmek istiyordur. Ölçülen iç taşma 29 px
     -> blok 220 px'te kilitli kalmak yerine 249 px'e uzar, `.aa-akis` kayar.
     Bu, "taşan içerik kendi kabında kaysın" kuralının İSTİSNASI değil: burada
     taşan şey METİN, kabı da sayfanın kendi dikey kaydırıcısıdır. */
  body.edulive-cihaz .aa-dusunce__govde {
    max-height: none;
    overflow: visible;
  }

  /* (5) K4 tabanı + K3 yüksekliği. Punto 15 -> 16 px: altında iOS odakta
     sayfayı yakınlaştırır ve düzen kayar. `min-height` 24 -> 44 px: alan
     28,5 px'ti, tek satırlık bir dokunma hedefi olarak K3'ün altında.
     Bedeli ölçüldü ve yukarıdaki dolgu kısıntılarıyla karşılandı. */
  body.edulive-cihaz .aa-girdi {
    font-size: 16px;
    min-height: 44px;
  }

  /* Sohbet arama alanı 13 px -> 16 px (aynı K4 gerekçesi). Punto düzeltilince
     kutu 19,5 -> 24 px'e çıktı ama K3'ün 44 px'i hâlâ uzaktaydı (ölçüldü:
     bu düzeltmeden önce geriye kalan TEK küçük hedef buydu).
     Yükseklik ALANIN KENDİSİNE veriliyor, sarmalayan `<label>`a değil:
     `.aa-arama` bir etiket ve ona dokunmak da alanı odaklar, ama ölçüm
     odaklanabilir ögeyi sayar — 44 px'i orada göstermezsek rakam yalan olur.
     Etiketin 7 px'lik DİKEY dolgusu sıfırlanıyor ki kutu 44+14=58 px'e
     şişmesin; yatay dolgu (10 px) yerinde kalıyor, ikon-metin boşluğu odur.
     `flex: none` — `.aa-yan__bas` esnek sütun; taban `flex-shrink` ile
     ezilmesin. Ölçüldü: alan 24 -> 44, etiket 40 -> 46, çekmecede taşma 0. */
  body.edulive-cihaz .aa-arama {
    padding-top: 0;
    padding-bottom: 0;
    flex: none;
  }

  body.edulive-cihaz .aa-arama input {
    font-size: 16px;
    min-height: 44px;
  }
}


@media (hover: none) and (pointer: coarse) and (max-width: 1023px) {

  /* (4) Dokunmatikte imleç yoktur: `:hover` ile açılan bir düğme HİÇ açılmaz.
     `.aa-og__eylemler` 4 sohbet satırında `display: none` -> Arşivle ve Sil
     dokunmatikte ERİŞİLEMEZ (8 düğme). Kaynak `:focus-within`i de sayıyor ama
     satırın kendisi bir `<button>`; ona dokunmak sohbeti AÇIYOR, odak orada
     kalmıyor. Açığa çıkarınca satır düzeni: başlık + 2 x 44 px = 88 px,
     satır genişliği 318,5 px -> başlığa 230 px kalır (ölçüm aşağıda, K2 = 0).
     `.aa-og__govde` `min-width: 0` — ızgara/esnek ögenin otomatik en küçük
     boyutu `min-content`tir; uzun sohbet başlığı satırı genişletip düğmeleri
     dışarı itebilirdi (8. bantta `.au-card` için yazılan aynı ders). */
  body.edulive-cihaz .aa-og__eylemler {
    display: flex;
  }

  body.edulive-cihaz .aa-og__govde {
    min-width: 0;
  }

  /* `.aa-eylemler` yalnız `:hover` ve SON mesajda görünüyor: ölçümde 4 mesajın
     3'ünde `opacity: 0` = 6 düğme (Kopyala · Faydalı · Faydasız · Yeniden üret)
     dokunmatikte görünmez. `opacity: 0` ögeyi erişim ağacından ÇIKARMAZ, yani
     ekran okuyucu onları okur ama gören kullanıcı bulamaz — daha da kafa
     karıştırıcı. Bedeli açıkça: her yanıtın altına kalıcı 44 px'lik bir eylem
     satırı gelir. Karşılığı, bir yanıtı kopyalamanın tek yolunun "son mesaj
     olmasını beklemek" olmaktan çıkmasıdır. */
  body.edulive-cihaz .aa-eylemler {
    opacity: 1;
  }
}


/* ===========================================================================
   13 · SERVİS SÜPÜRMESİ  —  284 ROTANIN ÖLÇÜMÜNDEN ÇIKANLAR
   Kullanıcı emri: "analiz sayfalarından başlayarak sırayla bütün servislerin
   sayfalarını düzelt". 12. bant chatbot'u kapattı; bu bant kalan servisleri
   kapatır. Kabul kriteri K2 · K3 · K4 · K9 · K20

   YÖNTEM — kör düzeltme YOK
   -------------------------
   `/tmp/audit2.py` 284 rotayı gerçek oturumla tek tek gezdi, her rotada
   CDP `Runtime.evaluate` ile ölçtü: ilk ekrandaki dokunulabilir öge sayısı
   (S1) · 11 px altı yazı (S2) · `scrollWidth - clientWidth` yatay taşma (S3)
   · boş ekran (S4) · `opacity: 0` denetim (S5). Aşağıdaki her kural bir
   ÖLÇÜME dayanır; ölçüm satırı kuralın üstündedir.

   DENETİMİN KENDİ YANLIŞ POZİTİFİ (kural yazmadan önce elendi)
   ------------------------------------------------------------
   Araç `.amn__nokta`yı da taşıyor diye işaretledi. `audit2.py` bir ögeyi
   kaydırıcı içinde saymak için YALNIZ `e.parentElement`in `overflowX`ine
   bakıyor; `.amn__nokta` iki kat içeride (`.amn > .amn__sekme > .amn__nokta`)
   olduğu için elenmiyor. Gerçek suçlu aşağıda (13.1) — araç ne derse desin,
   kaynak okunmadan kural yazılmaz.
   =========================================================================== */

/* --- 13.1 · ANALİZ MODÜLÜNÜN TAMAMI YATAY TAŞIYOR (K2) ---------------------
   ÖLÇÜM: 30 `/analiz/*` rotasının HEPSİ 470-496 px taşıyor.
     /analiz/genel        493 px      /analiz/beceri        471 px
     /analiz/alan/beceri  496 px      /analiz/raporlar      492 px
   Taşan öge her rotada aynı: `.au-gizli` (+122 … +209 px).

   KÖK NEDEN (AnalizModNav.razor.css, salt-okunur):
     .amn { display: flex; flex-wrap: wrap; ... }                  <- konumsuz
     @media (max-width: 640px) { .amn { flex-wrap: nowrap;
                                        overflow-x: auto; } }
     .au-gizli { position: absolute; width: 1px; height: 1px;
                 clip: rect(0,0,0,0); ... }                        <- ekran
                 okuyucu metni; her sekmede "— gösterilecek ölçüm yok"
   MUTLAK KONUMLU BİR TORUN, BİR ATANIN `overflow`UNDAN ANCAK O ATA ONUN
   KAPSAYAN BLOĞU İSE KIRPILIR — yani atanın kendisi konumlandırılmış olmalı.
   `.amn` konumsuz olduğu için `.au-gizli`nin kapsayan bloğu çok yukarıda bir
   ata; kaydırıcının `overflow-x: auto`su onu KIRPMIYOR. Sekmeler yatayda
   ~700 px'e uzandığından sağdaki sekmelerin gizli metni belge kutusunu
   ~490 px genişletiyor: telefon her analiz sayfasında yana kayıyor.

   ÇÖZÜM: kaydırıcıyı kapsayan blok yap. Görsel etkisi SIFIR (`relative` +
   ofset yok), ama artık `.au-gizli` `.amn`in kırpma kutusunun içindedir ve
   taşma BELGEYE değil, zaten kaydırılabilir olan şeride yazılır.
   `.au-gizli` genel bir yardımcı sınıftır (analiz dışında da kullanılıyor);
   bu yüzden ona GENEL bir kural yazılmadı, yalnız `.amn` konumlandırıldı. */
body.edulive-cihaz .amn {
  position: relative;
}

/* Kemer + askı: şeridin KENDİ yatay kaydırma alanını da şişirmesin diye
   gizli metin şeridin sol üst köşesine sabitlenir. 1x1 px ve `clip`li
   olduğu için görünürlükte hiçbir şey değişmez; ekran okuyucu aynı sırayla
   okumaya devam eder (`clip` erişim ağacını etkilemez). */
body.edulive-cihaz .amn .au-gizli {
  left: 0;
  top: 0;
}


@media (hover: none) and (pointer: coarse) {

  /* --- 13.2 · FORM DENETİMİ SÜPÜRMESİ (K3) --------------------------------
     6. bant `:where(button, a[href], summary, [role="button"])` süpürmesini
     yazmıştı ama `select` / `input` / `textarea` O LİSTEDE YOKTU. Ölçüm bunun
     bedelini gösterdi — 40+ rotada 32-38 px'lik denetimler:
       .af-sec 150x32   .au-select 160x32   .ad-sec 260x32   .ak-sec 200x32
       .aps-sec 320x32  .asa-sec 320x32     .asr-sec 150x32  .aoa-sec 160x32
       .ag-girdi 140x33 .ar-girdi 252x38    .au-input 221x35 .asi-girdi 92x34
       .aru-girdi 315x34  .cp__search-input 237x38  .ds__search-input 212x40
     Hepsinin kaynağı aynı desen: `padding: 6px 9px; font-size: .875rem`.

     Dışarıda bırakılanlar ve GEREKÇESİ:
       checkbox/radio — kutunun kendisi büyütülmez; dokunma hedefi onu saran
         `<label for>` ögesidir (ComponentPicker'da ölçüldü: `.cp__check`
         16x16 ama `.cp__card-body` bütün satırı kaplayan bir `<label>`).
       range — `.aas__tutamak` mutlak konumlu, üst üste İKİ tutamak; kutusunu
         44 px yapmak rayla hizasını bozar. Ayrı ele alınır (13.7).
       hidden — çizilmez.
     `height` yazan bir denetim varsa bile `min-height` kazanır (kullanılan
     yükseklik = max(height, min-height)), bu yüzden özgüllük yarışı yok. */
  body.edulive-cihaz :where(
    select,
    textarea,
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"])
  ) {
    min-height: 44px;
  }

  /* K4 (punto tabanı) 2. bantta `:where(body.edulive-cihaz)` ile (0,0,1)
     yazılmıştı — BİLEREK, çünkü taban asla TAVAN olmamalı (`.mfa-code input`
     20 px kalmalı). Ama (0,0,1), kapsamlı CSS'in (0,2,0)'ını yenemez; ölçüm
     bunu doğruladı: `.af-sec` cihaz katmanına rağmen 14 px kaldı (iOS
     odaklanınca sayfayı yakınlaştırır ve düzen kayar).
     2. bandın 222. satırdaki `.app-field .app-input` çözümüyle AYNI yöntem:
     genel bir ezme yerine ÖLÇÜLEN listeyi (0,2,1) ile yükselt. `max()` yine
     taban semantiğini korur — hiçbir değer düşmez. */
  body.edulive-cihaz .ad-sec,
  body.edulive-cihaz .af-sec,
  body.edulive-cihaz .ag-girdi,
  body.edulive-cihaz .ak-sec,
  body.edulive-cihaz .aoa-sec,
  body.edulive-cihaz .aps-sec,
  body.edulive-cihaz .ar-girdi,
  body.edulive-cihaz .aru-girdi,
  body.edulive-cihaz .asa-sec,
  body.edulive-cihaz .asi-girdi,
  body.edulive-cihaz .asr-sec,
  body.edulive-cihaz .au-input,
  body.edulive-cihaz .au-select,
  body.edulive-cihaz .cp__search-input,
  body.edulive-cihaz .ds__search-input {
    font-size: max(16px, 1rem);
  }

  /* --- 13.3 · TABLO BAŞLIĞI SIRALAMA DÜĞMESİ (K3) -------------------------
     ÖLÇÜM: `.at-sirala-btn` 20+ analiz rotasında 8x18 … 111x18.
     KÖK NEDEN (AnalizTablo.razor.css:53): `all: unset`. Bu, `display`i de
     sıfırlar -> düğme SATIR İÇİ (inline) kutuya döner. `min-height` satır içi
     kutuda ETKİSİZDİR; 6. bandın genel süpürmesi bu yüzden buraya işlemedi.
     Yükseklik 18 px = yalnız yazının satır kutusu.

     `padding-block` ile büyütmek düzeni HİÇ değiştirmezdi (satır içi kutuda
     dikey dolgu satır yüksekliğini etkilemez) ama dolgu ÜST SATIRIN üstüne
     taşar ve oradaki araç çubuğunun dokunuşlarını çalardı. Bu yüzden dürüst
     yol seçildi: kutuyu `inline-flex` yapıp 44 px ver. Bedeli, tablo başlık
     satırının ~36 -> 44 px'e çıkmasıdır (tablo başına BİR kez, 8 px). */
  body.edulive-cihaz .at-sirala-btn {
    display: inline-flex;
    align-items: center;
    min-height: 44px;

    /* GENİŞLİK (denetim sonrası ek): düzeltme sonrası ölçüm 20x44 … 111x44
       gösterdi — genişlik başlık YAZISININ genişliğidir, kuralla gelmez.
       Kısa başlıklarda ("#", "No") 20 px'e düşüyor. 44 px'lik `min-width`
       tablo başlık sütunlarını yapay olarak genişletir ve dar ekranda yatay
       taşma üretir (6. bandın kuralı); 24 px WCAG 2.5.8 (AA) tabanını
       karşılar ve hiçbir gerçek başlığı büyütmez. */
    min-width: 24px;
  }

  /* --- 13.4 · GRAFİK BÜYÜTME DÜĞMESİ (K20) --------------------------------
     ÖLÇÜM + KAYNAK (AnalizGrafik.razor.css:20-29):
       .ag-buyut { opacity: 0 }  ve  .ag-kap:hover .ag-buyut { opacity: 1 }
     Dokunmatikte `:hover` YOKTUR; `:focus-visible` de yoktur (odak halkası
     yalnız klavyeyle gelir). Yani 42 analiz rotasında grafiği tam ekran
     açmanın YOLU YOK — grafiğin okunmadığı şikayetinin ikinci yarısı budur
     (birinci yarısı 12. bantta chatbot grafiği için kapatıldı).

     K20 SAYIMI KAPANDI: bütün `.razor.css` dosyaları tarandı, `:hover` ile
     açığa çıkan yalnız ÜÇ seçici var — `.aa-eylemler` (12. bant kapattı),
     `.hub-card__glow` (salt süs, 2. bant zaten `display: none` yapıyor) ve
     buradaki `.ag-buyut`. Açık kalan kusur sınıfı yok. */
  body.edulive-cihaz .ag-buyut {
    opacity: 1;
  }

  /* --- 13.5 · GİZLİ DOSYA GİRDİSİ ÖLÇÜSÜNÜ KAYBEDİYOR (K2 + K3) -----------
     ÖLÇÜM: `/medya-studyo/sesler/klonla` 5 px, `/mufredat/ice-aktar` 9 px,
     `/tasarim-sistemi` 22 px yatay taşma; taşan öge her üçünde de
     `.app-upload__input` (343x25).
     KÖK NEDEN (D1 — bu projenin en öğretici hatası): AppFileUpload.razor:10
     `<InputFile class="app-upload__input">` yazıyor. Blazor'un kapsam
     özniteliğini (`b-duq9xbovo6`) YALNIZ bileşenin KENDİ işaretlemesindeki
     düz HTML ögelerine basar; bir ALT BİLEŞENİN kök ögesine BASMAZ. Bu yüzden
     `.app-upload__input[b-duq9xbovo6] { position: absolute; inset: 0 }` kuralı
     hiçbir zaman eşleşmiyor: girdi `static` akışta kalıyor, 343x25'lik ham
     dosya denetimi olarak çiziliyor ve kapsayıcısını (320x187) taşırıyor.
     Kapsamsız (bu dosya) yazınca kural nihayet eşleşir. */
  body.edulive-cihaz .app-upload .app-upload__input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
  }

  /* --- 13.6 · KÜÇÜK YAZI ARTIKLARI (K9) -----------------------------------
     ÖLÇÜM: `.aa-avatar` 10,5 px (chatbot rozet harfi, `/analiz/devamsizlik`
     dahil 3 rotada), `<kbd>` 10,5 px x3 (`/akademik/kurslar/yeni`).
     Eşik 11 px. `.cihaz-sekme__etiket` (10,5 px) BİLEREK dışarıda: iOS HIG
     sekme çubuğu etiketi ~10 pt'dir, 8. bandın kararıdır.
     `kbd` bir tür seçicisidir (0,0,1); kapsamlı kuralı yenmek için sınıf
     tekrarı ile (0,2,2)'ye çıkarıldı — `!important` gerekmedi. */
  body.edulive-cihaz .aa-avatar {
    font-size: 11px;
  }

  body.edulive-cihaz.edulive-cihaz kbd {
    font-size: max(11px, .8rem);
  }
}


/* --- 13.7 · TASARIM SİSTEMİ GALERİSİ: SABİT IZGARA TABANI (K2) ------------
   ÖLÇÜM: `/tasarim-sistemi` 22 px taşıyor; taşan `.app-field` ve alt ögeleri.
   KÖK NEDEN (Gallery.razor.css:113-130):
     .gal-grid    { grid-template-columns: repeat(auto-fill, minmax(240px,1fr)) }
     .gal-grid--2 { ... minmax(320px, 1fr) }   .gal-grid--3 { ... minmax(260px,1fr) }
   `minmax()`in ilk değeri SERT bir raylık en-küçüktür: kap 229 px olduğunda
   bile ray 320 px kalır ve `1fr` bunu KÜÇÜLTEMEZ. `min(320px, 100%)` deyimi
   tabanı kabın genişliğiyle sınırlar — geniş ekranda davranış birebir aynı,
   dar ekranda ray kaba sığar. (Bu, projede üçüncü kez görülen `minmax` tuzağı;
   TASARIM-MOBIL 13.12'de desen olarak kayıtlı.) */
body.edulive-cihaz .gal-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
}

body.edulive-cihaz .gal-grid--2 {
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
}

body.edulive-cihaz .gal-grid--3 {
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}


@media (hover: none) and (pointer: coarse) {

  /* --- 13.8 · TABLO BAŞLIĞINDAKİ "i" İPUCU DÜĞMESİ (K3 + K9) --------------
     ÖLÇÜM: bütün analiz rotalarında `BUTTON 9,92px` — kaynağı
     AnalizTablo.razor.css:114 `.at-ipucu__ac`: 14x14 daire, `.62rem` italik
     "i". Yani 42 rotada tekrar eden, 14 px'lik, 10 px yazılı bir hedef.
     Denetim aracı bunu S2'ye yazmadı çünkü ögenin metni bir sözde-öge
     değil gerçek metin ama `<button>` içinde tek karakter; eşiği ölçüm
     betiği yakaladı (`sm` alanı).

     NEDEN 44 DEĞİL 24: bu düğme, aynı başlık hücresindeki `.at-sirala-btn`in
     (13.3 ile 44 px'e çıktı) hemen yanındadır. 14 px'lik ögeyi 44'e çıkarmak
     — ister kutuyu büyüterek ister görünmez bir `::after` katmanıyla — her
     iki yönde 15 px taşar ve SIRALAMA dokunuşlarını çalar. Yardımcı bir
     ipucu için birincil denetimin dokunuşunu bozmak kötü bir takas.
     24x24 + 11 px, WCAG 2.5.8 (AA) "Target Size (Minimum)" eşiğini karşılar
     ve komşusuna değmez. K3'ün 44'ü birincil eylemler için geçerlidir. */
  body.edulive-cihaz .at-ipucu__ac {
    width: 24px;
    height: 24px;
    font-size: 11px;
  }

  /* --- 13.9 · `<small>` UA VARSAYILANI (K9) -------------------------------
     ÖLÇÜM: `/yonetim/kullanicilar` — 20 adet `SMALL` 10,8 px.
     KÖK NEDEN (admin-users.css:182): `.au-org small { color: var(--muted) }`
     — punto HİÇ yazılmamış. `<small>` tarayıcı varsayılanı `0.8em`'dir; ana
     kutu 13,5 px olunca 10,8 px'e düşer. Yazılmamış bir kural olduğu için
     kapsam özgüllüğü yok; (0,2,1) fazlasıyla yeter. */
  body.edulive-cihaz .au-org small {
    font-size: max(11px, 0.85em);
  }

  /* --- 13.10 · 2 PİKSEL EKSİK KALAN DÜĞME (K3) ---------------------------
     ÖLÇÜM: `.srp__btn` 42x44 (`/tasarim-sistemi`). Yükseklik 6. bantla
     düzelmiş, genişlik `padding: 9px 12px` + 13 px yazı yüzünden 42'de
     kalmış. `min-width` yalnız ÖLÇÜLMÜŞ dar düğmeye verilir (6. bandın
     kuralı: genel `min-width` yatay taşma üretir). */
  body.edulive-cihaz .srp__btn {
    min-width: 44px;
  }

  /* Aynı desen: `.pd-colors__picker` (UrunDuzenle.razor.css:82) `width: 42px`
     YAZILI bir renk seçicidir. `min-width` yazılı `width`i her zaman yener
     (kullanılan genişlik = max(width, min-width)) — bu yüzden kapsamlı
     kuralı ezmek için `!important` gerekmez. Yükseklik 6. bantla 44'e
     çıkmıştı; eksik olan tek eksen genişlikti. */
  body.edulive-cihaz .pd-colors__picker {
    min-width: 44px;
  }

  /* --- 13.11 · ÖLÇÜLEMEYEN KÜÇÜK PUNTOLAR — KAYNAK SAYIMI (K9) -----------
     GEREKÇE: 284 rotalık denetim BOŞ bir kiracı üzerinde koştu; veriye bağlı
     ögeler (takvim rozetleri, ay hücresi çipleri) hiç DOM'a girmedi, dolayısıyla
     ölçüme de girmedi. Bu yüzden `.razor.css` dosyalarında 11 px altına düşen
     her `font-size` bildirimi KAYNAK düzeyinde sayıldı (kök 16 px varsayımıyla
     `0.68rem`=10,88 · `0.66rem`=10,56 · `0.64rem`=10,24 · `0.62rem`=9,92).
     Sayım 6 dosyada 16 bildirim buldu; ikisi burada kapatılıyor, kalanı
     bilerek bırakılıyor (aşağıdaki not).

     (a) `aurora.css:656` `.chip .m` — 20x20 kutunun içinde baş harf rozeti,
         10 px. Küresel bir kural olduğu için her ekranda geçerli. 11 px
         hâlâ 20 px'lik kutuya sığar (satır yüksekliği `place-items: center`
         ile ortalanıyor, taşma yok). */
  body.edulive-cihaz .chip .m {
    font-size: 11px;
  }

  /* (b) `SocialMedia/Takvim.razor.css` — ay ızgarasının çipleri. Üçü de
         yalnız gönderi verisi varken doğar; denetimde görünmemelerinin
         sebebi budur. `.tk-chip` ayrıca bir `<button>` — küçük punto burada
         hem okunabilirliği hem dokunma hedefini etkiliyor; `min-height` ile
         WCAG 2.5.8 (AA) tabanına oturtuluyor. K3'ün 44'ü uygulanmıyor:
         bir ay hücresi 5-6 çip taşıyabilir, 44 px hücreyi patlatır —
         13.8'deki ile aynı gerekçeli taviz. */
  body.edulive-cihaz .tk-badge,
  body.edulive-cihaz .tk-chip,
  body.edulive-cihaz .tk-cell__more {
    font-size: 11px;
  }

  body.edulive-cihaz .tk-chip {
    min-height: 24px;
  }

  /* --- 13.12 · SINIFSIZ NATIVE DOSYA GİRİŞİ (K3) -------------------------
     ÖLÇÜM: `/sorular/toplu-uret` — `INPUT 343x25`. KAYNAK
     (SoruTopluUret.razor:47): `<InputFile OnChange … accept=".xlsx" />` —
     hiçbir sınıf, hiçbir kural. Android WebView bunu 25 px yüksekliğinde
     yerel bir "Dosya seç" düğmesi olarak çizer.

     SEÇİCİ NEDEN `:not([class])`: bu projede iki ayrı dosya-girişi deseni var.
     (1) SINIFLI/`::deep`li olanlar (`.app-upload__input`, `.vc-filebtn`
         içindeki) bilerek `opacity: 0` + `inset: 0`'dır — görünen düğme
         onların ARKASINDAKİ etikettir, dokunma hedefi zaten tam yüzeydir;
         onlara yükseklik vermek gereksiz, hatta kapsayıcıyı taşırabilir.
     (2) Hiç sınıfı olmayanlar yerel denetimin KENDİSİ olarak görünür — asıl
         dokunulan şey odur. `:not([class])` tam olarak ikinci kümeyi seçer.

     `::file-selector-button` ise her iki kümede de zararsızdır: görünmez
     girişte hiç çizilmez, görünende gerçekten dokunulan dikdörtgendir. */
  body.edulive-cihaz input[type="file"]:not([class]) {
    min-height: 44px;
  }

  body.edulive-cihaz input[type="file"]::file-selector-button {
    min-height: 44px;
    padding-inline: 12px;
  }

  /* BİLEREK DOKUNULMAYAN: `Components/Pages/Bbt/*` (BbtTakvim, BbtMiniTakvim,
     BbtSorular, BbtRaporlar) 12 bildirimle sayımın çoğunluğunu oluşturuyor.
     Dört rotası da `/bdt-*`: `/bdt-ornekler` üzerinde BAŞKA BİR OTURUM
     çalışıyor (kullanıcı bildirdi), `/bdt-sorular` parola kapılı ve
     denetimde `ERISIM-YOK` döndü. Ölçemediğim ve sahibi başkası olan bir
     yüzeye kör kural yazmak, düzelttiğinden çok bozar. O rotalar serbest
     kaldığında bu blok aynı desenle genişletilir. */

  /* --- 13.13 · İKİNCİ TAM DENETİMİN YENİ BULGULARI ----------------------
     284 rotalık ikinci koşu, ilk koşunun kapanmadığı DÖRT yüzey gösterdi.
     Dördü de ayrı kök nedene sahip; tek tek gerekçelendiriliyor. */

  /* (a) `/medya-studyo/sesler` — TAŞMA 260 px.
     Zincir: `sk-grid +260 → sk-card +260 → sk-card__player +157 → me +157`.
     İki ayrı kusur üst üste binmiş:
     · `SesKutuphanesi.razor.css:31` → `minmax(300px, 1fr)`. Bu kalıbın px
       değeri SERT alt sınırdır; 360 px'lik ekranda iz daralamaz (6. bandın
       ve 11 · 13.7 bantlarının aynı tuzağı — bu, dördüncü tekrarı).
     · `.sk-card` bir ızgara ÖGESİDİR ve ızgara ögesinin varsayılan
       `min-width` değeri `auto`'dur: içeriğinin min-content'inden dar
       olamaz. İçerikte native `<audio>` var; UA onu ~300 px doğal
       genişlikle ölçer (`width: 100%` içsel ölçümde `auto` gibi davranır),
       dolayısıyla kart 300 px'in altına inemiyordu. `min-width: 0` bu
       kilidi açar — kanonik çözüm budur, `overflow: hidden` DEĞİL (o,
       taşmayı gizler, oynatıcıyı kırpar). */
  body.edulive-cihaz .sk-grid {
    grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
    min-width: 0;
  }

  /* (a-2) SINIF ADI ÇAKIŞMASI — asıl 260 px'in kaynağı.
     `.sk-` öneki İKİ ayrı ekran ailesinde kullanılıyor: küresel
     `wwwroot/css/planlama.css:234` `.sk-grid { min-width: 640px }` (haftalık
     ders programı ızgarası) ve kapsamlı `SesKutuphanesi.razor.css:30`
     `.sk-grid` (ses kartları). Kapsamlı CSS `min-width` BİLDİRMEDİĞİ için
     küresel 640 px ses kütüphanesine SIZIYOR — 412 px'lik ekranda tam
     +228…260 px. Kapsam eki yalnızca kendi bildirdiği özellikleri korur.
     Çözüm iki katmanlı: `.sk-grid` genelinde kilidi aç, gerçek program
     ızgarasında geri ver. Program ızgarasının iki kullanımı da
     (`TaslakDetay.razor:88`, `TaslakOnay.razor:126`)
     `.sk-grid-wrap { overflow-x: auto }` içinde olduğundan 640 px orada
     zararsızdır — yatay kaydırma zaten tasarımın parçası. */
  body.edulive-cihaz .sk-grid-wrap > .sk-grid {
    min-width: 640px;
  }

  body.edulive-cihaz .sk-card,
  body.edulive-cihaz .sk-card__player,
  body.edulive-cihaz .sk-card__player .me {
    min-width: 0;
  }

  body.edulive-cihaz .me-audio {
    min-width: 0;
    max-width: 100%;
  }

  /* (b) `.app-tree__row` — 35 px yükseklik, 6 rotada ölçüldü
     (`/akademik/alanlar`, `/akademik/<x>/yeni`, `/admin/wallet/sub-pools/new`).
     `AppTree.razor.css:20` `padding: 7px 10px` veriyor; satır `cursor:
     pointer` ile TIKLANABİLİR — yani gerçek bir dokunma hedefi, dekoratif
     bir çizgi değil. Burada 44 px güvenli: ağaç dikey akar, yatay taşma
     riski yok. */
  body.edulive-cihaz .app-tree__row {
    min-height: 44px;
  }

  /* (c) ANALİZ ARALIK SÜZGECİ — kullanıcının öncelik verdiği analiz
     yüzeyinde, BOŞ kiracıda hiç DOM'a girmediği için ölçüme yakalanmayan
     iki hedef (13.11'in kaynak-sayımı yöntemiyle bulundu):
     · Tutamak 15x15 px (`AnalizAralikSuzgec.razor.css:42/48`). Parmakla
       çift tutamaklı bir aralık sürüklemek bu boyutta pratikte imkânsız.
       24 px WCAG 2.5.8 (AA) tabanıdır; iOS/Android yerel kaydırıcıları
       zaten bu bantta.
     · Kabın yüksekliği 20 px olduğundan 24 px'lik tutamak kabı 2'şer px
       taşardı ve WebKit'te isabet alanı kabın kutusuna kırpılabilir. Bu
       yüzden kap 24 px'e çıkarılıp `bottom: -2px` ile aşağı kaydırılıyor:
       tutamağın MERKEZİ rayın merkezinde (alttan 10 px) KALIR, hizalama
       bozulmaz. Kap `pointer-events: none` olduğu için büyümesi
       histogramdan dokunuş çalmaz. */
  body.edulive-cihaz .aas__tutamak {
    height: 24px;
    bottom: -2px;
  }

  body.edulive-cihaz .aas__tutamak::-webkit-slider-thumb {
    width: 24px;
    height: 24px;
  }

  body.edulive-cihaz .aas__tutamak::-moz-range-thumb {
    width: 24px;
    height: 24px;
  }

  /* Süzgecin "Sıfırla" düğmesi `padding: 0` + `.75rem` ile ~40x16'dır.
     `<button>` olduğu için satır-içi metin bağlantısı istisnası (13.4)
     GEÇERLİ DEĞİL — bağımsız bir denetimdir, 44 px alır. Başlık satırı
     `align-items: baseline` olduğundan `inline-flex` + `align-items:
     center` ile metin dikeyde ortalanır. */
  body.edulive-cihaz .aas__sifirla {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* (d) `.au-btn` — `/medya-studyo/sesler` ölçümünde 40x44. Yükseklik
     tamam, genişlik 4 px eksik (ikon-only içerik). Aurora'nın GENEL
     sınıfı olduğu için tek satırlık `min-width` tüm tüketicilerde 4 px
     büyütür; hiçbir yerde satır kırılmasına yetecek bir fark değil. */
  body.edulive-cihaz .au-btn {
    min-width: 44px;
  }

  /* (e) `.sdg` — analiz tablolarının satır-içi "sepete ekle" düğmesi
     (`SepetDugmesi.razor.css:6`, 26x26). 12 analiz tablosunda geçiyor;
     kullanıcının öncelik verdiği yüzeyin ASIL eylemi bu. Boş kiracıda
     satır üretilmediği için canlı denetime hiç yakalanmadı — 13.11'in
     kaynak-sayımı yöntemiyle bulundu.
     Burada 24 px'e değil 44 px'e çıkıyorum: `.at-sirala-btn`'de (13.3)
     genişlik vermekten kaçınmamın sebebi başlık sütunlarını şişirip YATAY
     TAŞMA üretmesiydi; oysa `AnalizTablo.razor.css:2` kapsayıcıya
     `overflow-x: auto` veriyor — tablo zaten kendi içinde kayıyor, sayfa
     taşmıyor. Kısıt yoksa proje standardı (K3) uygulanır. */
  body.edulive-cihaz .sdg {
    min-width: 44px;
    min-height: 44px;
  }

  /* --- 13.14 · ETİKETE SARILI ONAY KUTULARI + DOSYA GİRİŞİ DÜZELTMESİ ----
     13.2'de onay kutusu/radyo, K3'ün 44 px tabanından BİLEREK dışlanmıştı:
     "kutunun kendisi büyütülmez; dokunma hedefi onu saran <label> ögesidir."
     Bu doğru — ama yarım kalmış: o etiketlerin HİÇBİRİNDE min-height yok.

     PROJE SAYIMI (grep, 17 ayrı sınıf): `.as-onay` (6 kez), `.atn-onay` (4),
     `.asp-onay` (4), `.sm-gen__opt` (3), `.mfa-ack`, `.kd-check`, `.he-check`,
     `.hq-selectall`, `.cd-section-req`, `.aba-onay`, `.sde-boolrow` …
     Okunan CSS'te hepsi ZATEN `display: flex | inline-flex` + kendi `gap`ı ile
     tanımlı; tek eksikleri yükseklik. Bu yüzden burada YALNIZCA `min-height`
     veriyorum — `display` ya da `gap`e dokunmak, satır-içi metnin kendi
     boşluğunu bozma riski taşırdı (flex, metin düğümleri arasındaki boşluğu
     yutar). Zaten flex olan bir etikette `align-items: center` de mevcut,
     dolayısıyla 44'e çıkan kutuda metin ortalı kalır.

     SEÇİCİ: `:has(> input[type="checkbox"])` — yalnız kutuyu SARAN etiketi
     seçer. `for=` ile bağlı olanlar (`.ks__card-body`, `.cp__card-body`)
     eşleşmez; onlar zaten bütün bir kartı kaplıyor ve 44'ün üstünde.
     `:has()` Chrome 105+; desteklenmeyen ortamda yalnız bu kural düşer,
     yanına yazılmış hiçbir şey etkilenmez (geçersiz seçici = ölü kural). */
  body.edulive-cihaz label:has(> input[type="checkbox"]),
  body.edulive-cihaz label:has(> input[type="radio"]) {
    min-height: 44px;
  }

  /* 13.12 DÜZELTMESİ. Orada "sınıfsız girişler yerel denetimin KENDİSİDİR"
     demiştim; ikinci denetim bir istisna gösterdi: `VisualPlanCreate`
     (`.razor.css:14`) dosya girişini `.vc-filebtn ::deep input[type="file"]`
     ile — yani girişin KENDİSİNE sınıf vermeden — `opacity: 0; inset: 0`
     yapıyor. Görünen düğme arkasındaki `<label class="au-btn">`. Böyle bir
     girişe 44 px taban vermek, etiketten taşan görünmez bir dokunma alanı
     üretir. Etiket çocuğu olan dosya girişlerinde tabanı geri alıyorum;
     (0,3,3) > (0,3,2) olduğu için 13.12'nin kuralını yener. */
  body.edulive-cihaz label > input[type="file"]:not([class]) {
    min-height: 0;
  }
}

/* ===========================================================================
   14 · SINIFSIZ `<pre>` — "TEKNİK AYRINTI" BLOKLARININ YATAY TAŞMASI
   Kabul kriteri K2 (yatay taşma yok) · K9 (ham teknik kimlik yüzeye basılmaz)

   YÖNTEM — cihazsız, statik kaynak analizi
   ----------------------------------------
   Kullanıcı emri: "emülatörsüz devam et, statik analizle sayfaları düzelt".
   Bu bandın hiçbir kuralı canlı ölçüme dayanmıyor; her biri KAYNAKTAN
   ispatlanabilir bir CSS olgusuna dayanıyor. İspatlanamayan hiçbir şey
   kural olarak yazılmadı (aşağıdaki "elenenler" listesine bak).

   OLGU: `<pre>` ögesinin kullanıcı-ajanı varsayılanı `white-space: pre`dir.
   Satır kırılmaz; ögenin min-content genişliği EN UZUN SATIR kadar olur.
   Kapsayıcı `overflow` vermiyorsa taşma ızgara/blok zincirini yukarı doğru
   iterek BELGE düzeyinde yatay kaymaya döner (13.1 ile aynı mekanizma).

   SAYIM (grep, `--include=*.razor`, obj hariç): projede 13 `<pre>` var.
   Onunda sınıf var ve okundu — `.au-code` (3 kez) · `.amt-content` ·
   `.ctx-text` · `.etl-result__json` · `.pai-result__text` ·
   `.prm-preview__text` · `.md-lyrics` · `AuditLog` satır-içi biçimli.
   Bunların HEPSİ kendi `.razor.css` dosyasında zaten korumalı
   (`white-space: pre-wrap` + `word-break: break-word` + `overflow: auto`),
   `AuditLog` ise satır içinde `overflow-x: auto` taşıyor -> KURAL YAZILMADI.

   Geriye SINIFSIZ üç kullanım kalıyor, üçü de aynı desende:
     Ui/JobMonitor.razor:43              `<details class="jm-tech">`
     Pages/Content/JobDetail.razor:80    `<details class="jd-err-tech">`
     Pages/Question/SoruUretimIzleme.razor:71  `<details class="si-err-tech">`
   Üçü de `<summary>Teknik ayrıntı</summary>` altında ham hata metni basıyor
   (yığın izi, JSON, uzun URL). `wwwroot` altında `pre` ögesini hedefleyen
   TEK BİR genel kural yok (grep: 0 eşleşme) -> varsayılan `pre` yürürlükte,
   yani bu üç blok açıldığı anda sayfa yatay kayar. JobMonitor bir Ui
   bileşeni olduğu için kusur tek sayfada değil, onu tüketen her ekranda.

   SEÇİCİ NEDEN `details` İLE DARALTILDI
   -------------------------------------
   Çıplak `pre:not([class])` yazmak kolaydı ama 12. bandın ölçümünü bozardı:
   asistanın markdown gövdesi kod bloklarını da sınıfsız `<pre>` olarak basar
   ve orada `.aa-md pre` kuralı BİLEREK `overflow-x: auto` verir — 12. bant
   bunu "kendi kabında kayıyor, sözleşmenin istediği davranış" diye kabul
   etmişti (satır 1334-1337). Koda `pre-wrap` vermek hizalamayı bozardı.
   `details` bağlamı üç kusurlu yeri de kapsar, asistanı hiç kapsamaz.
   Özgüllük: (0,2,3) — `.jm-tech`in kapsamlı kuralı (0,2,0) olsaydı bile yener,
   ama zaten çakışan bir bildirim yok.

   `max-height: 40vh`: yığın izi ekranı boydan boya doldurup altındaki eylemi
   kaydırma dışına itmesin. `overflow: auto` ile birlikte blok kendi içinde
   kayar — 13.1 ve 8. bandın kurduğu "taşma kapsayıcıda kalır" ilkesi.

   ELENENLER (statik olarak bakıldı, kusur ÇIKMADI -> kural yazılmadı)
   ------------------------------------------------------------------
   • On katı ızgara (`.ct-split` 640 · `.pai-layout` 680 · `.prm-split` 680 ·
     `.agp-split` · `.cmr-split` · `.cvh-split` · `.mtp-split` · `.std-split` ·
     `.itl-grid` · `.sis-etl`, 580-680 px sert taban): `/tmp/izgara.py` ile
     tarandı, onunun da kendi `.razor.css` dosyasında telefon bandında
     `grid-template-columns: 1fr` ile çöktüğü görüldü. Araca güvenmeyip üçü
     elle de okundu (`.ct-split` · `.prm-split` · `.pai-layout`) — doğrulandı.
   • `min-width: 320-480px` taşıyan beş denetim: `.aps-sec` ve `.asa-sec`
     13.2'de CANLI 320x32 ölçülmüştü (o bandın ölçüm satırı), `.asa-sinav`
     `max-width: 100%` taşıyor, `.bs-matrix` `.bs-matrix-wrap` kaydırıcısının
     içinde. Hiçbiri kusur değil.
   • `AppDataGrid`: `.grid-scroll` `overflow-x: auto`, `.grid-table`ta
     `min-width` yok, `.grid-search` 42 px zaten 13.2nin genel taban kuralıyla
     44e çıkıyor (satır 1611).
   =========================================================================== */

body.edulive-cihaz details pre:not([class]) {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 40vh;
  overflow: auto;
  margin: 0;
}

/* Satır içi `<code>`: uzun kimlik/anahtar (KIE `ModelKey`, `KieJobId`, gizli
   önek) hücreyi min-content tabanından şişirebilir. `anywhere`, `break-word`un
   aksine min-content katkısını da düşürür — ızgara/tablo hücresinin taban
   genişliğini gerçekten küçülten tek değer budur. `pre` içindeki `code`
   DIŞLANDI: orada `white-space: pre` sarmayı zaten kapatır, kural etkisiz
   olurdu ama asistanın kaydırma davranışıyla ilgili yanlış bir izlenim
   bırakırdı. */
body.edulive-cihaz :not(pre) > code {
  overflow-wrap: anywhere;
}

/* `.md-lyrics` (MuzikDetay.razor.css:52) `white-space: pre-wrap` taşıyor ama
   `word-break`/`overflow-wrap` YOK — boşluksuz uzun bir dize (AI üretimi söz
   metninde geçebilen bağlantı ya da etiket) sarma noktası bulamaz. Tek satır
   ek; yerel kuralın diğer bildirimlerine dokunmuyor. */
body.edulive-cihaz .md-lyrics {
  overflow-wrap: anywhere;
}

/* ===========================================================================
   15 · YATAY SIKIŞMA — KÜÇÜLEMEYEN ESNEK ÇOCUK ve SERT TABANLI IZGARA

   İki mekanik tarama yapıldı, ikisi de kaynak ağacın TAMAMI üzerinde:

   A) `white-space: nowrap` taraması (/tmp/nowrap.py — blok düzeyinde, yalnız
      dosya düzeyinde değil): 105 bildirim, 46'sı KORUMALI (aynı blokta
      `text-overflow: ellipsis` ya da `overflow(-x): auto|scroll|hidden`),
      59'u aday. Adayların elenmesi tek tek KANIT ile yapıldı:
        - 16 aday `th`/`td` seçicisi -> 8. bandın `table { display: block;
          overflow-x: auto }` kuralı zaten kapsıyor.
        - `.nc-tab`: ebeveyni `.nc-tabs` `overflow-x: auto` taşıyor
          (NotificationCenter.razor.css:71). Betik ebeveyni göremez, markup
          okundu.
        - `.jft-timehead` `.av-timehead` `.sk-grid__timehead`: üçünün de kabı
          kaydırıcı (planlama.css:140 ve 232, OrtakBosZaman.razor.css:52).
        - İçeriği ölçülüp kısa çıkanlar: `.ad-fail__row` ("Satır 12"),
          `.dz-bar-label` ("5 yıldız"), `.psi-item__meta` (dd.MM.yyyy),
          `.bbt-whatsapp__no` (telefon numarası), `.ks__code` (kazanım kodu),
          `.vo-progress__label` ("3 / 10 soru"), `.asc-draft__check`
          ("Seçildi"), `.rcard .st` ve `.an-period` (durum rozetleri).
        - `.amn__sekme`: ebeveyn `.amn` `flex-wrap: wrap` -> nowrap yalnız
          etiket içi kırılmayı engelliyor, satır sarıyor.
        - `.he-bar__label`: 96 px sert ızgara izinde duruyor ama sözlükteki
          en uzun etiket "Uzmanlık" (HocaEslestirme.razor:194) — 12,5 px'te
          ~60 px. Taşmıyor.
        - `.psi-item__name`: nowrap TAŞIMIYOR (nowrap kardeşi `__meta`de) ve
          içeriği `Truncate(..., 80)` ile zaten kısaltılıyor.
      Geriye TEK kusur kaldı: `.as-satir__ad`.

   B) Sert taban taraması (/tmp/genislik.py): `width` / `min-width` /
      `flex-basis` >= 340 px olan 10 bildirim + sabit piksel izlerin toplamı
      >= 340 px olan 22 ızgara. Bunların da çoğu kanıtla elendi:
        - `auto-fit`/`auto-fill` + `minmax`/`clamp` kalıpları (`.au-filters`
          `minmax(200px, 240px)`, `.cards` `minmax(clamp(260px, 28vw, 320px),
          1fr)`): betik iki ucu toplar, gerçekte telefonda TEK sütuna düşer.
        - On `-split` ızgara: 14. bantta zaten doğrulanmıştı (her biri kendi
          `.razor.css` dosyasında telefon bandında `1fr`e çöküyor).
        - `.qr` `.ts-layout` `.vg-layout` `.lre-objrow` `.dz-summary__grid`
          `.au-split`: hepsinin kendi dosyasında `max-width` medya bloğu var
          (/tmp/izgara2.py ile tarandı, 640-900 px eşikleri).
        - `.pg-table` ve `.pg-heat`: ikisi de `.pg-table-wrap` kaydırıcısının
          içinde (ProgramGorunumu.razor:106). CSS'te `.pg-heatwrap` ayrı bir
          kap gibi duruyor, markup okunmasa yanlış kural yazılacaktı.
        - `.pg-list`: kabı `.pg-list-scroll` `overflow-y: auto` taşıyor; CSS
          kuralı gereği bir eksen `visible` dışıysa diğeri `auto` hesaplanır.
        - `.b1` `.b2` `.b3` ve `.blob`: dekoratif bulanık lekeler, konumları
          `position: absolute` ve kap `overflow: hidden`.
        - `.sis-bina-row` (`1fr minmax(200px, 260px)`, boşluk 12): sert taban
          ~212 px + bina adının min-content'i; ad sarabildiği için 375 px'lik
          ekranın iç genişliğine (kart dolgusundan sonra ~319 px) sığıyor.
          SINIRDA ama kusur değil — kardeşi `.sis-divrow` sığmıyor.
      Geriye TEK kusur kaldı: `.sis-divrow`.

   KUSUR 1 — `.as-satir__ad` (AnalizSepet.razor.css:53)
   ----------------------------------------------------
   Analiz sepetindeki öğrenci satırı esnek bir kap; yazar kardeş alanı
   `.as-satir__meta`yi `min-width: 0; overflow: hidden; text-overflow:
   ellipsis` ile korumuş ama adın kendisini korumayı atlamış. Esnek çocuğun
   otomatik en küçük boyutu min-content'tir; `nowrap` yüzünden bu, öğrencinin
   TAM ADININ tamamı demektir (AnalizSepet.razor:33 — `@o.TamAd`). Uzun ad =
   panel telefonda yatay taşar, silme düğmesi ekran dışına çıkar.
   Çözüm üç bildirim: küçülmeye izin ver, taşanı kırp, üç nokta koy. Bant
   sınırı YOK — kısaltma yalnız gerçekten taşma varsa görünür, masaüstünde
   davranış değişmez.

   KUSUR 2 — `.sis-divrow` (planlama.css:373)
   -------------------------------------------
   SIS sihirbazının alt-grup bölme satırı:
   `minmax(160px, 1fr) minmax(180px, 240px) auto` + iki 12 px boşluk.
   Sert taban 160 + 12 + 180 + 12 + düğme (~55) = ~419 px. Telefonun kart içi
   kullanılabilir genişliği ~319 px. Kesin taşma; üstelik satır bir `<li>`
   listesinde tekrar ettiği için sihirbazın o adımı boydan boya kayıyor
   (SisGroupDivisionsStep.razor:46).
   Telefonda tek sütun: ad, metin alanı, düğme alt alta. Düğme sağa hizalı
   kalsın diye `justify-self: end` — üç sütunlu düzendeki sağ kenar duygusu
   korunur. Yalnız telefon bandı: tablette 641 px'ten itibaren üç sütun
   rahat sığıyor.

   Özgüllük: her iki kural da `body.edulive-cihaz` öneki ile (0,2,1); kaynak
   bildirimler kapsamlı CSS'te (0,2,0) ya da global CSS'te (0,1,0) — `!important`
   gerekmiyor, K10 sayacı 0'da kalıyor.
   =========================================================================== */

body.edulive-cihaz .as-satir__ad {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 640px) {
  body.edulive-cihaz .sis-divrow {
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  body.edulive-cihaz .sis-divrow > button {
    justify-self: end;
  }
}

/* =========================================================================
   16. BANT — YÜZEN KROM ile ALT SEKME ÇUBUĞU ÇAKIŞMASI
   (Tur 27I · cihazsız statik tur)

   NEDEN BİR BANT GEREKTİ. frontend-3 WEB için yazıldı; web'de ekranın
   altında HİÇBİR ŞEY yok. Cihaz kabuğu ise 4. bantta ekranın altına
   `.cihaz-sekme` koyuyor: `position: fixed; bottom: 0;
   height: 56px + güvenli alan; z-index: 65`. Dolayısıyla kaynaktaki her
   "alta demirlenmiş sabit" öğe iki şekilde bozulur:
     (a) z-index'i 65'in ALTINDAysa çubuğun ARKASINDA kalır — görünmez,
         dokunulamaz;
     (b) 65'in ÜSTÜNDEyse çubuğu ÖRTER — gezinme kaybolur.
   Bu bant her iki yönü de düzeltir. Kaynağın kendi iç istifi KORUNUR:
   z-index'ler aynı farkla (+11) yukarı taşınır, sıralama değişmez.

   TARAMA (/tmp/sabit.py — tüm `.css`, obj/bin hariç, blok düzeyi):
   `position: fixed|sticky` taşıyan **54 blok**. Ayıklama:
     · 21 perde/örtü `inset: 0` — z 56-92, alta demirli değil, sorun yok.
     · 9 modal `top:50% + translate` — dikey merkezli, çubukla ilişkisiz
       (dar ekran modal davranışı AYRI bir eksendir, bu turda ele alınmadı).
     · 6 `sticky top:0` başlık (`thead th`, `.topbar`, `.imp-banner`) — üst
       kenar; çubuk alt kenarda.
     · 2 `sticky top:12px` yan panel (`.ks__panel`, `.vg-side`) — üst kenar.
     · 8 BBT bloğu (`.bbt-stage`, `.bbt-loupe`, `.bbt-tkv-overlay`) —
       KABUKSUZ rotalar: `/bdt-ornekler`, `/bdt-sorular` ve `-k12` ikizleri
       `RotaCozumleyici.KabuksuzRota`da (satır 42-43), o rotalarda çubuk
       ÇİZİLMEZ. `BbtTakvim` yalnız `BbtSorular.razor:251`den çağrılıyor,
       o da kabuksuz. Eleme kanıtlı.
     · `.aa-dibe` (`sticky bottom:12px`) — kaynağı kaydıran kap
       `.aa-kabuk`tır ve 13. bant onun yüksekliğini
       `calc(100dvh - --topbar-h - --sekme-h - --sekme-alt - 28px)` yapmıştı
       (satır 1379): sticky pil zaten çubuğun ÜSTÜNDE bitiyor.
     · 8 blok KUSURLU — aşağıda tek tek.

   ÖLÇÜ. Çubuğun kapladığı yükseklik `--sekme-h + --sekme-alt`
   (360x780 iPhone: 56 + 34 = 90 px). Kurallar kaynağın kendi `bottom`
   değerini KORUYUP üstüne bu payı ekliyor — yani yazarın seçtiği boşluk
   (78 px rehber düğmesi) aynen duruyor, yalnız sıfır noktası çubuğun
   üstüne kayıyor. Öğrenci sepeti 2026-09-17'den beri üstten konumlanır,
   bkz. (1).

   MEDYA KOŞULU 4. bantla AYNI OLMAK ZORUNDA: `--sekme-h`/`--sekme-alt`
   yalnız orada tanımlı. Başka bir koşulda yazılsaydı `var()` çözümsüz
   kalır, `calc()` tamamen geçersiz olur ve kural sessizce düşerdi.

   ÖZGÜLLÜK: `body.edulive-cihaz .X` = (0,2,1); kapsamlı CSS'in
   `.X[b-xxxxx]` kuralı (0,2,0). `!important` GEREKMEDİ (K10; dosyadaki
   yorum-dışı `!important` sayısı hâlâ 0).
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- (1) Öğrenci sepeti — analiz ekranlarının ana eylemi ----------------
     KUSUR (a) tipi, bu taramanın en ağırı: `.as-rozet` z-index **55**,
     çubuk 65. Sepet çubuğun arkasında kalırsa telefonda sepete ULAŞILAMAZ —
     sepet açılamıyorsa analiz akışı kopuyor. İç istif korunarak +11
     kaydırıldı: 55->66, 56->67, 57->68. Üst sınır kontrol edildi: hesap
     menüsü 70, modal/diyalog 80-92, "Diğer" sayfası 78/79 — hiçbirinin
     altını oymuyoruz.
     2026-09-17: sağ-alt yüzen rozet SAĞ KENAR RAYI, alttan açılan çekmece
     kenara yapışmayan YAN KART oldu (AnalizSepet.razor.css). İkisi de artık
     ÜSTTEN konumlanır; eski `bottom` kuralı burada kalsaydı `top` ile
     birlikte rayı boydan boya uzatırdı. Kart üst barın 12 px altında
     başlar, çubuğun 12 px üstünde biter; 360 px ekranda iki yandan 12 px
     boşlukla tam ene iner. */
  body.edulive-cihaz .as-rozet {
    top: calc(var(--topbar-h) + 150px);
    z-index: 66;
  }

  body.edulive-cihaz .as-perde {
    z-index: 67;
  }

  body.edulive-cihaz .as-panel {
    top: calc(var(--topbar-h) + 12px);
    left: 12px;
    right: auto;
    bottom: calc(var(--sekme-h) + var(--sekme-alt) + 12px);
    width: min(378px, calc(100vw - 24px));
    z-index: 68;
  }

  /* 2026-09-17 üçüncü tur: sepet SOLA geçti, telefonda ray sağda kaldı
     (gerekçe AnalizSepet.razor.css başında). Kart rayın tarafından açılır. */
  @media (max-width: 640px) {
    body.edulive-cihaz .as-panel {
      left: auto;
      right: 12px;
    }
  }

  /* Ayrıntı ve büyütülmüş grafik alt sekmenin üstünde biter; kapatma eylemi görünür kalır. */
  body.edulive-cihaz .ap-pencereler,
  body.edulive-cihaz .ap-perde {
    bottom: calc(var(--sekme-h) + var(--sekme-alt));
  }
  body.edulive-cihaz .ag-kap--buyuk {
    bottom: calc(var(--sekme-h) + var(--sekme-alt) + 12px);
  }

  /* --- (2) Rehber açma düğmesi ------------------------------------------
     `.ar-ac` z-index 55 (AnalizRehber.razor.css:26), `bottom: 78px`.
     6. bantta dokunma hedefi 44x44'e çıkarıldığı için 78..122 px'i
     kaplıyor; çubuk 0..90 -> alt 12 px'i çubuğun arkasında ve tıklama
     oraya düşerse çubuğa gidiyor. Eskiden sepet rozetiyle aynı sütundaydı
     (20 -> 78 farkı); rozet 2026-09-17'de sağ kenar rayına taşındı, bu
     kayma artık yalnız rehber düğmesi içindir. */
  body.edulive-cihaz .ar-ac {
    bottom: calc(var(--sekme-h) + var(--sekme-alt) + 78px);
    z-index: 66;
  }

  body.edulive-cihaz .az-sayfa .au-head .ar-ac {
    bottom: auto;
    z-index: auto;
  }

  /* --- (3) Bildirim yığını ----------------------------------------------
     KUSUR (b) tipi: `.toast-host` z-index **1000** — çubuğun üstünde
     çiziliyor ve `bottom: 20px` ile tam onun üzerine oturuyor. Kap
     `pointer-events: none` ama `.toast` `auto` (ToastHost.razor.css:10,27):
     bildirim görünürken altındaki sekme dokunulamaz hale geliyor.
     z-index'e DOKUNULMADI (bildirim her şeyin üstünde kalmalı); yalnız
     çubuğun üstüne kaldırıldı. */
  body.edulive-cihaz .toast-host {
    bottom: calc(var(--sekme-h) + var(--sekme-alt) + 20px);
  }

  /* --- (4) Hata şeridi ---------------------------------------------------
     `#blazor-error-ui` (app.css:109) `bottom: 0; z-index: 1000` — hata
     anında tam olarak çubuğun üstüne biniyor, "Yenile" bağlantısı ve
     kapatma çarpısı sekmelerle çakışıyor. Kimlik seçicisi `#id` (1,0,0)
     olduğu için burada da `#` ile yazıldı; sınıf seçici kazanamazdı. */
  body.edulive-cihaz #blazor-error-ui {
    bottom: calc(var(--sekme-h) + var(--sekme-alt));
  }

  /* --- (5) Analiz pencere şeridi ----------------------------------------
     `.ap-pencereler` (AnalizPanelHost.razor.css:20) `bottom: 0; z-index: 61`
     — çubuk 65 olduğu için panelin ALT 90 px'i çubuğun arkasında. Panelin
     dibinde ne varsa (liste sonu, eylem şeridi) telefonda erişilemiyordu.
     Perdeye (`.ap-perde`, z 60) DOKUNULMADI: o zaten üstbarın altından
     başlayan yumuşak bir karartma; çubuğun onun üstünde kalması gezinmeyi
     açık tutuyor ve bu pencere kilitleyen bir modal değil. */
  body.edulive-cihaz .ap-pencereler {
    bottom: calc(var(--sekme-h) + var(--sekme-alt));
  }

  /* --- (6) Büyütülmüş grafik: KURAL 17. BANTTA, BURADA DEĞİL --------------
     Tur 27I'de buraya `.ag-kap--buyuk` için alt kenar boşluğu yazılmıştı.
     Tur 27J'de KALDIRILDI: o kutu, kaynağında üstbarın (z 50) üstüne
     çıkacak şekilde z-index 61 ile yazılmış — yani KROMU ÖRTMEK niyetiyle
     tasarlanmış bir ışık kutusu. Doğru düzeltme onu çubuğun ÜSTÜNE almaktır
     (17. bant, z 83), çubuğun üstünde durmak için dibini kesmek değil.
     İki kural birlikte dururken ikincisi ölü koddu. */
}


/* ===========================================================================
   17 · KATMAN MERDİVENİ: SAYFA KATMANLARI SEKME ÇUBUĞUNUN ALTINDA KALIYOR
   YALNIZ CİHAZ BANDI (4. ve 16. bantla AYNI medya koşulu) — K9 · K10 · K21

   SORUN — iki katmanlı, ikincisi asıl kök neden
   --------------------------------------------
   (A) Görünen belirti: kaynaktaki 15 sabit örtü katmanı (perde, modal,
       çekmece, açılır panel) z-index 40..61 aralığında yazılmış. Cihaz
       kabuğunun alt gezinme çubuğu ise z-index 65. Yani KİLİTLEYEN bir
       perde açıkken bile çubuk onun üstünde çiziliyor ve dokunuşu alıyor:
       kullanıcı "kapat" demeden başka bir sekmeye geçebiliyor, kritik
       akışlarda (parola yeniden doğrulama, geri alınamaz silme) modal
       aşılabiliyor.

   (B) KÖK NEDEN — z-index sayıları zaten HİÇ okunmuyordu.
       `MainLayout.razor:78` içeriği `<main class="wrap">` ile sarar ve
       `aurora.css:585` bu elemana `position: relative; z-index: 1` verir.
       Bu bir YIĞIN BAĞLAMIDIR (stacking context). Bağlam içindeki her
       eleman — 61 de yazsa, 100000 de yazsa — dış dünyada `.wrap`in tek
       bir değeriyle, yani 1 ile boy ölçüşür. Öğrenci düzeninde aynı tuzak
       `.student-wrap` ile kurulur (`StudentLayout.razor.css:137-139`).
       Sonuç: sayfa içinde yazılmış HİÇBİR örtü, üstbarın (50) ya da sekme
       çubuğunun (65) üstüne çıkamaz. Tekil seçicilere z-index yazmak
       bu tuzak kaldırılmadan HİÇBİR ŞEY DEĞİŞTİRMEZ.

       Bu, 27F turunun dersinin dördüncü kez doğrulanmasıdır: stil sayfası
       tek başına yeterli değil, DOM yuvalanması doğrulanmadan kural yazma.
       Kanıt zinciri: `MainLayout.razor:78` · `aurora.css:585-587` ·
       `StudentLayout.razor.css:137-139`.

   İKİNCİ BAĞLAM: ÜSTBAR
   ---------------------
   `.topbar` (aurora.css:224-226) `position: sticky; z-index: 50` — o da bir
   yığın bağlamı. Hesap menüsü (`.menu`, aurora.css:493, z 70), kurum
   seçici (`.ou-switch__menu`, z 60), bildirim açılırı (`.nbell__menu`, z 60)
   ve iki kapatma perdesi ONUN İÇİNDE (`MainLayout.razor:45,48,54`). Üçü de
   dışarıda 50 olarak görünür, yani çubuğun altında. Tek tek yükseltmek
   burada da işe yaramaz; yükseltilmesi gereken KAPSAYICIDIR.

   TARAMA (bu turda, `/tmp/zsira.py` + z-index >= 45 dökümü)
   --------------------------------------------------------
   z=90..92  `.qrd-*` `.cd-*` `.etl-guard*` `.ar-*` `.ts-*` `.imp-banner`
             -> (B) kalkınca kendiliğinden çubuğun üstüne çıkar, KURAL YOK.
   z=60/61   `.sum-*` `.pk-*` `.ap-*` `.ag-*` `.aa-yan` açılırlar
   z=58/59   `.ase__perde` `.ase__panel`
   z=55/56/57 `.as-*` `.ar-ac` `.nbell__scrim` `.ou-switch__scrim`
   z=50      `.app-ms__scrim`
   z=40/41   `.ss-perde` `.ss-dialog`
   `Bbt*` ekranları ELENDİ: `@layout EmptyLayout` kullanıyorlar, o düzende
   `.wrap` YOK (`EmptyLayout.razor` yalnız `.auth-shell`), ayrıca kullanıcının
   öteki ajanının işi — bu bandın hiçbir seçicisi onların sınıflarını tutmaz.

   TUZAKLAR — bu turda ölçülüp kurala çevrilenler
   ----------------------------------------------
   1. `.ase__perde` SABİT (z 58) ama `.ase__panel` MUTLAK (z 59) ve ikisi
      aynı bağlamda. Yalnız perdeyi yükseltmek paneli perdenin ARKASINA
      gömerdi. İkisi birlikte taşınır, aradaki fark korunur.
   2. `.ap-perde` / `.ap-pencereler` (AnalizPanelHost.razor.css:1-20) BİLEREK
      kromu örtmez; kendi yorumu bunu yazıyor: üstbarı örtmek gezinmeyi de
      kapatıyordu. z-index'lerine DOKUNULMADI — (B) kalkınca 60/61 ile
      üstbarın üstünde ama sekme çubuğunun (65) altında kalırlar; çubuğun
      görünür kalması yazarın niyetiyle birebir aynı. Dip boşluğu zaten
      16. bantta verildi.
   3. `.blob` fonu (`MainLayout.razor:14-16`) `position: fixed; z-index: 0`
      ve `<main>`den ÖNCE geliyor. `.wrap` z-index'i `auto` olunca ikisi de
      "konumlanmış, z-auto/0" boyama adımında kalır ve AĞAÇ SIRASI karar
      verir: `<main>` sonra geldiği için içerik fonun ÜSTÜNDE kalır. Ölçüldü,
      fon içeriği örtmüyor.
   4. Hesap menüsünün kapatma perdesi (`.scrim`) sekme çubuğunun üstündedir.
      Böylece açık sheet varken sekme navigasyonu tıklanamaz; route değişimi de
      savunma amaçlı olarak MainLayout içindeki tüm açık menüleri kapatır.

   YERLEŞİM — aile içi sıra korunur, tavana uyulur
   -----------------------------------------------
   Tavan (bu dosyada belgeli): sekme çubuğu 65 · hesap menüsü 70 ·
   uygulama "Diğer" tabakası 78/79 · modal bandı 80-92 · bildirim 1000.
     65  sekme çubuğu
     66  hesap menüsü perdesi
     67  `.topbar` (içindeki üç açılır + iki perde onunla birlikte yükselir)
     68/69  sohbet çekmecesi perdesi / çekmece
     70/71  seviye eşiği perdesi / paneli
     72/73  çoklu seçim perdesi / paneli
     82/83  büyütülmüş grafik perdesi / kutusu
     84/85  paket kill-switch perdesi / modalı
     86/87  sınav itirazı perdesi / diyaloğu
     88/89  step-up perdesi / modalı — kill-switch'in ÜSTÜNDE, çünkü
            `PaketDetay.razor:188` bu akışı parola yeniden doğrulamasıyla
            kapatıyor: step-up, kill-switch modalının üstünde açılır.

   ÖZGÜLLÜK: `body.edulive-cihaz .X` = (0,2,1); kaynaktaki `.X` (0,1,0) ve
   kapsamlı CSS'in `.X[b-xxxx]` (0,2,0) biçimlerinin ikisini de yener.
   `!important` KULLANILMADI (K10 sayacı 0 kalır).

   GERİ ALMA: bu bandın tamamı silinirse davranış Tur 27I sonuna döner.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- (1) KÖK NEDEN: sayfa gövdesinin yığın bağlamı kaldırılır ---------- */
  body.edulive-cihaz main.wrap,
  body.edulive-cihaz main.student-wrap {
    z-index: auto;
  }

  /* --- (2) Üstbar kapsayıcısı: içindeki üç açılır onunla birlikte çıkar -- */
  body.edulive-cihaz .scrim {
    z-index: 66;
  }
  body.edulive-cihaz .topbar {
    z-index: 67;
  }

  /* --- (3) Analiz asistanı sohbet çekmecesi (kullanıcı önceliği) --------- */
  body.edulive-cihaz .aa-kabuk--cekmece .aa-perde {
    z-index: 68;
  }
  body.edulive-cihaz .aa-yan {
    z-index: 69;
  }

  /* --- (4) Seviye eşiği açılırı: perde SABİT, panel MUTLAK, birlikte ----- */
  body.edulive-cihaz .ase__perde {
    z-index: 70;
  }
  body.edulive-cihaz .ase__panel {
    z-index: 71;
  }

  /* --- (5) Çoklu seçim açılırı ------------------------------------------ */
  body.edulive-cihaz .app-ms__scrim {
    z-index: 72;
  }
  body.edulive-cihaz .app-ms__panel {
    z-index: 73;
  }

  /* --- (6) Büyütülmüş grafik: kromu ÖRTMEK için yazılmış ışık kutusu ----- */
  body.edulive-cihaz .ag-perde {
    z-index: 82;
  }
  body.edulive-cihaz .ag-kap--buyuk {
    z-index: 83;
  }

  /* --- (7) Paket kill-switch: geri alınamaz, aşılamamalı ---------------- */
  body.edulive-cihaz .pk-scrim {
    z-index: 84;
  }
  body.edulive-cihaz .pk-modal {
    z-index: 85;
  }

  /* --- (8) Sınav itirazı diyaloğu (öğrenci düzeni) ----------------------- */
  body.edulive-cihaz .ss-perde {
    z-index: 86;
  }
  body.edulive-cihaz .ss-dialog {
    z-index: 87;
  }

  /* --- (9) Step-up: kill-switch'in de üstünde -------------------------- */
  body.edulive-cihaz .sum-scrim {
    z-index: 88;
  }
  body.edulive-cihaz .sum-modal {
    z-index: 89;
  }
}


/* ===========================================================================
   18 · ORTALANMIŞ MODALLAR YATAYDA EKRANDAN TAŞIYOR (onay düğmesi erişilemez)
   YALNIZ CİHAZ BANDI — K9 · K10 · K21

   SORUN
   -----
   Beş modal aynı desenle yazılmış: `position: fixed; top: 50%; left: 50%;
   transform: translate(-50%, -50%)` — genişlik `min(…, calc(100vw - 32px))`
   ile sınırlı ama YÜKSEKLİK SINIRSIZ ve taşma davranışı tanımsız.

   Ortalanmış bir kutunun içeriği görünür alandan uzunsa, kutu yukarı VE
   aşağı taşar; kendisi kaydırılamadığı için alt kenarındaki eylem şeridi
   ekranın dışında kalır ve BELGE de kaydırılamaz (kutu `fixed`). Yani
   kullanıcı "Onayla"ya ulaşamaz; modal `aria-modal` olduğundan kaçış da
   yalnız perdeye dokunmaktır. Telefon YATAYDA en dar durum: 390x844 bir
   cihaz yatayken görünür yükseklik ~390 px, ölçülen içerikler ise:

     .qrd-modal   ~400 px  (başlık + alt metin + 220x220 tuval + kod satırı
                            + eylemler + 44 px iç boşluk)      QrCodeDialog.razor
     .pk-modal    ~416 px  (kill-switch: başlık + uyarı + ad yazma alanı +
                            eylemler)                          PaketDetay.razor:184
     .cd-modal    değişken (mesaj uzunluğuna bağlı)             ConfirmDialog.razor
     .etl-guard   değişken (`au-card` gövdesi + eylemler)       EtlManagementPage.razor:207
     .sum-modal   değişken (parola + hata bandı + eylemler)     StepUpModal.razor

   Beşinde de `max-height` YOK, `overflow` YOK. Kaynak salt-okunur (K-1).

   ÇÖZÜM
   -----
   Kutuya görünür alanı aşmayan bir tavan ver ve taşmayı kutunun İÇİNE al.
   Tavan: dinamik görünüm yüksekliği eksi güvenli alan eksi 24 px nefes payı.
   `100dvh` desteklenmeyen bir motorda ikinci bildirim yok sayılır, birinci
   satırdaki `100vh` yürürlükte kalır (aşamalı geliştirme).

   ÖLÇÜLEN TUZAKLAR
   ----------------
   1. Üçü (`.etl-guard`, `.pk-modal`, `.sum-modal`) `display: flex;
      flex-direction: column`. Kaydırılabilir bir sütun esnek kapsayıcıda
      çocukların `flex-shrink: 1` ile EZİLMESİ beklenir — ama `min-height`
      varsayılanı `auto` olduğu için otomatik en küçük boyut devreye girer
      ve metin/tuval kendi yüksekliğinin altına inemez; sonuç ezilme değil,
      TAŞMA olur ve kaydırıcı çalışır. Bu yüzden çocuklara `flex-shrink: 0`
      YAZILMADI (gereksiz kural üretmemek için; davranış ölçüldü).
   2. `overscroll-behavior: contain` eklendi: modal sonuna gelindiğinde
      kaydırmanın ARKADAKİ sayfaya zincirlenmesini keser. Perde `fixed`
      olduğu için arka plan zaten görünmez, ama zincirleme iOS'ta gövdeyi
      oynatıp modalı kaydırılmış gibi gösteriyordu.
   3. Kutular `translate(-50%, -50%)` ile ortalanıyor; `max-height`
      dönüşümden ÖNCE düzen aşamasında uygulandığı için ortalama bozulmaz —
      kutu kısalır, merkezi aynı kalır.
   4. `env(safe-area-inset-*)` yatayda çentik/ana ekran çubuğu payını
      düşürür; desteklenmeyen yerde `0px` yedeği devreye girer.

   ELENENLER (zaten korumalı — kural yazılmadı)
   --------------------------------------------
   `.ts-modal`  `max-height: calc(100vh - 64px)` + `overflow` VAR
                (TenantSwitchModal.razor.css:17)
   `.ss-dialog` `max-height: calc(100vh - 2rem); overflow-y: auto` VAR
                (SinavSonuclarim.razor.css:86)
   Bbt ekranları: `EmptyLayout`, öteki ajanın alanı — dokunulmadı.

   ÖZGÜLLÜK: `body.edulive-cihaz .X` = (0,2,1) > kapsamlı `.X[b-xxxx]`
   (0,2,0). `!important` KULLANILMADI.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .qrd-modal,
  body.edulive-cihaz .cd-modal,
  body.edulive-cihaz .etl-guard,
  body.edulive-cihaz .pk-modal,
  body.edulive-cihaz .sum-modal {
    max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 24px);
    max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* =========================================================================
   BANT 19 — YAZILIM KLAVYESİ ÖRTÜSÜ                             (Tur 31)
   =========================================================================
   KUSUR (ölçüldü, iPhone 17 · iOS 26.3 simülatörü, giriş ekranı):
   klavye açılınca «Giriş yap» düğmesi klavyenin arkasında kalıyor ve
   SAYFA KAYDIRILARAK DA ULAŞILAMIYOR. Ölçüm:
       kapalı  iH=874 vvH=874   ·  klavye açık  iH=848 vvH=471
       sH=936  sY=88 = AZAMİ (936-848)  ->  son 377 px erişilemez
   Sebep: WKWebView klavyede *layout* viewport'u küçültmez, yalnız görsel
   viewport iner; kaydırma sınırı layout viewport'a bakar. Bu yüzden
   `100dvh` de `env(safe-area-inset-bottom)` da bu örtüyü GÖREMEZ —
   1344. satırdaki F-listesi maddesi ("bunu CSS göremez") tam olarak bunu
   söylüyordu. Örtü artık js/klavye-ortu.js tarafından ÖLÇÜLÜP
   `--klavye-ortu` değişkenine yazılıyor; buradaki kurallar onu tüketir.

   NEDEN BANTSIZ (K10)
   -------------------
   Yazılım klavyesi ekran genişliğine bağlı değildir: 640 px telefonda da,
   1024 px iPad'de de, dokunmatik Windows'ta da açılır. Değişken klavye
   kapalıyken 0'dır ve Android'de konak katmanı (MainActivity, Tur 30)
   WebView'ı fiilen küçülttüğü için hep 0 kalır -> kural orada ölü ve
   zararsızdır. Masaüstünde de değişken hiç dolmaz.

   NEDEN body'YE DOLGU
   -------------------
   Ölçümde kök kaydırıcı belgenin kendisi (`documentElement.scrollHeight`
   936, `window.scrollY` 88). Belgeye klavye kadar dolgu eklemek kaydırma
   payını doğurur; kullanıcı düğmeye ulaşır. İçeriğe DOKUNULMAZ, düzen
   yeniden akmaz — yalnız altta boşluk açılır. Klavye kapanınca değişken
   0'a döner ve sayfa birebir eski haline gelir (Tur 31'de gözlendi:
   klavye kapanışında düzen tam geri dönüyor).

   `:has()` İSTİSNASI
   ------------------
   `.aa-kabuk` (analiz asistanı) `100dvh` ile ekranı doldurur ve kendi
   içinde kayar; ona AYRICA kabuk yüksekliğinden düşüş uygulanıyor. Aynı
   sayfada body dolgusu da olsaydı örtü İKİ KEZ sayılır, altta 377 px
   ölü boşluk kalırdı. `:has()` WKWebView (iOS 15.4+) ve Android WebView
   (Chrome 105+) tarafından destekleniyor; desteklenmeyen yerde kural
   düşer ve yalnız çift boşluk görülür — sessiz erişilemezlik değil.
   ========================================================================= */

body.edulive-cihaz {
  padding-bottom: var(--klavye-ortu, 0px);
}

body.edulive-cihaz:has(.aa-kabuk) {
  padding-bottom: 0;
}

/* Analiz asistanı: kabuk klavye kadar kısalır, besteci klavyenin ÜSTÜNE
   çıkar. 1368. banttaki telefon kuralının aynısıdır, tek farkı klavye
   payıdır; bantsızdır çünkü klavye iPad'de de örter. `min-height: 0`
   telefon bandındaki gerekçeyle aynı sebeple gerekli. */
body.edulive-cihaz.klavye-acik .aa-kabuk {
  height: calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 28px - var(--klavye-ortu, 0px));
  min-height: 0;
}


/* ===========================================================================
   20 · YAPIŞKAN ÜST KENAR ÇAKIŞMASI + GÖRÜNTÜ-YÜKSEKLİĞİ İÇ KAYDIRICILAR
   CİHAZ BANDI (telefon + dokunmatik tablet)  —  kabul kriteri K9 · K10 · K21

   Tur 27I `position: fixed|sticky` taşıyan 54 bloğu ALT kenar ekseninde
   (sekme çubuğuyla çakışma) taramıştı; `sticky top:*` olanları "üst kenar;
   çubuk alt kenarda" diyerek elemişti. Bu tur o elemenin ikinci eksenini
   ölçüyor: ÜST kenarda da bir krom var — üstbar (`.topbar`, 17. bantta
   z 66, yüksekliği `--topbar-h`; telefonda 52 px, tablette 70 px).

   TARAMA (tüm `*.razor.css`, obj/bin hariç, blok düzeyi): `position: sticky`
   taşıyan 10 blok. Tek tek ölçüldü:

   ELENDİ — yazar zaten kapatmış
   ·  `.kv-onizleme` (KartvizitList:7-13, `top: 88px`) — aynı dosyanın
      :46-50 satırında `@media (max-width:900px){ position: static }`.
      Cihaz bandının tamamı 900 px'in altında ya da dokunmatik tablet;
      1024-1279 dokunmatik aralıkta kural yazmak yazarın kararını EZERDİ.

   ELENDİ — ızgara tek sütuna inince yapışkanlık FİİLEN ÖLÜ
   ·  `.ks__panel`  (KazanimSecici:293-295, `top: 12px`)
   ·  `.vg-side`    (VideoScriptGraph:23-28, `top: 12px`)
      İkisi de ızgaranın DOĞRUDAN öğesi (`KazanimSecici.razor:159`
      `<aside class="ks__panel">`, `VideoScriptGraph.razor:101`
      `<aside class="vg-side">`). Yapışkan öge KAPSAYICI BLOĞU içinde
      kayar; ızgara öğesinin kapsayıcı bloğu kendi ızgara ALANIDIR.
      `.ks` 720 px altında, `.vg-layout` 900 px altında `1fr`e iniyor —
      tek sütunda her öğe kendi satırında, satır yüksekliği = öğe
      yüksekliği, yani kayma payı SIFIR. Kural yazmak ölü kod olurdu.

   ELENDİ — kaydırma atası yüksekliği sınırlı ya da hiç kaydırmıyor
   ·  `.at-kap--sanal thead th` / `.at-tablo th` / `.pg-list th` (`top: 0`)
      — üçü de `overflow` taşıyan bir kaba gömülü; yapışkanlık görünüm
      alanına değil O KABA göre çalışır, üstbarla ilişkisi yok.
   ·  `.student-topbar` (`top: 0`) — öğrenci düzeninin KENDİ üstbarı;
      o düzende `.imp-banner` yok (bileşen yalnız `MainLayout.razor:12`).
   ·  `.aa-dibe` — 13. bant `.aa-kabuk` yüksekliğini zaten çubuğa göre
      kesiyor (satır 1379); `.bkw-dibe` BBT, kabuksuz rota.

   KUSUR 1 — kimliğe bürünme şeridi üstbarı YUTUYOR
   `MainLayout.razor:12` `<ImpersonationBanner />` üstbardan (satır 18)
   ÖNCE geliyor ve `position: sticky; top: 0; z-index: 80`
   (ImpersonationBanner.razor.css:1-4). Üstbar da `sticky; top: 0`.
   İkisi AYNI kapsayıcı blokta ve AYNI eşiğe demirli: sayfa kaydırılınca
   ikisi de 0'a çakılır, üst üste biner. z 80 > 66 olduğu için kazanan
   şerit olur; 52 px'lik üstbarın büyük kısmı — kurum değiştirici,
   bildirim zili, hesap menüsü — şeridin ARKASINDA kalır ve tıklanamaz.
   Cihazda gezinme alt çubukta olduğu için ekran kilitlenmez ama hesap
   menüsü (çıkış, tema) erişilemez hâle gelir.

   KARAR: cihazda üstbar üst yuvayı KAZANIR (`z-index: 64` < 66).
   Şerit akıştaki yerini korur — sayfa başındayken tam görünür ve "Çık"
   düğmesi tıklanabilir; kaydırılınca üstbarın arkasına geçer.
   ELENEN ALTERNATİFLER: (a) `position: static` — aynı görsel sonucu
   verir ama akışı da değiştirir, gereksiz risk. (b) üstbarı şerit
   yüksekliği kadar aşağı itmek — şeridin yüksekliği İÇERİĞE bağlı
   (hedef kullanıcının adı) ve bunu ifade eden bir belirteç yok;
   `:has()` ile koşullamak eski Android WebView'da güvenli değil.

   KUSUR 2 — `vh` tabanlı iç kaydırıcılar yatayda kromu aşıyor
   Sayfaya gömülü üç kaydırma kabı yüksekliğini görüntü yüksekliğinin
   yüzdesi olarak alıyor: `.at-kap--sanal` 70vh (AnalizTablo:12-16),
   `.ge` 62vh (GraphEditor:3-10), `.cs-thread` 52vh (AjanSohbet:6-14).
   `vh` KROMU BİLMEZ. Ölçüm (360x780 dik): krom dışı bant
   780-52-56-34-24 = 614 px; 70vh = 546 → sığıyor, sorun yok.
   Yan çevrildiğinde (780x360): bant 360-70-56-0-24 = 210 px;
   70vh = 252 → kabın dibi sekme çubuğunun ALTINA taşıyor, son satır ve
   yatay kaydırma çubuğu çubuğun arkasında kalıyor.
   KURAL `min()` ile yazıldı: kaynağın değeri TAVAN olarak korunur,
   yalnız krom dışı bant daha darsa devreye girer — dik ekranda tek bir
   piksel değişmez, yalnız yatayda kısar. `100vh` satırı `100dvh`
   desteklemeyen WebView için önce yazıldı (aynı desen 18. bantta).

   GERİ ALMA: bu bandın tamamı silinebilir; hiçbir kural başka bir bandın
   önkoşulu değil.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- (1) Üst yuva üstbarındır ----------------------------------------- */
  body.edulive-cihaz .imp-banner { z-index: 64; }

  /* --- (2) `vh` kaydırıcıları krom dışı banda kısılır ------------------- */
  body.edulive-cihaz .at-kap--sanal {
    max-height: min(70vh, calc(100vh  - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
    max-height: min(70vh, calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
  }

  /* `.ge` ve `.cs-thread` 240 px `min-height` taşıyor (GraphEditor:9,
     AjanSohbet:11). En küçük yükseklik en büyüğü EZER: yatay bant 210 px'e
     inince 240 px yine taşardı, kural ölü kod olurdu. Cihazda taban
     kaldırılıyor — tavanı kaynak zaten kendi `vh` değeriyle veriyor. */
  body.edulive-cihaz .ge {
    min-height: 0;
    max-height: min(62vh, calc(100vh  - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
    max-height: min(62vh, calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
  }

  body.edulive-cihaz .cs-thread {
    min-height: 0;
    max-height: min(52vh, calc(100vh  - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
    max-height: min(52vh, calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px));
  }
}


/* ===========================================================================
   21 · ANALİZ ASİSTANI (SOHBET) — ONARIM TABLET BANDINA TAŞINIYOR
   641-1023 px  +  1024-1279 px YALNIZ dokunmatik   —  K3 · K4 · K9 · K10

   KUSUR (statik çözümleme; emülatörsüz tur, kullanıcı kararı).
   12/13. bant sohbeti TELEFONDA onardı ama kuralların TAMAMI
   `@media (max-width: 640px)` içindedir (satır 1376). Alt gezinme çubuğu
   ise 4. bantta (satır 375) CİHAZ BANDININ TAMAMINDA çiziliyor:
   `.cihaz-sekme` yüksekliği `--sekme-h` 56 px + `--sekme-alt` güvenli alan.
   Yani 641-1023 px'te çubuk VAR, telafisi YOK. Sonuç, kaynaktan satır satır:

   1) BESTECİ ÇUBUĞUN ARKASINDA — kullanıcı yazamıyor/gönderemiyor.
      641-900 px : AnalizAsistan.razor.css:498
                   `.aa-kabuk { height: calc(100vh - var(--topbar-h) - 28px) }`
      901-1279 px: aynı dosya :11  `... - 44px`
      İkisi de GÖRÜNÜM yüksekliğidir; çubuğun 56 px'i düşülmez.
      Kabuğun son öğeleri `.aa-alt` (besteci: `.aa-girdi` + `.aa-gonder`,
      :404) ve `.aa-dipnot` (:449) olduğu için çubuğun altında kalan tam
      olarak GİRİŞ ALANIDIR. Telefonda ölçülmüştü: 47 px örtüşme,
      `.aa-dipnot` %100 görünmez (12. bant, madde 1).
   2) `min-height: 520px` (:12) telefon bandı DIŞINDA hiç sıfırlanmıyor.
      Manzara duruşunda (ör. 780x360 telefon, 1024x768 tablet penceresi)
      krom dışı bant 520 px'in altına iner; taban yüksekliği yukarıdaki
      `calc()`i EZER ve kural ölü kod olur. 19. bantta aynı tuzağa
      `.ge`/`.cs-thread` için düşülmüştü — `min-height` `max-height`i de
      `height`i de yener, önce taban kaldırılır.
   3) K4 — `.aa-girdi` 15 px (:422), `.aa-arama input` 13 px (:51).
      16 px altındaki alan iOS'ta odakta sayfayı yakınlaştırır. K3 —
      `.aa-girdi` `min-height: 24px` (:420), tek satırlık dokunma hedefi.
      Punto/yükseklik ekran genişliğine bağlı değildir; tablette de kusurdur.
   4) İÇ İÇE KAYDIRICI — `.aa-dusunce__govde { max-height: 220px;
      overflow: auto }` (:224) zaten kayan `.aa-akis` içinde ikinci bir
      kaydırma tuzağı. Dokunmatikte hangi kabın kaydığı belirsiz.

   YAZILMADI — ÖLÇÜLDÜ, KUSUR ÇIKMADI ya da KANIT YOK
   ---------------------------------------------------
   • GRAFİK yatay kaçışı (`.aa-kart--grafik{overflow-x:auto}` +
     `.aa-grafik{min-width:560px}`) tabletTE ÖLÜ KOD olurdu: 641 px'lik en
     dar tablette bile akış içi genişlik ~590 px, 901-1023'te kenar çubuğu
     (280 px + 14 gap) düşülünce ~700 px — ikisi de 560 px tabanın üstünde,
     kaydırıcı hiç doğmaz. Telefondaki 265 px'lik daralma tablette yok.
   • ÇEKMECE `.aa-yan` (641-900 px'te `position: fixed`, :500-505):
     13. bandın `bottom: 12px` payı CİHAZDA ÖLÇÜLMÜŞ bir 4 px kutu taşmasını
     kapatıyordu ve sabit kapsayıcının `.aa-kabuk` kutusunu izlediği
     ölçümle saptanmıştı (12. bant madde 2). Kapsayıcı kabuğu izlediğine
     göre (1) numaralı yükseklik düzeltmesi çekmeceyi KENDİLİĞİNDEN
     yukarı çeker; tablette yeniden ölçüm yapılmadan `bottom` yazmak
     körlemesine olurdu ve tutarsa 56 px liste boşa giderdi. Emülatör
     turu açıldığında ölçülecek — 6. bölüm A listesine düşüldü.
   • Krom kısıntıları (`.aa-ust__alt` gizleme, dolgu daraltmaları) telefona
     özgüdür: tablette dikey bütçe geniş (1194x834 manzarada kabuk 664 px),
     bilgi gizlemek için sebep yok.

   NEDEN ÜÇ BLOK
   -------------
   Kaynak 900 px'te kendi sabitini değiştiriyor (28 -> 44 px; o sabit
   `.wrap` dolgu farkını taşır). Tek bir `calc()` yazmak 901-1023'te
   kabuğu 16 px uzatır, yani kaynağın kararını ezerdi. Bu yüzden yalnız
   ÇUBUK payı ekleniyor, sabit kaynağın verdiği gibi bırakılıyor.
   `100vh` satırı `100dvh` desteklemeyen eski WebView için önce yazıldı
   (aynı desen 18. ve 19. bantta).

   ÇAKIŞMA YOK: 13. bandın klavye kuralı
   `body.edulive-cihaz.klavye-acik .aa-kabuk` (satır 2656) (0,3,1)
   özgüllüğündedir, buradaki (0,2,1)'i klavye açıkken yener — sıraya
   rağmen davranış değişmez.

   GERİ ALMA: bandın tamamı silinebilir; hiçbir kural başka bandın
   önkoşulu değil.
   ========================================================================= */

@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* (2) Taban önce kalkar — yoksa aşağıdaki iki `height` kuralı da ölü kod. */
  body.edulive-cihaz .aa-kabuk {
    min-height: 0;
  }

  /* (4) Düşünce bloğu iç kaydırıcısı kaldırılır: `<details>` kapalı gelir,
     açan kullanıcı tamamını görmek ister; taşan metni sayfanın kendi
     dikey kaydırıcısı (`.aa-akis`) taşır. */
  body.edulive-cihaz .aa-dusunce__govde {
    max-height: none;
    overflow: visible;
  }

  /* (3) K4 tabanı + K3 yüksekliği — telefon bandındaki kuralın aynısı. */
  body.edulive-cihaz .aa-girdi {
    font-size: 16px;
    min-height: 44px;
  }

  /* `.aa-arama` bir `<label>`; dikey dolgusu sıfırlanmazsa alan 44 px'e
     çıkınca kutu 58 px'e şişer. Yatay dolgu (ikon-metin boşluğu) kalır.
     `flex: none` — `.aa-yan__bas` esnek sütun, taban ezilmesin. */
  body.edulive-cihaz .aa-arama {
    padding-top: 0;
    padding-bottom: 0;
    flex: none;
  }

  body.edulive-cihaz .aa-arama input {
    font-size: 16px;
    min-height: 44px;
  }
}


/* (1a) 641-900 px — kaynağın sabiti 28 px (AnalizAsistan.razor.css:498).
   Örnek 780x360 manzara telefon: eski 360-70-28 = 262 (alt kenar çubuğun
   56 px'ine giriyor) -> yeni 360-70-56-0-28 = 206, besteci çubuğun üstünde. */
@media (min-width: 641px) and (max-width: 900px) {

  body.edulive-cihaz .aa-kabuk {
    height: calc(100vh  - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 28px);
    height: calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 28px);
  }
}


/* (1b) 901-1023 px + 1024-1279 dokunmatik — kaynağın sabiti 44 px
   (AnalizAsistan.razor.css:11). Örnek iPad 1194x834 manzara:
   eski 834-70-44 = 720 (çubuğa 56 px giriyor) -> yeni 664. */
@media (min-width: 901px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .aa-kabuk {
    height: calc(100vh  - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 44px);
    height: calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 44px);
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   BANT 22 · YÖNETİM MODÜLÜ — DOKUNMA HEDEFİ VE OKUNABİLİRLİK (Tur 33)
   TASARIM-MOBIL §13.8 adım 4 (Y1/Y2 ölçütleri) ile RENDER EDİLMİŞ ekranda
   ölçüldü; 28 yönetim rotasının tamamı tarandı, aşağıdaki üç kalıp gerçek
   kusur çıktı (kalan bulgular gerekçeli eleme ya da frontend-3 işi).
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- 14.1 · TABLO HÜCRESİNDEKİ ÇIPLAK BAĞLANTI (Y1) ------------------------
   ÖLÇÜM: /yonetim/abonelik-planlari  `td > a` 66x16  ·  /yonetim/kurumlar
   `td > a` 48..76 x 35. Bu bağlantı satırın BİRİNCİL eylemidir (kayda gider)
   ama satır içi kutu olduğu için dokunma alanı yalnız yazının kendisidir;
   hücre 42 px yüksek olsa da boşluğa dokunmak bir şey yapmaz.
   KARAR: 26 px taban — WCAG 2.5.8 (AA) 24 px eşiğinin üstünde, `td`nin
   8+8 px dolgusuyla toplam 42 px'lik satıra TAM oturur, yani hiçbir tabloyu
   yükseltmez. Halihazırda 26 px'i geçen (iki satıra sarmış) bağlantılara
   `min-height` dokunmaz. Sınıflı bağlantılar (`.au-btn` vb.) kendi
   bantlarına sahip olduğu için `:not([class])` ile kapsam dışı bırakıldı. */
body.edulive-cihaz td > a:not([class]) {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
}

/* 14.1b · Hücreyi dokunma hedefine çevirme.
   ÖLÇÜM: bu bağlantıların bulunduğu `td`ler TEK çocukludur ve içlerinde
   başka tıklanabilir öğe YOKTUR (/yonetim/abonelik-planlari td 78x43 ·
   /yonetim/kurumlar td 88x161, ikisinde de tdCocuk=1, tdTiklanabilir=1).
   Bu yüzden hücrenin tamamını bağlantıya vermek hiçbir eylemi örtmez.
   KAZANÇ: gerçek dokunma alanı 66x26 yerine 78x43 olur — 44 px hedefe
   satır yüksekliğini hiç artırmadan ulaşılır (yazının kendisini büyütmek
   satırı 60 px'e çıkarıp 20 satırlık tabloyu okunmaz yoğunlukta uzatırdı).
   Kapsam `:has()` ile yalnız o hücrelere daraltıldı. */
body.edulive-cihaz td:has(> a:not([class])) {
  position: relative;
}
body.edulive-cihaz td > a:not([class])::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* --- 14.2 · ETİKETSİZ SATIR SEÇİM KUTUSU (Y1) ------------------------------
   ÖLÇÜM: /yonetim/kullanicilar `input.au-check` 16x16, 20 satırda 20 örnek.
   KÖK NEDEN (admin-users.css:131): `width/height: 16px` sabit.
   §13.14'ün etiket kuralı burada KURTARMAZ — bu kutular `<td>` içinde
   çıplaktır (`aria-label` var, saran `<label>` yok), yani gerçek dokunma
   hedefi 16 px'in kendisidir.
   KARAR: 24 px (WCAG 2.5.8 AA tabanı). Satır 42 px, hücre dolgusu 8+8 ->
   26 px'lik iç alan; 24 px sığar, satır yüksekliği değişmez. */
body.edulive-cihaz .au-check {
  width: 24px;
  height: 24px;
}

/* --- 14.3 · 12 px ALTI YARDIMCI METİN (Y2) ---------------------------------
   ÖLÇÜM: /yonetim/kullanicilar `.au-org small` 11.05 px (20 örnek — "· 5/A"
   sınıf bilgisi) · /yonetim/kartvizitler `.au-dim` 11.48 px (8 örnek — unvan).
   KÖK NEDEN: `.au-org` 13 px + `<small>`ın tarayıcı varsayılanı (0.85em) ->
   11.05; `.au-dim` de göreli küçültme zincirinde 11.48'e iniyor.
   KARAR: `max(12px, 0.9em)` — 12 px'in ALTINA inmeyi engeller, üstünü
   olduğu gibi bırakır (mutlak değer dayatmaz, ölçek ayarına saygılıdır).
   Kapsam ölçülen iki kalıpla sınırlı; genel `small` kuralı yazılmadı —
   ölçülmemiş yerde davranış değiştirmek §13.10'un yasakladığı iştir. */
body.edulive-cihaz .au-org small {
  font-size: max(12px, 0.9em);
}

/* 14.3b · `.au-dim` ancak `!important` ile düzelir — GEREKÇE (K10 borcu +1).
   ÖLÇÜM: /yonetim/kartvizitler'de öğe şöyle geliyor:
   `<span class="au-dim" style="display:block;font-size:.85em">`.
   Boyut SATIR İÇİ stildedir; satır içi stili yenmenin CSS'te tek yolu
   `!important`tır (özgüllük artırmak yetmez — 14.3'ün ilk hâli sınıf
   seçicisiyle yazılmıştı ve cihazda ölçüldüğünde 11.475 px'te kalmıştı).
   Kalıcı çözüm frontend-3'te satır içi stilin kaldırılmasıdır; orası
   salt-okunur olduğu için ILERLEME §6.B'ye borç olarak yazıldı. */
body.edulive-cihaz .au-dim {
  font-size: max(12px, 0.9em) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 23 · MEDYA STÜDYOSU — DOKUNMA HEDEFİ VE OKUNABİLİRLİK (Tur 33)
   TASARIM-MOBIL §13.8 adım 4 (Y1/Y2/Y3) ile render edilmiş ekranda ölçüldü;
   medya-studyo'nun 23 rotasının TAMAMI tarandı. Üç kalıp çıktı; üçü de tek
   tek kaynağına kadar izlendi (frontend-3 scoped CSS bundle'ından okundu).
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- 15.1 · MEDYA ÖNİZLEME ALTYAZISINDAKİ BAĞLANTI (Y1) --------------------
   ÖLÇÜM: `figcaption.me-caption > a` 105x16 — /medya-studyo altında 211 örnek
   (sesler 60 · videolar/onaylar 50 · gorseller 57 · videolar 23 · karakterler
   14 · montaj 4 · mekanlar 2 · stiller 1). Bağlantı metni "Yeni sekmede aç".
   KÖK NEDEN: ortak `MedyaOnizleme` bileşeni (scoped b-o7p60hapie) — kural
   yalnız `.me-caption{font-size:.82rem}` + `.me-caption a{underline}`; `a`
   satır içi (inline) olduğu için kutusu metnin kendisi kadar, 16 px.
   BAĞLAM ÖLÇÜMÜ: figcaption 323x20, TEK çocuklu, içinde başka tıklanabilir
   YOK, padding 0 -> hücrenin tamamını bağlantıya vermek hiçbir eylemi örtmez
   (BANT 14.1b ile aynı kalıp, aynı gerekçe).
   KARAR: 26 px taban — WCAG 2.5.8 (AA) 24 px eşiğinin üstünde; kart başına
   yalnız +6 px maliyet getirir (metni büyütmek 211 kartı birden uzatırdı).
   Gerçek hedef 105x16 yerine 323x26 olur. */
body.edulive-cihaz figcaption.me-caption {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 26px;
}
body.edulive-cihaz figcaption.me-caption > a::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* --- 15.2 · 12 px ALTI ROZET VE SAYAÇ METNİ (Y2) ---------------------------
   ÖLÇÜM: 11.5-11.8 px, toplam 260+ örnek — `gl-type`(60) `vo-type`(50)
   `vo-cost`(50) `vo-kind`(50) `vl-type`(24) `ml-type`(24) `kl-type`(19)
   `sm-chip`(2) `mz-type`(2) `mj-type`(1) ve `app-richtext__count`(3 rotada).
   KÖK NEDEN: `font-size: .72rem` / `.74rem` rozet deseni (10 ayrı scoped
   dosyada aynı değer) + `app-richtext__count` sabit `11.5px`.
   KARAR: `max(12px, 0.75rem)` — 0.75rem varsayılan kökte tam 12 px'tir,
   yani görünüm bugünkünden yalnız 0.5 px büyür (yerleşim kaymaz), buna
   karşılık kullanıcı yazı tipi ölçeğini büyüttüğünde rozet de birlikte
   büyür (K3 · yazı tipi ölçeği kabul kriteri). `em` DEĞİL `rem` seçildi:
   bu rozetler zaten rem tabanlı, `em` kullanmak ebeveyn 15 px olan yerlerde
   metni 13.5 px'e çıkarıp ölçmediğim bir yerleşim değişikliği doğururdu.
   Özgüllük notu: scoped kurallar `.gl-type[b-hash]` = (0,2,0); eşitlikte
   yükleme sırası karar verir, bu yüzden hepsi öğe adıyla (0,2,1) yazıldı. */
body.edulive-cihaz span.gl-type,
body.edulive-cihaz span.kl-type,
body.edulive-cihaz span.ml-type,
body.edulive-cihaz span.mz-type,
body.edulive-cihaz span.mj-type,
body.edulive-cihaz span.vl-type,
body.edulive-cihaz span.vo-type,
body.edulive-cihaz span.vo-cost,
body.edulive-cihaz span.vo-kind,
body.edulive-cihaz span.sm-chip,
body.edulive-cihaz div.app-richtext__count {
  font-size: max(12px, 0.75rem);
}

/* --- 15.3 · MONTAJ SEÇİCİDE KESİK ALT BAŞLIK (Y3) --------------------------
   ÖLÇÜM: /medya-studyo/montaj/olustur `.mo-pick__konu` scrollWidth 172 >
   clientWidth 102 (4 örnek) — kap zinciri ul.mo-pick 257 -> button
   .mo-pick__row 257 (gap 12) -> span.mo-pick__main 145 px.
   EK ÖLÇÜM: `.mo-pick__title` AYNI metni taşıyor ve o SARIYOR (whiteSpace
   normal, scrollWidth == clientWidth) -> kesilen bilgi bir satır yukarıda
   zaten tam görünüyor. Yani bu bir veri tekrarı (frontend-3 kaynaklı),
   kusurun kendisi değil.
   KARAR: `__konu`yu GİZLEMEK yerine SARMASINA izin verildi. Gizleme, her
   kayıtta title == konu olduğunu varsaymayı gerektirir — ölçtüğüm üç örnekte
   öyleydi ama tümünde doğrulanmadı; sarma en kötü ihtimalle bir satır yer
   alır, bilgi kaybı ihtimalini sıfırlar (gece vardiyası: geri alınabilir
   olanı seç). Kalıcı çözüm frontend-3'te tekrarın kaldırılmasıdır -> §6.B. */
body.edulive-cihaz .mo-pick__konu {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 24 · SOSYAL MEDYA + İÇERİK STÜDYOSU — ROZET OKUNABİLİRLİĞİ (Tur 33)
   §13.8 adım 4 (Y1/Y2/Y3) ile render edilmiş ekranda ölçüldü; sosyal-medya'nın
   21 rotası ve content-studio'nun 19 rotasının TAMAMI tarandı. Y1 ve Y3 SIFIR
   çıktı; iki modülde toplam ÜÇ Y2 bulgusu var ve üçü de BANT 15.2'nin kalıbının
   aynısı: frontend-3'te tekrar eden `font-size: 0.7-0.72rem` rozet deseni.
   Aynı çözüm uygulanır — gerekçesi 15.2'de yazılıdır (rem seçimi, özgüllük).
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- 16.1 · ONAY KUYRUĞU ROZETİ VE OLGU ETİKETİ (Y2) -----------------------
   ÖLÇÜM: /sosyal-medya/onay — `span.oy-badge.oy-badge--muted` 11.5px x2 ve
   `.oy-facts dt` 11.2px x2.
   KÖK NEDEN (frontend-3 bundle b-8ejzc6l4yz): `.oy-badge{font-size:.72rem}`
   (:19053) ve `.oy-facts dt{font-size:.7rem}` (:19108).
   NOT: `.oy-badge` zaten `display:inline-flex` — Y1 vermiyor, yalnız metin
   küçük. Yani burada dokunma hedefi değil OKUNABİLİRLİK düzeltiliyor. */
body.edulive-cihaz span.oy-badge,
body.edulive-cihaz .oy-facts dt {
  font-size: max(12px, 0.75rem);
}

/* --- 16.2 · DERS SEÇİCİ ÇİPİNDEKİ SAYAÇ (Y2) -------------------------------
   ÖLÇÜM: /content-studio/plans/generate — `span.ds-chip__count` 11.5px x16.
   KÖK NEDEN (b-gd7uj4oj7p): `.ds-chip__count{font-size:.72rem;padding:1px 6px}`
   (:28995). Çip içindeki kazanım sayısı — 16 ders çipinin her birinde bir tane.
   `padding` küçük olduğu için 0.5 px büyüme çipi taşırmaz (ölçüldü: çip
   yüksekliği rozetin değil, ebeveyn `.ds-chip` dolgusunun ürünü). */
body.edulive-cihaz span.ds-chip__count {
  font-size: max(12px, 0.75rem);
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 25 · AJAN KAZANIM SEÇİCİ + GERÇEK ZAMANLI DURUM (Tur 33)
   Turun son iki modülü: ajan (5 rota) ve tekil sayfalar (11 rota) §13.8 adım 4
   ile tarandı. Y1 SIFIR — bkz. 17.0 notu. Kalan iki bulgu yine 0.7x rem rozet
   deseni (BANT 15.2 / 16 ile aynı kök), aynı reçeteyle kapatılır.
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- 17.0 · YANLIŞ-POZİTİF KAYDI: `input.cp__check` 16x16 x500 ---------------
   /ajan/ders-icerigi/uret ilk ölçümde 500 adet 16x16 onay kutusu bildirdi —
   turun en büyük görünen Y1 bulgusuydu. DOM ölçümü kusuru ÇÜRÜTTÜ:

     <li class="cp__item">
       <input type="checkbox" id="cp-…" class="cp__check">   ← 16x16
       <label class="cp__card-body" for="cp-…">…</label>     ← 240x70  ✅
     </li>

   Etiket input'u SARMIYOR, `for=` ile kardeşi — bu yüzden §13.14 filtresinin
   `closest('label')` testi elemedi. Gerçek dokunma hedefi 240x70 px etikettir
   (WCAG 2.5.8'in "eşdeğer işlevli yeterli hedef" istisnası). CSS YAZILMADI.
   ÖLÇÜM ARACI DÜZELTİLDİ: t33-gorsel.py artık `closest('label')` bulamazsa
   `label[for=<id>]` kardeşini de arıyor — bu yanlış-pozitif bir daha çıkmaz. */

/* --- 17.1 · KAZANIM KARTI ROZETLERİ (Y2) -----------------------------------
   ÖLÇÜM: /ajan/ders-icerigi/uret — `.cp__badge--ders` 11.0px x499,
   `--sinif` 11.0px x496, `--tema` 11.0px x415. Toplam 1410 örnek; turun en
   yaygın okunabilirlik kusuru.
   KÖK NEDEN (b-umqgisywlw:28702): `.cp__badge{font-size:11px;height:19px;
   display:inline-grid;place-items:center;line-height:1}`.
   Burada kaynak SABİT px (rem mirası yok) — yine de `max(12px,0.75rem)`
   yazılıyor ki kullanıcının yazı tipi ölçeği rozeti de büyütsün (§13 tercihi).
   `height` 19→20px: 12px metin `line-height:1` ile 19px kutuya sığar, ama
   1px pay bırakmak yuvarlama farklarında kırpılmayı engeller. `.cp__item`
   84px yüksekliğinde olduğu için 1px'lik büyüme yerleşimi kaydırmaz. */
body.edulive-cihaz span.cp__badge {
  font-size: max(12px, 0.75rem);
  height: 20px;
}

/* --- 17.2 · GERÇEK ZAMANLI DURUM ÇİPİ VE NOTU (Y2) -------------------------
   ÖLÇÜM: /status/realtime — `span.rs-pill.is-on` 11.5px x3, `p.rs-note`
   11.5px x2.
   KÖK NEDEN (b-6cdvbv4i4k): `.rs-pill{font-size:.72rem}` (:13965) ve
   `.rs-note{font-size:.72rem}` (:14013).
   `.rs-pill` zaten `inline-flex` + `padding:3px 12px` — Y1 vermiyor, yalnız
   metin küçük. `.rs-note` `line-height:1.4` ile akan paragraf; 0.5px büyüme
   satır yüksekliğini ~0.7px artırır, kap sabit yükseklikli değil. */
body.edulive-cihaz span.rs-pill,
body.edulive-cihaz p.rs-note {
  font-size: max(12px, 0.75rem);
}

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .hub-card:has(> .hub-card__ikon)::before {
    display: none;
  }

  body.edulive-cihaz .hub-card__metin {
    flex: 1 1 auto;
    min-width: 0;
  }
}

@media (max-width: 640px) {
  body.edulive-cihaz .hub-card__ikon {
    width: 20px;
    height: 20px;
    border-radius: 0;
    background: none;
    border: 1px solid transparent;
    align-self: center;
  }

  body.edulive-cihaz .hub-card__ikon svg {
    width: 20px;
    height: 20px;
  }
}

@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .hub-card {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 10px;
    row-gap: 8px;
    align-content: end;
  }

  body.edulive-cihaz .hub-card__metin {
    display: contents;
  }

  body.edulive-cihaz .hub-card__ikon {
    grid-column: 1;
    grid-row: 1;
    width: 32px;
    height: 32px;
    border-radius: 10px;
    align-self: center;
  }

  body.edulive-cihaz .hub-card__ikon svg {
    width: 18px;
    height: 18px;
  }

  body.edulive-cihaz .hub-card__title {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
    min-width: 0;
  }

  body.edulive-cihaz .hub-card__desc {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}

/* ===========================================================================
   26 · "BENİ HATIRLA" ONAY KUTUSU — DOKUNMA HEDEFİ
   CİHAZ BANDI (telefon + dokunmatik tablet)  —  K3 · K9 · K10

   Öğe YALNIZ cihaz uygulamasında çizilir: Login.razor onay kutusunu
   `ISessionPersistencePreference` DI'da çözülebiliyorsa gösterir ve o servis
   yalnız MauiProgram'da kayıtlıdır. Web'de işaretleme hiç üretilmez, bu yüzden
   masaüstünde eşleşecek bir seçici de yoktur (K9 sınaması etkilenmez).

   auth.css tabanı 22x22 px verir — WCAG 2.5.8 için yetersiz. Kutunun GÖRSEL
   boyutu korunur (tasarım değişmez), dokunma hedefi ::after ile büyütülür;
   böylece kutu ile etiket arasındaki 10 px boşluk da hedefe dahil olur.
   Etiketin kendisi de aynı satırda 44 px yüksekliğe çıkarılır — kullanıcı
   metne dokununca da tercih değişir (Login.razor etikete de @onclick verir).
   =========================================================================== */
@media (max-width: 640px), (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz .giris__hatirla {
    gap: 12px;
    margin-top: 20px;
  }

  body.edulive-cihaz .giris__hatirla-kutu {
    position: relative;
    min-height: 22px;
  }

  body.edulive-cihaz .giris__hatirla-kutu::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }

  body.edulive-cihaz .giris__hatirla-etiket {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}


/* ===========================================================================
   27 · PUNTO ÖLÇEĞİ  —  YALNIZ TELEFON  (YENI-DIL §2.3, 2026-09-17)
   ===========================================================================
   GÜNCEL: tablet masaüstü puntosunu alır; aşağıdaki küçültmeler TELEFON bandına
   taşındı (23c). Ölçek `--yazi-*` tokenlarıdır (23a, TELEFON'da `body` üzerinde);
   `--cihaz-yazi-*` eski adlar takma ad olarak CİHAZ bandında kalır (23b). Aşağıdaki
   ölçüm ve kapsam notu ölçeğin ilk kuruluşuna (2026-08) aittir.

   ÖLÇÜM (iPhone 17 Pro, 402 CSS px, canlı ekran görüntüsünden):
     .giris__h            23 px   ("Tekrar hoş geldiniz")
     .giris__mobil-marka  22 px   ("EduLive")
     .home-hero__title    22 px   ("Merhaba, tugcek" — 1. bantta zaten 42'den indi)
     .au-title            22 px   (clamp(22,3vw,30) alt sınırı — 323 sayfa)
     .au-sub              14 px  ·  .giris__s 13,5  ·  .giris__foot 13
     .au-breadcrumb       13 px  ·  alan etiketi 12,5  ·  alt çubuk 10,5
   İki ayrı kusur: (a) başlıklar 402 px'lik ölçüye göre büyük, (b) ekranda 14
   farklı punto dolaşıyor — bir ölçek yok.

   ÖLÇEK (tek kaynak, `body.edulive-cihaz` üzerinde özel özellik olarak):
     --cihaz-yazi-xl 20   ekran başlığı, KPI sayısı   (masaüstü 22-30)
     --cihaz-yazi-lg 17   kart/sayfa alt başlık        (şu an ALICISI YOK)
     --cihaz-yazi-md 15   gövde metni       (aurora.css:209 zaten 15)
     --cihaz-yazi-sm 13   yardımcı metin, düğme, uyarı
     --cihaz-yazi-xs 12   etiket, kırıntı, rozet, küçük düğme (K9 tabanı 11'in üstünde)
   Adımlar 1,15-1,18 oranında; 4 pt'lik sıçrama yok, hiyerarşi korunuyor.

   KAPSAM (ikinci turda ölçülerek genişletildi). Aday sınıflar `*.razor`
   içindeki gerçek kullanım sayısıyla elendi; cihazda hiç çizilmeyen veya
   sıfır kullanımlı olanlar ALINMADI:
     ALINDI    .au-btn 335 · .au-banner 210 · .au-status 175 · .au-btn--sm 138
               .au-facts 55 · .au-summary 38 · .au-kpi__num 30 · .au-email 30
               .au-danger-zone__title 18 · .au-assign-row__role/scope 7
               .auth-error 4 · .auth-foot 2 · .org-card__type 2
               .home-hero__sub · .hub-card__desc · .menu button
     ALINMADI  .card h3 / .card p / .rcard / .notif / .wallet / .chip / .hero
               .eyebrow  —  hiçbiri `class="..."` olarak razor'da GEÇMİYOR
               (aurora.css'in kullanılmayan bölümü; ölü kural yazılmadı).
     ALINMADI  .giris__ust 19 · .giris__soz p 15,5 · .auth-brand__logo 22
               .auth-brand__word 20  —  ilk ikisi `.giris__foto` içinde ve
               auth.css:791 onu `max-width:900px`te `display:none` yapar;
               son ikisi 46 px'lik amblem kutusuyla dengede, küçültmek
               kutuyla metni ayırırdı.
   `.home-hero__sub` ve `.hub-card__desc` telefon bandında (1. bant) zaten
   `display:none`; kural TABLET için yazıldı — orada ikisi de çizilir.

   NE DEĞİŞMİYOR — bilerek:
   • GİRDİ PUNTOSU. 2. bant girdileri `max(16px, 1rem)` yapar; iOS 16'nın
     altında odakta sayfayı yakınlaştırır (K4). Ölçek girdilere UYGULANMAZ.
   • ALT ÇUBUK 10,5 px. Kendi bandında ölçülerek seçildi; 5 yuva 72 px'e
     sığsın diye. Ölçek onu büyütseydi "Planlama" yuvayı taşırırdı (K2).
   • MASAÜSTÜ. Sorgu 1. bantla birebir aynı; >= 1280 px'te hiçbir kural
     eşleşmez (K9).
   • WCAG 11 px tabanı. En küçük değer 12 px — 13.11'in tabanının üstünde.
   • `--cihaz-yazi-lg` TANIMLI AMA KULLANILMIYOR. İki aday elendi:
     `.hub-card__title` 1. bantta ölçülerek 15 px'e çekilmişti (143 px'lik
     sütunda 17 px başlığı 3 satıra kırıyor) ve `.cihaz-sheet__baslik` kendi
     bandında zaten 16 px. İkisini de 17'ye çekmek BÜYÜTME olurdu; bu tur
     küçültme turu. Token ölçeğin tam hâlini belgelemek için duruyor.
   • DÜĞME KUTULARI. `.au-btn` 13,5 -> 13 ve `.au-btn--sm` 12,5 -> 12 yalnız
     punto değiştirir; dolgu (`9px 16px` / `7px 12px`) ve 13.x bantlarının
     `min-width: 44px` kuralı yerinde. 402 px'te ölçüldü: .au-btn 76x34,
     .au-btn--sm 38,6x29 — dokunma hedefi kuralları K3'ü ayrıca sağlıyor.

   ÖZGÜLLÜK: `body.edulive-cihaz .au-title` (0,2,1) kapsamlı `.au-title`
   (0,1,0) ve `admin-users.css`in kapsamsız kuralını yener; `!important` yok.
   `clamp()` yazan kurallar da düz değerle eziliyor — clamp özgüllük taşımaz.
   =========================================================================== */
/* PUNTO a · YAZI ÖLÇEĞİ TOKENLARI — TELEFON. Vitrin ve analiz dosyalarının TELEFON
   kuralları bunları kullanır; TELEFON dışında tanımsızdır (tablet masaüstü değerinde). */
@media (max-width: 640px) {

  body.edulive-cihaz {
    --yazi-baslik: 22px;
    --yazi-baslik-genel: 20px;
    --yazi-kapak: 20px;
    --yazi-kpi: 20px;
    --yazi-bolum: 14px;
    --yazi-govde: 13px;
    --yazi-kucuk: 12px;
    --yazi-etiket: 11px;
    --yazi-sekme: 10.5px;
  }
}

/* PUNTO b · ESKİ ÖLÇEK ADLARI — CİHAZ. `--cihaz-yazi-*` takma addır: telefonda `--yazi-*`
   tokenına bağlanır, tablette token olmadığından yedek değer kalır (tablet
   tüketicileri — kullanıcı listesi, kart tablo — bu turda değişmez). */
@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz {
    --cihaz-yazi-xl: var(--yazi-baslik-genel, 20px);
    --cihaz-yazi-lg: 17px;
    --cihaz-yazi-md: 15px;
    --cihaz-yazi-sm: var(--yazi-govde, 13px);
    --cihaz-yazi-xs: var(--yazi-kucuk, 12px);
  }
}

/* PUNTO c · TELEFON PUNTO KURALLARI — eskiden CİHAZ bandındaydı; tablet artık almaz. */
@media (max-width: 640px) {

  /* --- ekran başlıkları: vitrinsiz başlık, "Merhaba", KPI ------------------ */
  body.edulive-cihaz .au-title,
  body.edulive-cihaz .giris__h,
  body.edulive-cihaz .auth-card__title {
    font-size: var(--yazi-baslik-genel);
    line-height: 1.2;
  }

  body.edulive-cihaz .home-hero__title {
    font-size: var(--yazi-baslik);
    line-height: 1.2;
  }

  body.edulive-cihaz .au-kpi__num {
    font-size: var(--yazi-kpi);
    line-height: 1.2;
  }

  /* Marka kelimesi başlıkla aynı satırda değil ama aynı ağırlıkta okunuyor;
     22 -> 18 ile amblemin 62 px'lik kutusuyla dengeye giriyor. */
  body.edulive-cihaz .giris__mobil-marka span {
    font-size: 18px;
  }/* --- md · gövde --------------------------------------------------------- */
/* --- gövde · yardımcı metin, düğme, uyarı ------------------------------- */



  body.edulive-cihaz .au-sub,
  body.edulive-cihaz .giris__s,
  body.edulive-cihaz .giris__foot,
  body.edulive-cihaz .auth-card__sub,
  body.edulive-cihaz .au-btn,
  body.edulive-cihaz .au-banner,
  body.edulive-cihaz .au-summary,
  body.edulive-cihaz .au-danger-zone__title,
  body.edulive-cihaz .au-assign-row__role,
  body.edulive-cihaz .au-facts > div,
  body.edulive-cihaz .hub-card__desc,
  body.edulive-cihaz .auth-error,
  body.edulive-cihaz .menu button {
    font-size: var(--yazi-govde);
  }

  /* --- küçük · etiket ve kırıntı -----------------------------------------
     Alan etiketi 12,5 -> 12: girdi kutusunun kendi puntosu (16 px, K4)
     değişmediği için etiket/değer karşıtlığı artıyor, azalmıyor. */
  body.edulive-cihaz .au-breadcrumb,
  body.edulive-cihaz .app-field .app-field__label,
  body.edulive-cihaz .giris__hatirla-etiket,
  body.edulive-cihaz .au-btn--sm,
  body.edulive-cihaz .au-email,
  body.edulive-cihaz .au-status,
  body.edulive-cihaz .au-assign-row__scope,
  body.edulive-cihaz .auth-foot,
  body.edulive-cihaz .org-card__type {
    font-size: var(--yazi-kucuk);
  }

  /* ÖZGÜLLÜK ÖLÇÜLDÜ: giriş ekranında yukarıdaki (0,3,1) YETMEZ —
     `auth.css:641` etiketi `.giris .giris__form .app-field .app-field__label`
     ile (0,4,0) yazar ve sınıf sayısı 4 > 3 olduğu için kazanır (ilk turda
     etiket 12,5 px'te kaldı, ölçümle görüldü). Aynı zinciri `body` ile
     tekrarlamak (0,5,1) veriyor. */
  body.edulive-cihaz .giris .giris__form .app-field .app-field__label {
    font-size: var(--yazi-kucuk);
  }
}

@media (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .hub-card {
    background: var(--glass);
  }

  body.edulive-cihaz .hub-card__glow {
    display: block;
    opacity: 0.6;
  }
}






/* ═══════════════════════════════════════════════════════════════════════════
   28 · ÜST BAR GÜVENLİ ALANA DEMİRLENİR — kaydırınca çentiğin altına girmesi
   CİHAZ BANDI (telefon + tablet + dokunmatik 1024-1279)      K6 · K9 · K10

   ŞİKÂYET: "sadece mobil için kaymayan tab bar olmaz mı" — ekran görüntüsünde
   marka amblemi ile saat 18:01 üst üste binmişti.

   KUSUR — SİMÜLATÖRDE ÖLÇÜLDÜ (iPhone 17 Pro, 402x874 CSS px)
   `.status-bar-safe-area` (app.css) `position: sticky; top: 0` ve yüksekliği
   `env(safe-area-inset-top)` = 62 px. `.topbar` (aurora.css:307) da
   `position: sticky; top: 0`. İKİSİ AYNI kapsayıcı blokta ve AYNI eşiğe
   demirli — 19. banttaki `.imp-banner` kusurunun birebir aynı mekanizması,
   bu kez suçlu güvenli alan tamponu.

   Sayfa başındayken sorun görünmez: tampon akışta üst barın ÜSTÜNDEDİR,
   bar 62 px'ten başlar. Kaydırılınca ikisi de 0'a çakılır:

     scrollY   .status-bar-safe-area      .topbar
     0         top=0   h=62               top=62   ✓ doğru
     55        top=0   h=62               top=7    ✗ çentiğin ALTINDA

   Yani bar 55 px kayınca 62 px'lik tamponun içine 55 px giriyor; marka,
   kurum değiştirici, bildirim zili ve avatar saatin/dinamik adanın arkasında
   kalıyor. Ekran görüntüsündeki üst üste binme tam olarak budur.

   ÇÖZÜM: üst bar 0'a değil GÜVENLİ ALANIN ALTINA demirlenir. `top` yapışkan
   eşiği taşır; `env()` orada da geçerlidir. Yedek değer 0px ŞART — env()
   desteklenmeyen WebView'da bildirim kuralı tümden düşerdi.

   ÖLÇÜM SONRASI (aynı cihaz, kural uygulanmış paket):
     scrollY=18 (sayfanın sonu)  ->  .topbar top=62.0  ✓ değişmiyor
     docH 892 · innerH 874 · `.cihaz-sekme` top=784 h=90 — alt çubuk ve
     belge yüksekliği bir piksel bile değişmedi.

   KAPSAM — üç yapışkan üst krom birlikte kaydırılır, aksi hâlde ayrışırlar:
   ·  `.topbar`          aurora.css:307    personel düzeni
   ·  `.student-topbar`  StudentLayout:36  öğrenci düzeni (kendi barı)
   ·  `.imp-banner`      ImpersonationBanner:1  akışta barın ÜSTÜNDE; aynı
      eşiğe taşınmazsa 19. bandın z 64 kararı korunsa bile şerit çentiğe
      girerdi. z sırası DEĞİŞMEDİ, yalnız demir noktası ortaklaştı.

   NEDEN TAMPONA `top` YAZILMADI: `.status-bar-safe-area` doğru davranıyor —
   çentiğin tam altında durup arkasına opak zemin koymak onun işi. Sorun
   barın onunla AYNI eşiği paylaşması; düzeltme bar tarafına yazılır.

   ELENEN ALTERNATİFLER
   (a) Tamponu `position: fixed` yapmak — barın demir noktasını düzeltmez,
       yalnız tamponu akıştan çıkarıp bu kez 62 px'lik bir boşluk açardı.
   (b) `.topbar`a `margin-top` — akıştaki yeri değiştirir, yapışkan eşiği
       değiştirmez; kaydırınca aynı çakışma sürerdi.
   (c) Tampona `z-index` verip barın üstünde tutmak — çakışmayı gizler,
       barın kendisi yine erişilemez kalırdı (19. bandın reddettiği yol).

   NEDEN app.css'te DEĞİL: bu bir BANT kuralıdır. Masaüstünde (>= 1280 px,
   fareli) `env()` sıfırdır ve web bir piksel değişmemelidir (K9) — cihaz.css
   bant sözleşmesi bunu yapısal olarak garanti eder.

   GERİ ALMA: bu bandın tamamı silinebilir; hiçbir kural başka bir bandın
   önkoşulu değil.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .topbar,
  body.edulive-cihaz .student-topbar,
  body.edulive-cihaz .imp-banner {
    top: env(safe-area-inset-top, 0px);
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   29 · ÜST KROM SAYFA DEGRADESİNİ SÜRDÜRÜR — beyaz bloğun kesik izi
   CİHAZ BANDI (telefon + tablet + dokunmatik 1024-1279)      K9 · K10

   ŞİKÂYET: "şu renkler tabbardan devam edemez mi kesik gibi olmuş".

   KUSUR — EKRAN GÖRÜNTÜSÜNDEN ÖLÇÜLDÜ
   Üst blok saf beyaz rgb(255,255,255); hemen altındaki sayfa rgb(241,246,254).
   Arada `--line` saç çizgisi. Yani krom, `--page-bg` degradesini kesiyor.

   Beyaz tesadüf değil: 10. bant `.topbar` ve `.student-topbar`ın
   `backdrop-filter: blur(22px)` katmanını kaldırıp yerine opak beyaz koymuştu
   (cihazda bulanıklık pahalı). `.status-bar-safe-area` (app.css) da
   `var(--yuzey, #ffffff)`. İkisi birleşince 114 px'lik kesintisiz beyaz blok
   oluşuyor. 10. bandın opaklık kararı DOĞRU ve korunuyor — değişen yalnız
   opak zeminin RENGİ: beyaz yerine sayfanın kendi degradesi.

   NEDEN `background-attachment: fixed` — SİMÜLATÖRDE ÖLÇÜLDÜ
   `body` zaten `background-attachment: fixed` kullanıyor (aurora.css:207).
   Yapışkan kroma aynı bildirim verilince ikisi AYNI referansa hizalanır.
   iPhone 17 Pro / iOS 26.1, yüksek kontrastlı degrade (kırmızı-yeşil-mavi)
   ile üç kaydırma konumunda bar içi ve hemen altındaki içerik ölçüldü:

     kaydırma        `attachment: fixed`      `100vw 100vh` hizalama
     0               fark 5   pürüzsüz        fark 65   DİKİŞ
     400             fark 5   pürüzsüz        fark 23   DİKİŞ
     900             fark 5   pürüzsüz        fark 121  DİKİŞ

   `100vw 100vh` + `background-position` ELENDİ: kağıt üstünde denk düşüyor
   ama iOS'ta yapışkan öğenin boyama kutusu kaydırmayla birlikte gezmediği
   için renk sabit kalıyor, sayfa akıp gidiyor — kaydırdıkça dikiş büyüyor
   (yukarıdaki üçüncü sütun). Ölçüm bu yolu kapattı.

   KAPSAM
   ·  `.topbar`                personel düzeni
   ·  `.student-topbar`        öğrenci düzeni
   ·  `.status-bar-safe-area`  çentik tamponu (app.css'te `--yuzey`di);
      üçü bitişik durduğu için biri beyaz kalsa kesik yine görünürdü.

   DOKUNULMAYANLAR
   ·  `.imp-banner` — kehribar UYARI şeridi; rengi kasıtlı ayrımdır, degradeye
      karışması uyarıyı zayıflatırdı (10. bandın kararı duruyor).
   ·  `.toast` — kayan bildirim, sayfa kromu değil.
   ·  `.cihaz-sekme` (alt çubuk) — ekran görüntüsünde yok, kullanıcı sormadı.
   ·  `border-bottom` saç çizgisi — bar sınırını hâlâ belli eder; kaldırmak
      ayrı bir karar, istenmedi.
   ·  10. bandın `backdrop-filter: none` kararı — aynen yerinde.

   GERİ ALMA: bu bandın tamamı silinebilir; 10. bandın beyaz zemini geri gelir.
   ========================================================================= */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .student-topbar,
  body.edulive-cihaz .status-bar-safe-area {
    background: var(--page-bg);
    background-attachment: fixed;
  }
}


@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .student-topbar {
    border-bottom-color: transparent;
  }

  body.edulive-cihaz .student-topbar::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    pointer-events: none;
    background: linear-gradient(
      90deg,
      var(--marka-500) 0%,
      var(--turkuaz-500) 52%,
      var(--basari) 100%
    );
  }
}


@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .cihaz-sekme__ikon {
    width: 24px;
    height: 24px;
  }

  body.edulive-cihaz .cihaz-sekme__ikon svg {
    width: 24px;
    height: 24px;
  }

  body.edulive-cihaz .cihaz-sekme__etiket {
    font-size: 11px;
  }
}



@media (max-width: 640px) {








}


@media (max-width: 640px) {

















  body.edulive-cihaz:has(.student-topbar) {
    --topbar-h: 58px;
  }

  body.edulive-cihaz .student-topbar {
    padding-bottom: 3px;
  }

  body.edulive-cihaz .menu {
    min-width: 264px;
    max-width: calc(100vw - 20px);
  }

  body.edulive-cihaz .menu .mt {
    text-transform: none;
    letter-spacing: 0;
    font-size: var(--cihaz-yazi-sm);
    line-height: 1.35;
    padding: 7px 12px 4px;
  }



  body.edulive-cihaz .menu button {
    min-height: 44px;
    padding-top: 11px;
    padding-bottom: 11px;
    justify-content: flex-start;
    text-align: left;
  }

  body.edulive-cihaz .menu button > svg {
    flex: 0 0 auto;
  }
}


@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {





  /* Dokunma bandında üçü de 44 px; açılırlar barın alt çizgisine aynı
     kaymayla iner. */








  body.edulive-cihaz .student-topbar {
    padding-bottom: 3px;
  }
}


@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .wrap:has(.au-liste-kullanicilar) {
    padding-left: 0;
    padding-right: 0;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar {
    padding-left: 12px;
    padding-right: 12px;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head {
    display: block;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head--geri {
    display: flex;
  }

  /* P2-84 · web'de aksiyonlar süzgeç satırının SAĞINDA duruyor (admin-users.css).
     Dar bantta yan yana sığmaz: satır sütuna döner ve aksiyonlar `order: -1` ile
     yine başlığın hemen altına, süzgeçlerin ÜSTÜNE çıkar — bandın eski dizilimi
     birebir korunur. Sarmalayıcının kendi 16 px boşluğu yeterli olduğu için
     aksiyonların 14 px'lik üst marjı burada sıfırlanır. */
  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filtre-satiri {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filtre-satiri > .au-head__actions {
    order: -1;
    margin-top: 0;
    margin-left: 0;
  }

  /* Web'deki tek sıra kuralı (admin-users.css `.au-filtre-satiri > .au-filters`)
     bandda geri alınır: burada süzgeçler bandın kendi sütun sayısına uyar —
     640 px altında alt alta, üstünde iki ya da üç sütun. */
  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filtre-satiri > .au-filters {
    display: grid;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filtre-satiri > .au-filters > * {
    min-width: 0;
    max-width: none;
  }

  body.edulive-cihaz .au-page .au-filtre-satiri {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
  }

  body.edulive-cihaz .au-page .au-filtre-satiri > .au-head__actions {
    order: -1;
    margin-top: 0;
    margin-left: 0;
  }

  body.edulive-cihaz .au-page .au-filtre-satiri > .au-filters {
    display: grid;
  }

  body.edulive-cihaz .au-page .au-filtre-satiri > .au-filters > * {
    min-width: 0;
    max-width: none;
  }

  @media (min-width: 641px) {

    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head {
      display: flex;
    }

    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions {
      margin-top: 0;
    }
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 9px;
    margin-top: 14px;
  }

  @media (min-width: 641px) {

    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions .au-btn--primary {
      grid-column: auto;
    }
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions .au-btn {
    justify-content: center;
    min-height: 44px;
    padding: 9px 10px;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-head__actions .au-btn--primary {
    grid-column: 1 / -1;
  }

  body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filters {
    grid-template-columns: 1fr;
    gap: 12px;
    margin-bottom: 18px;
  }

  @media (min-width: 641px) {

    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filters {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Arama kutusu (SearchExternal ile süzgeç satırına indi) iki sütunlu bantta
       kendi satırını tam genişlik kaplar — e-posta araması dar kutuda okunmuyor. */
    body.edulive-cihaz .au-page.au-liste-kullanicilar .au-filters > .au-arama {
      grid-column: 1 / -1;
    }
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid {
    gap: 18px;
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid .grid-toolbar {
    justify-content: stretch;
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid .grid-search {
    width: 100%;
    min-width: 0;
    height: 44px;
    background: transparent;
    border-color: var(--n-200);
    border-radius: var(--radius-sm);
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid .grid-search input {
    font-size: max(16px, 1rem);
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid .grid-pager {
    gap: 10px;
    margin-top: 18px;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-scroll {
    overflow-x: visible;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table,
  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody,
  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody tr,
  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody td {
    display: block;
    width: auto;
  }

  body.edulive-cihaz .au-liste-kullanicilar .app-grid .grid-scroll {
    overflow: visible;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table thead {
    display: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody {
    display: grid;
    gap: 10px;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody tr {
    position: relative;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    grid-template-areas:
      "org org    org"
      "sec ad     durum"
      "sec eposta eposta"
      "sec roller roller";
    column-gap: 10px;
    row-gap: 3px;
    padding: 0 14px 13px 3px;
    border: 1px solid var(--n-200);
    border-radius: 18px;
    background: var(--yuzey);
    overflow: hidden;
    -webkit-tap-highlight-color: transparent;
    transition:
      background 0.18s var(--ease-smooth),
      border-color 0.18s var(--ease-smooth);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody tr::before {
    content: "";
    grid-column: 1 / -1;
    grid-row: 1;
    align-self: stretch;
    margin: 0 -14px 0 -3px;
    background: var(--marka-600);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody tr:active {
    background: var(--n-100);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody tr:has(.au-check:checked) {
    border-color: var(--marka-500);
    background: color-mix(in srgb, var(--marka-500) 4%, var(--yuzey));
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table tbody td {
    display: contents;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-namecell {
    display: contents;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-avatar {
    display: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check {
    grid-area: sec;
    justify-self: center;
    align-self: center;
    position: relative;
    appearance: none;
    -webkit-appearance: none;
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    z-index: 2;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    border-radius: 7px;
    border: 1.5px solid var(--n-300);
    background: var(--yuzey);
    transition:
      background 0.16s var(--ease-smooth),
      border-color 0.16s var(--ease-smooth),
      transform 0.16s var(--ease-smooth);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check:checked::before {
    background: var(--marka-500);
    border-color: var(--marka-500);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check:active::before {
    transform: scale(0.9);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 4.5px;
    height: 9.5px;
    margin: -6.8px 0 0 -2.5px;
    border: 2.1px solid var(--on-brand);
    border-top: 0;
    border-left: 0;
    transform: rotate(42deg);
    opacity: 0;
    transition: opacity 0.12s ease;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check:checked::after {
    opacity: 1;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check:focus-visible {
    outline: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-check:focus-visible::before {
    box-shadow:
      0 0 0 3px var(--yuzey),
      0 0 0 5.5px var(--marka-500);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-org {
    grid-area: org;
    z-index: 1;
    display: block;
    min-width: 0;
    max-width: calc(100% - 10.4em);
    padding: 8px 0 8px 17px;
    color: var(--on-brand);
    font-size: var(--cihaz-yazi-xs);
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: -0.004em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-org small {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table td:nth-child(7) .au-dim {
    position: absolute;
    top: 0;
    right: 17px;
    z-index: 1;
    display: block;
    min-width: 0;
    padding: 8px 0;
    color: color-mix(in srgb, var(--on-brand) 84%, var(--marka-600));
    font-size: var(--cihaz-yazi-xs);
    font-weight: 500;
    line-height: 1.4;
    letter-spacing: -0.004em;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table td:nth-child(4) .au-dim {
    grid-area: org;
    z-index: 1;
    display: block;
    max-width: calc(100% - 10.4em);
    padding: 8px 0 8px 17px;
    color: color-mix(in srgb, var(--on-brand) 84%, var(--marka-600));
    font-size: var(--cihaz-yazi-xs);
    font-weight: 600;
    line-height: 1.4;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table td:nth-child(5) .au-dim {
    grid-area: roller;
    margin-top: 8px;
    color: var(--n-400);
    font-size: var(--cihaz-yazi-xs);
    line-height: 1.4;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-name {
    grid-area: ad;
    align-self: end;
    min-width: 0;
    max-width: 100%;
    margin-top: 11px;
    font-family: var(--font-display);
    font-size: 17.5px;
    font-weight: 600;
    line-height: 1.24;
    letter-spacing: -0.024em;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-email {
    grid-area: eposta;
    display: block;
    min-width: 0;
    max-width: 100%;
    padding: 0;
    border-radius: 0;
    background: none;
    font-family: inherit;
    font-size: 12.5px;
    line-height: 1.35;
    letter-spacing: -0.004em;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    overflow-wrap: normal;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-chips {
    grid-area: roller;
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    max-width: 100%;
    margin-top: 8px;
    overflow: hidden;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-chip {
    flex: 0 1 auto;
    min-width: 0;
    padding: 3px 8px;
    border: 0;
    border-radius: 7px;
    background: var(--n-100);
    color: var(--n-600);
    font-size: var(--cihaz-yazi-xs);
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -0.004em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-chip--more {
    flex: 0 0 auto;
    padding: 3px 2px;
    background: none;
    color: var(--n-400);
    font-weight: 500;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-status {
    grid-area: durum;
    justify-self: end;
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 11px;
    padding: 3px 9px;
    border: 0;
    border-radius: 8px;
    font-size: var(--cihaz-yazi-xs);
    font-weight: 600;
    letter-spacing: -0.004em;
    white-space: nowrap;
    box-shadow: none;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-status::before {
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-status.is-active {
    background: color-mix(in srgb, var(--basari-metin) 12%, var(--yuzey));
    color: var(--basari-metin);
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-status.is-active::before {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--basari-metin) 55%, transparent);
    animation: cihazDurumNabzi 2.4s var(--ease-smooth) infinite;
  }

  @keyframes cihazDurumNabzi {
    0% {
      box-shadow: 0 0 0 0 color-mix(in srgb, var(--basari-metin) 50%, transparent);
    }
    70% {
      box-shadow: 0 0 0 6px color-mix(in srgb, var(--basari-metin) 0%, transparent);
    }
    100% {
      box-shadow: 0 0 0 0 color-mix(in srgb, var(--basari-metin) 0%, transparent);
    }
  }

  body.edulive-cihaz .au-liste-kullanicilar .grid-table .au-status.is-passive {
    background: var(--n-100);
    color: var(--n-500);
  }
}


@media (max-width: 640px) {

  body.edulive-cihaz .wrap,
  body.edulive-cihaz .student-wrap,
  body.edulive-cihaz .auth-shell {
    padding-left: 12px;
    padding-right: 12px;
  }

  body.edulive-cihaz .au-page,
  body.edulive-cihaz .gallery {
    padding-left: 0;
    padding-right: 0;
  }
}


@media (max-width: 640px) {

  body.edulive-cihaz .auth-shell:has(> .giris) {
    padding-left: 0;
    padding-right: 0;
  }
}


@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  @keyframes cihazSayfaGirisi {
    to {
      opacity: 1;
    }
  }

  body.edulive-cihaz .au-page {
    animation-name: cihazSayfaGirisi;
  }
}


/* ALT SAYFALAR — ortak telefon kabuğu ve başlık sözleşmesi. */
@media (max-width: 640px) {
  body.edulive-cihaz .scrim,
  body.edulive-cihaz .nbell__scrim,
  body.edulive-cihaz .ou-switch__scrim,
  body.edulive-cihaz .kurum-sec__scrim,
  body.edulive-cihaz .ubg__scrim,
  body.edulive-cihaz .akn-bolum__perde,
  body.edulive-cihaz .app-ms__scrim,
  body.edulive-cihaz .ase__perde { background: var(--scrim); }

  body.edulive-cihaz .menu,
  body.edulive-cihaz .nbell__menu,
  body.edulive-cihaz .ou-switch__menu,
  body.edulive-cihaz .kurum-sec__menu,
  body.edulive-cihaz .ubg__sayfa,
  body.edulive-cihaz .akn-bolum__sayfa,
  body.edulive-cihaz .app-ms__panel,
  body.edulive-cihaz .ase__panel {
    position: fixed;
    inset: auto 0 0 0;
    width: auto;
    min-width: 0;
    max-width: none;
    min-height: calc(var(--sekme-h, 0px) + var(--sekme-alt, 0px) + 20px);
    max-height: 76dvh;
    margin: 0;
    padding: 8px 14px calc(var(--sekme-h, 0px) + var(--sekme-alt, 0px) + 14px);
    border: 0;
    border-top: 1px solid var(--hat-kart);
    border-radius: var(--kose-sayfa);
    background: var(--yuzey);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: var(--sayfa-alt-golge);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    transform-origin: bottom center;
  }
  body.edulive-cihaz .menu::before,
  body.edulive-cihaz .nbell__menu::before,
  body.edulive-cihaz .ou-switch__menu::before,
  body.edulive-cihaz .kurum-sec__menu::before,
  body.edulive-cihaz .ubg__sayfa::before,
  body.edulive-cihaz .akn-bolum__sayfa::before,
  body.edulive-cihaz .app-ms__panel::before,
  body.edulive-cihaz .ase__panel::before {
    content: "";
    display: block;
    flex: none;
    width: 38px;
    height: 4px;
    margin: 2px auto 10px;
    border-radius: var(--radius-pill);
    background: var(--n-300);
  }
  body.edulive-cihaz .ustbar-sheet-baslik,
  body.edulive-cihaz .ubg__bas,
  body.edulive-cihaz .nbell__head,
  body.edulive-cihaz .kurum-sec__head,
  body.edulive-cihaz .ou-switch__head,
  body.edulive-cihaz .akn-bolum__baslik {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 0 12px;
    margin: 0 0 8px;
    border-bottom: 3px solid var(--basari);
    color: var(--marka-700);
    font: 700 16px var(--font-display);
    letter-spacing: 0;
    text-transform: none;
  }
  body.edulive-cihaz .ustbar-sheet-baslik > span { display: inline; }
  body.edulive-cihaz .nbell__head .nbell__title { font: inherit; color: inherit; }
  body.edulive-cihaz .ustbar-sheet-kapat,
  body.edulive-cihaz .akn-bolum__kapat {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: auto;
    min-width: 44px;
    height: 36px;
    min-height: 36px;
    margin: 0 0 0 auto;
    padding: 0 12px;
    flex: 0 0 auto;
    border: 1px solid var(--hat-girdi);
    border-radius: var(--kose-dugme);
    color: var(--marka-600);
    background: var(--yuzey);
    font: 600 13px var(--font-body);
    touch-action: manipulation;
  }
  body.edulive-cihaz .ustbar-sheet-kapat::after,
  body.edulive-cihaz .akn-bolum__kapat::after { content: ""; position: absolute; inset: -4px; }
  body.edulive-cihaz .topbar .menu .ustbar-sheet-kapat { width: auto; min-height: 36px; padding: 0 12px; }
  body.edulive-cihaz .topbar .ubg .ustbar-sheet-kapat { min-height: 36px; }
  body.edulive-cihaz .menu button[role="menuitem"],
  body.edulive-cihaz .nbell__item,
  body.edulive-cihaz .nbell__all,
  body.edulive-cihaz .kurum-sec__item,
  body.edulive-cihaz .ou-switch__item,
  body.edulive-cihaz .akn-bolum__oge,
  body.edulive-cihaz .app-ms__opt { min-height: 48px; font-size: 15px; color: var(--fg); }
  body.edulive-cihaz .menu button[role="menuitem"] > svg { width: 18px; height: 18px; }
  body.edulive-cihaz .kurum-sec__item.is-active,
  body.edulive-cihaz .ou-switch__item.is-active,
  body.edulive-cihaz .akn-bolum__oge--secili {
    border-radius: var(--kose-dugme);
    border-left: 3px solid var(--basari);
    background: color-mix(in srgb, var(--marka-500) 6%, var(--yuzey));
    color: var(--marka-600);
    font-weight: 700;
    box-shadow: none;
  }
  body.edulive-cihaz .kurum-sec__item.is-active::after,
  body.edulive-cihaz .ou-switch__item.is-active::after { content: "✓"; margin-left: auto; }
  body.edulive-cihaz .ustbar-kimlik { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
  body.edulive-cihaz .ustbar-kimlik__harf { display: grid; place-items: center; flex: 0 0 40px; height: 40px; border-radius: var(--kose-dugme); background: var(--marka-600); color: var(--on-brand); font-weight: 700; }
  body.edulive-cihaz .ustbar-kimlik > div { min-width: 0; display: grid; gap: 4px; }
  body.edulive-cihaz .ustbar-kimlik strong { font: 700 16px var(--font-display); color: var(--marka-700); }
  body.edulive-cihaz .ustbar-kimlik > div > span { font-size: 13px; color: var(--muted); }
  body.edulive-cihaz .topbar .menu > .mt { display: none; }
  body.edulive-cihaz .kurum-sec__liste,
  body.edulive-cihaz .ou-switch__liste { max-height: none; overflow-y: visible; }

  @keyframes cihazAcilirSayfa {
    from { opacity: 0; transform: translateY(18px); }
    to { opacity: 1; transform: none; }
  }
  body.edulive-cihaz .menu.is-acik,
  body.edulive-cihaz .nbell__menu.is-acik,
  body.edulive-cihaz .ou-switch__menu.is-acik,
  body.edulive-cihaz .kurum-sec__menu.is-acik,
  body.edulive-cihaz .ubg__sayfa.is-acik,
  body.edulive-cihaz .akn-bolum__sayfa,
  body.edulive-cihaz .app-ms__panel,
  body.edulive-cihaz .ase__panel { animation: cihazAcilirSayfa .2s var(--ease-smooth) both; }

  body.edulive-cihaz.klavye-acik .menu,
  body.edulive-cihaz.klavye-acik .nbell__menu,
  body.edulive-cihaz.klavye-acik .ou-switch__menu,
  body.edulive-cihaz.klavye-acik .kurum-sec__menu,
  body.edulive-cihaz.klavye-acik .ubg__sayfa,
  body.edulive-cihaz.klavye-acik .akn-bolum__sayfa,
  body.edulive-cihaz.klavye-acik .app-ms__panel,
  body.edulive-cihaz.klavye-acik .ase__panel {
    bottom: var(--klavye-ortu, 0px);
    max-height: calc(76dvh - var(--klavye-ortu, 0px));
    padding-bottom: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  body.edulive-cihaz .menu.is-acik,
  body.edulive-cihaz .nbell__menu.is-acik,
  body.edulive-cihaz .ou-switch__menu.is-acik,
  body.edulive-cihaz .kurum-sec__menu.is-acik,
  body.edulive-cihaz .ubg__sayfa.is-acik,
  body.edulive-cihaz .akn-bolum__sayfa,
  body.edulive-cihaz .app-ms__panel,
  body.edulive-cihaz .ase__panel { animation: none; }
}


@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .app-ms__panel {
    display: flex;
    flex-direction: column;
    overflow-y: hidden;
  }

  body.edulive-cihaz .app-ms__search {
    flex: 0 0 auto;
    height: 44px;
    font-size: max(16px, 1rem);
  }

  body.edulive-cihaz .app-ms__opts {
    flex: 1 1 auto;
    max-height: none;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  body.edulive-cihaz .app-sel__opt {
    min-height: 52px;
    font-size: max(16px, 1rem);
  }
}


@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .menu,
  body.edulive-cihaz .nbell__menu,
  body.edulive-cihaz .ou-switch__menu,
  body.edulive-cihaz .kurum-sec__menu {
    max-height: calc(100dvh - var(--topbar-h) - var(--sekme-h) - var(--sekme-alt) - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  body.edulive-cihaz .app-ms__panel,
  body.edulive-cihaz .ase__panel {
    max-height: 52dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
}


@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) {
    gap: 16px;
  }

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-toolbar {
    justify-content: stretch;
  }

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-search {
    width: 100%;
    min-width: 0;
    height: 44px;
    background: transparent;
    border-color: var(--n-200);
    border-radius: var(--radius-sm);
  }

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-search input {
    font-size: max(16px, 1rem);
  }

  body.edulive-cihaz .grid-scroll:not(.au-liste-kullanicilar *) {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) {
    display: block;
    width: auto;
    font-size: max(14px, var(--cihaz-yazi-sm));
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) thead {
    display: none;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody {
    display: grid;
    gap: 10px;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody tr {
    display: block;
    width: auto;
    padding: 8px 14px 12px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius);
    background: var(--glass-strong);
    box-shadow: var(--glass-shadow);
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody tr:hover {
    background: var(--glass-strong);
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td {
    display: grid;
    grid-template-columns: minmax(0, 34%) minmax(0, 1fr);
    column-gap: 12px;
    align-items: baseline;
    width: auto;
    min-width: 0;
    padding: 5px 0;
    border-bottom: 0;
    vertical-align: baseline;
    overflow-wrap: anywhere;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td::before {
    content: attr(data-etiket);
    font-size: var(--cihaz-yazi-xs);
    font-weight: 600;
    line-height: 1.4;
    color: var(--muted);
    overflow-wrap: anywhere;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td > .au-status,
  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td > .au-chip,
  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td > .au-chips,
  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td > .au-email,
  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td > code.au-email {
    justify-self: start;
    max-width: 100%;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td:not([data-etiket=""]):has(> * + *) {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 12px;
    row-gap: 2px;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td:not([data-etiket=""]):has(> * + *)::before {
    flex: 0 0 34%;
    max-width: 34%;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td:not([data-etiket=""]):has(> * + *) > * {
    min-width: 0;
    overflow-wrap: anywhere;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td[data-etiket=""] {
    display: block;
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td[data-etiket=""]::before {
    content: none;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td .au-head__actions,
  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td[data-etiket=""] > div {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 8px;
    margin-top: 0;
  }

  body.edulive-cihaz .grid-table:not(.au-liste-kullanicilar *) tbody td .au-btn {
    justify-content: center;
    min-height: 44px;
    padding: 9px 10px;
  }

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-pager {
    gap: 10px;
    margin-top: 14px;
  }

  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-pager__nav .au-btn,
  body.edulive-cihaz .app-grid:not(.au-liste-kullanicilar *) .grid-pager__nav button {
    min-height: 44px;
    min-width: 44px;
  }
}


@media (max-width: 640px) {

  body.edulive-cihaz .au-form-actions {
    position: sticky;
    bottom: calc(var(--sekme-h) + var(--sekme-alt));
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 10px;
    margin-top: 18px;
    padding-top: 12px;
    padding-bottom: 12px;
    background: var(--yuzey);
    border-top: 1px solid var(--line);
  }

  body.edulive-cihaz .au-form-actions:last-child {
    position: static;
    background: transparent;
    padding-bottom: 0;
  }

  body.edulive-cihaz .au-form-actions .au-btn {
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    justify-content: center;
  }

  body.edulive-cihaz:has(.student-topbar) .au-head .au-head__actions {
    display: grid;
    grid-auto-flow: row;
    gap: 9px;
    margin-top: 14px;
  }

  body.edulive-cihaz:has(.student-topbar) .au-head .au-head__actions .au-btn {
    justify-content: center;
    min-height: 44px;
  }

  body.edulive-cihaz:has(.student-topbar) .au-head {
    display: block;
  }

  body.edulive-cihaz:has(.student-topbar) .au-head--geri {
    display: flex;
  }

  body.edulive-cihaz:has(.student-topbar) .au-page .au-head.au-head--geri:has(.au-sub) {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    row-gap: 14px;
  }

  body.edulive-cihaz:has(.student-topbar) .au-page .au-head.au-head--geri:has(.au-sub) > *:not(.au-breadcrumb):not(:has(.au-title)) {
    grid-column: 1 / -1;
    grid-row: 3;
    margin-top: 0;
  }

  /* Başlık ve geri ilk satırda; eylemler tek kaydırılabilir satırda. */
  body.edulive-cihaz:has(.topbar) .au-head {
    display: block;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 12px;
    row-gap: 8px;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri > .au-breadcrumb {
    grid-column: 1;
    grid-row: 1;
    margin: 0;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri > div:has(.au-title) {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri:has(.au-sub) {
    row-gap: 8px;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri > .au-head__actions,
  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri:has(.au-sub) > .au-head__actions {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  body.edulive-cihaz:has(.topbar) .au-page .au-head.au-head--geri:has(.au-sub) > div > .au-sub {
    grid-row: 3;
  }

  body.edulive-cihaz:has(.topbar) .au-head .au-head__actions {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    justify-self: start;
    gap: 8px;
    width: max-content;
    max-width: 100%;
    min-width: 0;
    margin: 0;
    padding: 2px;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
  }

  body.edulive-cihaz:has(.topbar) .au-head .au-head__actions::-webkit-scrollbar {
    display: none;
  }

  body.edulive-cihaz:has(.topbar) .au-head .au-head__actions:has(> :nth-child(3)) {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - 8px) / 2);
    width: 22rem;
    mask-image: linear-gradient(to right, transparent, var(--yuzey) 2px, var(--yuzey) calc(100% - 8px), transparent);
  }

  body.edulive-cihaz:has(.topbar) .au-head .au-head__actions .au-btn {
    position: relative;
    flex: 0 0 auto;
    justify-content: center;
    height: 40px;
    min-height: 40px;
    min-width: 44px;
    padding: 0 12px;
    border-radius: var(--kose-dugme);
    white-space: nowrap;
    scroll-snap-align: start;
  }

  body.edulive-cihaz:has(.topbar) .au-head .au-head__actions .au-btn::after {
    content: "";
    position: absolute;
    inset: -2px 0;
    min-height: 44px;
  }

  body.edulive-cihaz .au-filters {
    grid-template-columns: 1fr;
  }

  body.edulive-cihaz .au-filters > * {
    min-width: 0;
  }
}



/* CİHAZ — personel listesi puntosu; öğrenci kabuğu tabanını korur. */
@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-org { font-size: 13px; }
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-name { font-size: 13.5px; }
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-chip { font-size: 12px; }
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-status { font-size: 12.5px; }
  body.edulive-cihaz:has(.topbar) .grid-table:not(.au-liste-kullanicilar *) { font-size: 13.5px; }
  body.edulive-cihaz:has(.topbar) .grid-table:not(.au-liste-kullanicilar *) tbody td::before { font-size: 12.5px; }
}

/* TABLET — vitrinsiz sayfa başlığı masaüstü puntosunda. */
@media (min-width: 641px) and (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz:has(.topbar) .au-page:not([class*="-vitrin"]) > .au-head .au-title {
    font-size: 30px;
  }
}

/* TELEFON — kullanıcı ve genel kart tablo metni ortak ölçekte. */
@media (max-width: 640px) {
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table,
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-name,
  body.edulive-cihaz:has(.topbar) .grid-table:not(.au-liste-kullanicilar *) {
    font-size: var(--yazi-govde);
  }
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-email,
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-org,
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-chip,
  body.edulive-cihaz:has(.topbar) .au-liste-kullanicilar .grid-table .au-status,
  body.edulive-cihaz:has(.topbar) .grid-table:not(.au-liste-kullanicilar *) tbody td::before {
    font-size: var(--yazi-kucuk);
  }
}


@media (max-width: 640px) {

  body.edulive-cihaz .hub-grid {
    gap: 0;
  }

  body.edulive-cihaz .hub-grid .hub-card {
    border-radius: 0;
  }

  body.edulive-cihaz .hub-grid .hub-card:nth-child(2n) {
    border-left-width: 0;
  }

  body.edulive-cihaz .hub-grid .hub-card:nth-child(n + 3) {
    border-top-width: 0;
  }

  body.edulive-cihaz .hub-grid .hub-card:first-child {
    border-top-left-radius: 10px;
  }

  body.edulive-cihaz .hub-grid .hub-card:nth-child(2),
  body.edulive-cihaz .hub-grid .hub-card:first-child:last-child {
    border-top-right-radius: 10px;
  }

  body.edulive-cihaz .hub-grid .hub-card:nth-child(odd):last-child,
  body.edulive-cihaz .hub-grid .hub-card:nth-child(odd):nth-last-child(2) {
    border-bottom-left-radius: 10px;
  }

  body.edulive-cihaz .hub-grid .hub-card:last-child {
    border-bottom-right-radius: 10px;
  }
}

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz.edulive-web {
    --sekme-h: 0px;
    --sekme-alt: 0px;
  }

  body.edulive-cihaz.edulive-web .wrap {
    padding-bottom: 80px;
  }

  body.edulive-cihaz.edulive-web .student-wrap {
    padding-bottom: 64px;
  }
}


@media (min-width: 641px) and (max-width: 1023px) {

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-filters {
    grid-template-columns: repeat(3, minmax(0, 240px));
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-filters > .au-arama {
    grid-column: 1 / -1;
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-head__actions {
    display: flex;
    flex-wrap: nowrap;
    gap: 10px;
    margin-top: 0;
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-head__actions .au-btn {
    white-space: nowrap;
  }
}

@media (min-width: 421px) and (max-width: 640px) {

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-head {
    display: flex;
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-head__actions {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    margin-top: 0;
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-head__actions .au-btn {
    white-space: nowrap;
    padding-left: 10px;
    padding-right: 10px;
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-filters > .au-arama {
    grid-column: 1 / -1;
  }
}

@media (min-width: 421px) and (max-width: 520px) {

  body.edulive-cihaz.edulive-web .au-page.au-liste-kullanicilar .au-filters {
    grid-template-columns: 1fr;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 30 · ANALİZ MODÜLÜ GÖRSEL NORMALİZASYONU (Tur 34)

   KAPSAM KARARI (Mert, 31 Ağustos): web'e DOKUNULMAYACAK. Mobil ve web aynı
   razor dosyalarını derliyor; razor'a yapılan her düzeltme web'i de değiştirir.
   Bu yüzden analiz modülünün görsel tutarsızlıkları YALNIZ bu katmanda,
   mevcut sınıf adları hedeflenerek düzeltiliyor.

   ⚠ GÜNCELLEME (2 Eylül, merge): bu dosya artık `EduLive.Mobile/wwwroot/css`
   altında DEĞİL, `EduLive.Web/wwwroot/css` altında ve WEB DE YÜKLÜYOR
   (`App.razor:28`). Mobil onu `EduLive.Mobile.csproj:139`'daki
   `$(WebSrc)/wwwroot` altındaki HER ŞEYİ kendi köküne bağlayan kuralla
   alıyor (glob deseni burada YAZILAMAZ: içindeki yıldız-eğik çizgi dizisi bu
   yorumu erken kapatır ve bandın tamamı ayrıştırıcı tarafından düşürülür —
   2 Eylül'de tam olarak bu oldu, Bant 18 sessizce ölmüştü). Yani "web bu dosyayı hiç
   yüklemiyor" gerekçesi ARTIK GEÇERSİZ; web-etkisizlik garantisi tek bir şeye
   dayanıyor: `edulive-cihaz` gövde sınıfını YALNIZ
   `EduLive.Mobile/wwwroot/index.html` ekliyor, `EduLive.Web` hiçbir yerde
   eklemiyor. Bu yüzden aşağıdaki her kuralın `body.edulive-cihaz` öneki
   taşıması artık bir üslup tercihi değil, DOĞRULUK KOŞULUDUR — öneksiz tek bir
   kural web'i anında etkiler.

   ÖLÇÜM (Android emülatör, ÜRETİM verisi — api-gateway.edulive.ai,
   K12 Bilisim Maarif Model Okulu): analiz modülünün 20 rotası gezildi,
   ekran görüntüsü alındı, 6'sı piksel düzeyinde incelendi.

   KÖK NEDEN (keşif): 57 analiz sayfasının 13'ü `AnalizSayfa` kabuğunu
   KULLANMIYOR (AnalizAsistan, AnalizTanimlar, AnalizSinavlar, AnalizItirazlar,
   AnalizExcel, AnalizRaporUrlleri, AnalizHub, AnalizKitapcikAnahtar,
   AnalizMebKazanim, AnalizOptikTxt, AnalizSinavDersleri, AnalizSinavPlanlama,
   AnalizSinavSorulari) — kendi markup'ını yazıyor. Dört sekme dilinin, yedi
   boş-durum tasarımının ve kayıp breadcrumb'ların yapısal sebebi bu.
   CSS bu 13 sayfayı kabuğa SOKAMAZ; yalnız görsel dillerini yaklaştırabilir.

   DENETİMDE GERİ ÇEKİLEN BULGU: "'?' düğmesi içeriğe biniyor" kusur DEĞİL.
   `.ar-ac` 14. bantta (satır 2322) sepet rozetiyle aynı sütuna, aradaki 58 px
   korunarak ölçümle yerleştirilmiş. Üzerine yazmak o istifi bozar — dokunulmadı.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- 18.1 · SAYFA BAŞLIĞINDAKİ ODAK HALKASI --------------------------------
     ÖLÇÜM: 20 rotanın TAMAMINDA `h1.au-title` mavi yuvarlak çerçeve içinde
     görünüyor ("Analiz panosu", "Beceri analizi", "Sınav yönetimi"…).
     Kullanıcı bunu doldurulacak bir girdi kutusu sanıyor.

     KÖK NEDEN: `Routes.razor:17` `<FocusOnNavigate Selector="h1" />` her
     gezinmede başlığa PROGRAMATİK odak veriyor (geçici `tabindex="-1"`).
     `aurora.css:151` küresel kuralı `:focus-visible { outline: 2.5px solid
     var(--brand); outline-offset: 3px; border-radius: 8px }` — WebView bu
     programatik odağı klavye kaynaklı sayıp halkayı çiziyor. Depoda h1 için
     bastırma kuralı YOK (grep: 0).

     NEDEN GÜVENLİ: `h1` etkileşimli bir öğe değil; odak halkası ona bir eylem
     imkânı bildirmiyor. Ekran okuyucular odağı halkadan değil odak olayından
     duyuyor, yani erişilebilirlik kaybı yok. Düğme/bağlantı odağına
     DOKUNULMUYOR — yalnız `h1`. */
  body.edulive-cihaz h1:focus,
  body.edulive-cihaz h1:focus-visible {
    outline: none;
  }

  /* --- 18.2 · ARKA PLANI OLMAYAN DÜĞMELER (afordans) -------------------------
     ÖLÇÜM: /analiz/genel'de BEŞ eylemden yalnız BİRİ düğmeye benziyor.
     "Akademik rapor (PDF)" dolu; "Beceri raporu (PDF)", "Alan becerileri
     raporu (PDF)", "↓ Öğrenci sıralaması (CSV)", "↓ Şube karnesi (CSV)",
     "Sıfırla" düz yazı. /analiz/sinavlar'da beş gezinme bağlantısının hepsi
     aynı durumda.

     KÖK NEDEN (`admin-users.css:66-80`): `.au-btn` tabanında `border: none`
     ve `background` HİÇ TANIMLI DEĞİL. Dolgu yalnız modifier'larda
     (`--primary` :87, `--ghost` :96, `--danger` :107). `RaporSeridi.razor:13-18`
     yalnız `Birincil` olana `--primary` veriyor; kalanlar çıplak `.au-btn`
     (`AnalizGenel.razor:26-27` CSV'ler, `:35` Sıfırla).

     ÇÖZÜM: modifier'sız `.au-btn`e `--ghost` görünümü. Yeni bir dil
     uydurulmuyor — `admin-users.css:96-100`'ün DEĞERLERİ birebir kullanılıyor,
     böylece "ikincil düğme" tek bir görünüme sahip oluyor.

     KAPSAM: kural analiz modülüyle sınırlı DEĞİL; `.au-btn` uygulama genelinde
     (çıplak yüzlerce örnek). Bilinçli: "arka planı olmayan düğme" her ekranda
     aynı afordans kusuru.

     ÖZGÜLLÜK: `body.edulive-cihaz .au-btn:not(...)` = (0,3,1); kapsamlı CSS
     (0,2,0) ve `admin-users.css` (0,1,0) yenilir. `!important` gerekmedi. */
  body.edulive-cihaz .au-btn:not([class*="au-btn--"]) {
    background: var(--glass);
    color: var(--fg-soft);
    border: 1px solid var(--line);
  }

  /* --- 18.3 · <a class="au-btn"> ÜZERİNDE DEVRE DIŞI GÖRÜNÜMÜ ----------------
     ÖLÇÜM: /analiz/sinav-karne'de "↓ Karne (PDF)" devre dışıyken yalnızca
     biraz daha açık mor — devre dışı olduğu anlaşılmıyor.
     KÖK NEDEN: `.au-btn:disabled` tanımlı (`admin-users.css:82-85`,
     `opacity:.55`) ama `<a>` üzerinde `:disabled` sözde-sınıfı ÇALIŞMAZ
     (300 örnek, bkz. 6. bant satır 623). `aria-disabled` için seçici yoktu. */
  body.edulive-cihaz .au-btn[aria-disabled="true"] {
    opacity: .55;
    pointer-events: none;
  }

  /* --- 18.4 · SEKME DİLİ: 5 → 2 (semantik aileye göre) -----------------------
     ÖLÇÜM: modülde BEŞ ayrı "seçili" görünümü var — planda dördü sayılmıştı,
     kod okumasında beşincisi (`.af-seg__b--aktif`) çıktı:

       1 `.amn__sekme--aktif`     glass-strong zemin + brand-strong metin + 650
       2 `.atn-sekme button.aktif` glass zemin + CYAN (`--accent`) iç halka
       3 `.ast-kip__sekme--secili` şeffaf zemin + brand kenarlık (yumuşak)
       4 `.as-sekme--secili`       DOLU `--brand-strong` + `--on-brand`
       5 `.af-seg__b--aktif`       DOLU `--brand` + `--on-brand` + nokta

     PLANDAN SAPMA (gerekçeli): plan "4 → 1" diyordu. Beşincisi bulununca
     bunların TEK dil olmadığı görüldü — iki ayrı BİLEŞEN türü var:

       • GEZİNME SEKMESİ  = "hangi görünümdeyim" (1, 2)  → yumuşak vurgu
       • SEGMENT DENETİMİ = "hangi değeri seçtim" (3, 4, 5) → dolu pilul

     Hepsini tek görünüme indirmek YANLIŞ olurdu: dolu-pilul bir gezinme
     çubuğu ağırlaşır, hayalet bir segment denetimi ise "seçtim" afordansını
     kaybeder. Bu yüzden hedef 5 → 2: her aile KENDİ referansına hizalanır.
     Referanslar zaten en olgun ikisi: `.amn__sekme--aktif` (ortak bileşen) ve
     `.af-seg__b--aktif`.

     ÖZGÜLLÜK: kapsamlı (scoped) CSS son seçiciye `[b-xxxx]` ekler, yani
     `.atn-sekme button.aktif` → (0,3,1). Sınıf sayısı EŞİTLENDİĞİ için üstünlük
     ELEMENT sayısından geliyor: `body.edulive-cihaz .atn-sekme button.aktif`
     = (0,3,2). Diğer üçünde (0,2,1) > (0,2,0) zaten yeterli. */

  /* AİLE 1 — gezinme sekmesi. Cyan halka kaldırılıyor: `--accent` (#06b6d4)
     gerçek bir token ama marka GRADYANLARINA ait; aktiflik rengi olarak
     kullanıldığında aynı modülde iki farklı "aktif" rengi doğuyor. */
  body.edulive-cihaz .atn-sekme button.aktif {
    background: var(--glass-strong);
    color: var(--brand-strong);
    font-weight: 650;
    box-shadow: none;
  }

  /* AİLE 2 — segment denetimi. `.af-seg__b--aktif` referans; diğer ikisi
     ona hizalanıyor. `.as-sekme--secili` yalnız bir ton uzaktaydı
     (`--brand-strong` → `--brand`); `.ast-kip__sekme--secili` ise yumuşak
     kenarlıktan dolu piluluya geçiyor. */
  body.edulive-cihaz .as-sekme--secili,
  body.edulive-cihaz .ast-kip__sekme--secili {
    background: var(--brand);
    color: var(--on-brand);
    border-color: var(--brand);
  }

  /* --- 18.5 · KPI IZGARALARININ SÜRÜKLENMESİ --------------------------------
     ÖLÇÜM: ÜÇ ayrı KPI ızgarası var (planda iki sayılmıştı) —
       `.ap-kpi-grid`  (AnalizPano.razor.css:3)    minmax(160px,1fr) · gap 12
       `.az-kpi-serit` (analiz.css:10)             minmax(158px,1fr) · gap 11
       `.ast-kpi`      (AnalizTarama.razor.css:8)  minmax(158px,1fr) · gap 11
     KÖK NEDEN: `AnalizPano` ve `AnalizTarama` ortak `AnalizKpi` ızgarasını
     kullanmıyor, kendi kaplarını yazmış.

     DÜRÜST DEĞERLENDİRME: telefon genişliğinde `auto-fit` üçünde de 2 sütun
     veriyor; görünür fark yalnız 1 px boşluk. Yani bu tek başına bir
     SÜRÜKLENME temizliği — asıl hizasızlığın sebebi 18.5b'de. `stretch`
     korunuyor: plandaki `align-items:start` kartların alt kenarlarını tırtıklı
     bırakır ve giderilmek istenen hizasızlığı geri getirirdi. */
  body.edulive-cihaz .ap-kpi-grid,
  body.edulive-cihaz .az-kpi-serit,
  body.edulive-cihaz .ast-kpi {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    align-items: stretch;
  }

  /* --- 18.5b · KPI KARTLARININ BASAMAKLANMASININ GERÇEK SEBEBİ --------------
     ÖLÇÜM (/analiz/tarama, üretim verisi): aynı ızgara satırındaki iki kart
     16 px kaymış duruyor —
       kart 1 "TARANACAK SINAV"  top=221  margin-top: 0px
       kart 2 "SEÇİLİ"           top=237  margin-top: 16px
       kart 3 "OKUNMAYAN ÖĞR."   top=336  margin-top: 16px
     Animasyon değil (`animation-name: none`), `transform: none`,
     `align-self: auto`. Fark birebir marjdan geliyor.

     KÖK NEDEN (`admin-users.css:272`): `.au-card + .au-card { margin-top:16px }`
     — DİKEY İSTİF için yazılmış bir kural. Izgara içinde ilk karttan sonraki
     HER kart bitişik kardeştir, dolayısıyla ızgaranın hiç istemediği bir üst
     marj alır; ızgaranın kendi `gap`'i zaten aralığı veriyor. Satır içindeki
     kartlar birbirine göre kayar, satırlar arası boşluk da gap+16 olur.

     `AnalizKpi.razor.css:6-14` yazarı bu belirtiyi 2026-08-22'de görmüş ve
     `height:100%` ile içerik tarafını düzeltmiş ("şerit basamaklanır" yorumu);
     ama kayma içerikten değil DIŞ marjdan geldiği için sürüyordu.

     KAPSAM ÖLÇÜLDÜ (tahmin değil): 5 rotada 6 ızgara kabında 27 kart etkileniyor
     — .ast-kpi, .ast-izgara, .ap-kpi-grid, .az-kpi-serit, .az-izgara.
     Yalnız bu ölçülmüş kaplar hedefleniyor; `.au-card + .au-card` kuralının
     GERÇEKTEN dikey istif olan kullanımlarına dokunulmuyor.

     ÖZGÜLLÜK: (0,4,1) > kaynak kuralın (0,2,0)'ı. */
  body.edulive-cihaz .ast-kpi > .au-card + .au-card,
  body.edulive-cihaz .ast-izgara > .au-card + .au-card,
  body.edulive-cihaz .ap-kpi-grid > .au-card + .au-card,
  body.edulive-cihaz .az-kpi-serit > .au-card + .au-card,
  body.edulive-cihaz .az-izgara > .au-card + .au-card {
    margin-top: 0;
  }

  /* --- 18.6 · FİLTRE GİRDİLERİ FARKLI GENİŞLİKTE -----------------------------
     ÖLÇÜM: /analiz/beceri'nin tarih alanları ile /analiz/genel'inkiler farklı
     genişlikte. KÖK NEDEN: `AnalizBeceri` ORTAK filtreyi kullanıyor
     (`AnalizFiltre.razor:85-94` → `.af-sec`, `min-width:150px`), `AnalizGenel`
     ise kopyalamış (`AnalizGenel.razor:33-34` → `.ag-girdi`, `min-width` YOK).

     ⚠️ İLK DENEMEM REGRESYONDU — ÖLÇÜMLE YAKALANDI. `min-width: 0` + `width:
     100%` yazmıştım ("hücreni doldur"). Emülatörde sonuç: `.af-sec` 150 px'den
     82 px'e, tarih girdileri 72 px ve 52 px'e DÜŞTÜ. Sebep: esnek öğenin
     otomatik asgari boyutu min-content'tir; `min-width: 0` bu tabanı sıfırlar.
     Taban yok olunca ebeveyn `.af-alan` / `.ag-alan` da (kendisi bir esnek öğe)
     min-content'e büzüldü. 52 px'lik bir `<input type="date">` "gg.aa.yyyy"yi
     gösteremez — yani "eşitleme" düzeltmesi alanları kullanılamaz hâle getirdi.

     DOĞRUSU: tabanı KALDIRMAK değil, PAYLAŞTIRMAK. `.af-sec`in zaten sahip
     olduğu 150 px `.ag-girdi`ye de veriliyor — uydurma bir sayı değil, ortak
     filtrenin kendi ölçüsü. `width: 100%` yer varken ikisinin de hücresini
     doldurmasını sağlar; `min-width` ise daralınca sarmalarını. */
  body.edulive-cihaz .af-sec,
  body.edulive-cihaz .ag-girdi {
    box-sizing: border-box;
    width: 100%;
    min-width: 150px;
  }

  /* --- 18.7 · TABLO BAŞLIKLARI "KOPUK GRİ BLOKLAR" ---------------------------
     ÖLÇÜM: /analiz/tarama'da başlık satırı tek bir şerit değil, birbirinden
     kopuk gri kutular dizisi gibi görünüyor.

     KÖK NEDEN (gerçek, tahmin değil): `AnalizTablo.razor.css:38-41`
     `.at-tablo th { background: var(--page-bg) }` yazıyor — ama `--page-bg`
     düz renk DEĞİL, `aurora.css:100`'de bir GRADYAN:
        linear-gradient(135deg, #f8faff 0%, #eef2ff 46%, #f6f3ff 100%)
     Arka plan gradyanı her ögenin KENDİ kutusuna göre çözülür. Yani her `<th>`
     tam gradyanın kendi kopyasını çiziyor; komşu hücreler farklı dilimlerde
     bitip başlıyor ve satır parçalı görünüyor. Sütun ne kadar darsa geçiş o
     kadar sert.

     ÇÖZÜM: düz bir zemin. `--glass-hover` seçildi (%92 opak) çünkü başlık
     `position:sticky` — altından kayan satırlar yarı saydam bir başlıktan
     görünürdü. Paletteki en opak cam tonu bu. */
  body.edulive-cihaz .at-tablo thead {
    background: var(--at-bas-rampa, var(--marka-rampa-serit));
  }
  body.edulive-cihaz .at-tablo:has(thead .at-sabit) thead {
    background: var(--at-bas-zemin, var(--marka-500));
  }
  body.edulive-cihaz .at-tablo thead th {
    background: transparent;
    color: var(--at-bas-metin, var(--on-brand));
  }

  /* --- 18.8 · BOŞ DURUMLAR: YEDİ TİPOGRAFİ, TEK DİL -------------------------
     ÖLÇÜM: yedi ayrı boş-durum bloğu; birincil metin .88 / .9 rem arasında
     salınıyor, ikincil metin kimi yerde .8 kimi yerde .76 rem, üstelik ÜÇÜNDE
     `opacity:.7` zaten soluk gri metnin üzerine biniyor (kontrast kaybı).

     KAPSAM KARARI: yalnız TİPOGRAFİ ve RENK birleştiriliyor; hizalama ve
     yerleşim ellenmiyor. Sebep dürüst: bu yedi durumun hepsine emülatörde
     ulaşmak belirli veri hâlleri gerektiriyor ve göremediğim bir yerleşimi
     değiştirmek doğrulanmamış bir değişiklik olurdu. Farklı yazı boyutu ve
     soluk metin, farklı hizalamadan daha rahatsız edici ve risksiz düzeltilir.

     `.aa-bos` KASTEN dışarıda: o bir "kahraman" boş durumu (marka karosu,
     52vh) ve sohbet ekranının ilk izlenimi — diğerleriyle aynı olması
     gerekmiyor. */
  body.edulive-cihaz .abs__ana,
  body.edulive-cihaz .at-bos__ana,
  body.edulive-cihaz .ag-bos__ana,
  body.edulive-cihaz .az-durum,
  body.edulive-cihaz .au-bos,
  body.edulive-cihaz .ask-bos {
    font-size: .875rem;
    color: var(--fg-soft);
  }

  body.edulive-cihaz .abs__yonerge,
  body.edulive-cihaz .at-bos__neden,
  body.edulive-cihaz .ag-bos__neden,
  body.edulive-cihaz .ask-bos p {
    font-size: .78rem;
    color: var(--muted);
    opacity: 1;
    line-height: 1.4;
  }

  /* Dikey ritim: 14 / 28 / 35 px karışıklığı yerine tek değer.
     YALNIZ dikey: `.au-bos` sola hizalı bir `<p>` ve yatay dolgusu 0 — ona
     yatay dolgu vermek metni kart içindeki komşularından kaydırırdı. Her
     bloğun kendi yatay dolgusu korunuyor. */
  body.edulive-cihaz .az-durum,
  body.edulive-cihaz .au-bos,
  body.edulive-cihaz .ask-bos {
    padding-top: 22px;
    padding-bottom: 22px;
  }

  /* --- 18.9 · BOŞ TABLODA BAŞLIK SATIRI -------------------------------------
     ÖLÇÜM: `AnalizTanimlar`ın 10 tablosunun 4'ünde `<thead>` var, 6'sında yok
     → aynı kartta iki tablo boşken iki farklı görünüm veriyor. Çoğunluğa
     (başlıksız) hizalanıyor: veri yokken sütun adları bilgi taşımıyor.
     `:has()` WebView 151'de destekli.

     ⚠️ Bu kuralın tetiklenmesi boş-durum bloğunun tablonun İÇİNDE (bir `<td>`
     içinde) çizilmesine bağlı; dışında çiziliyorsa seçici hiçbir şeyle
     eşleşmez ve zararsızca ölür. Aşağıda DOM üzerinde doğrulandı. */
  body.edulive-cihaz table:has(.abs, .at-bos) thead {
    display: none;
  }

  /* --- 18.10 · ROZET ≠ DÜĞME (18.2'nin ürettiği yan etkinin kapatılması) -----
     ÖLÇÜM: /analiz/tarama'da "en çok 20 MB" bir `<span class="ast-rozet">` —
     bilgi rozeti, tıklanabilir DEĞİL. Hesaplanmış görünümleri karşılaştırınca:
        rozet : rgba(255,255,255,0.6) | 0.76px rgba(15,23,42,0.07)
        düğme : rgba(255,255,255,0.6) | 0.76px rgba(15,23,42,0.07)   ← BİREBİR
     Sebep `AnalizTarama.razor.css:13`: `.ast-rozet` zemini
     `var(--surface-2, var(--glass))` yazıyor ama `--surface-2` palette TANIMLI
     DEĞİL (aurora.css) → `--glass`e düşüyor; kenarlığı da `--line`. Yani 18.2'de
     çıplak `.au-btn`e hayalet görünüm verince rozetle düğme ayırt edilemez oldu.

     BU YAN ETKİYİ BEN AÇTIM: değişiklikten önce çıplak düğmenin zemini/kenarlığı
     yoktu (asıl kusur oydu), rozetin vardı. Düğmeyi zayıflatmak yanlış olurdu —
     o zaman çıplak düğme, açıkça `--ghost` yazılmış düğmeden ayrışır ve YENİ bir
     tutarsızlık doğardı. Onun yerine ROZET farklılaştırılıyor: kenarlık yok +
     susturulmuş metin = "bilgi"; kenarlık + tam metin rengi = "dokunulabilir".

     `--dikkat` gibi modifier'lı rozetler DIŞARIDA: onların kendi kenarlık rengi
     anlam taşıyor (ölçme kapısı uyarısı), susturmak o sinyali siler. */
  body.edulive-cihaz .ast-rozet:not([class*="ast-rozet--"]) {
    border-color: transparent;
    color: var(--muted);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 31 · ASİSTAN'IN KAYIP GERİ BAĞLANTISI (Tur 34, Faz 4b)

   NEDEN AYRI BANT: 18. bandın sorgusu 1023 px'e kadar uzanıyor, oysa Asistan'ın
   sohbet çekmecesi `AnalizAsistan.razor.css:521`'de YALNIZ `max-width: 900px`
   altında gizleniyor. 18. bandı kullansaydım 901–1023 px arasında hem çekmece
   içindeki asıl bağlantı hem de mobil ikizi görünür olurdu — aynı adı taşıyan
   iki bağlantı ekran okuyucuda tekrardır. Sorgu bilerek kaynağıyla birebir aynı.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {

  /* --- 19.1 · İKİZİ AÇ, ASLINI GİZLE ----------------------------------------
     ÖLÇÜM (/analiz/asistan, üretim verisi): `.aa-geri` var, metni "Analiz",
     `href="/analiz"` — ama sol=-299 px, genişlik 294 px, yani sağ kenarı -5 px:
     tamamen ekran dışında. Ata zinciri tek bir dönüşüm gösteriyor:
         .aa-yan -> matrix(1, 0, 0, 1, -336, 0)      (= 1.05 × min(86vw,320px))
     Dönüşümlü ata, `position:fixed` torunlar için de KUŞATAN BLOK olduğundan
     CSS bu bağlantıyı çekmeceden çıkaramaz; tek yol karşı-dönüşümdü ve o da
     çekmecenin kendi `transition: transform .22s` animasyonuyla çekişirdi.

     Başlık satırına da sığmıyor (ölçüldü): `.aa-ust` 411 px'lik görünümde
     x=49..363 dolu; kalan boşluklar 49 ve 48 px, bağlantı ~70 px istiyor.

     ÇÖZÜM: razor'da kabuğun ÜSTÜNE ikinci bir bağlantı kondu ve bileşenin kendi
     CSS'inde `display:none` yapıldı — web HİÇBİR genişlikte etkilenmez. Burada
     yalnız mobilde açılıyor. Aynı anda iki "Analiz" bağlantısı olmasın diye
     çekmecedeki asıl bağlantı da gizleniyor (çekmece açıkken görünürdü). */
  body.edulive-cihaz .aa-geri-mobil {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    margin: 0 0 var(--aa-geri-bosluk, 8px);
  }

  body.edulive-cihaz .aa-yan .aa-geri {
    display: none;
  }

  /* --- 19.2 · KABUK YÜKSEKLİĞİNİ EKLENEN KADAR KIS --------------------------
     `.aa-kabuk` mobilde `height: calc(100vh - var(--topbar-h) - 28px)`
     (AnalizAsistan.razor.css:522). Üstüne akışta yer kaplayan bir bağlantı
     eklendiği için bu hesap artık görünümü taşırır.

     ÇIKARILAN DEĞER ÖLÇÜLDÜ, tahmin edilmedi: bağlantının kutu yüksekliği 44 px
     (6. bandın dokunma hedefi kuralı `.au-breadcrumb`e de uyguluyor) + 8 px alt
     marj = **52 px** dış yükseklik. İlk yazdığım 30 px'lik tahminle sayfa fazladan
     22 px taşıyordu. 52 ile ölçüm: kabuk 728 → 706 px, alt kenarı 830 px, görünüm
     838 px — kabuk artık görünüme SIĞIYOR ve dikey taşma 76 px, yani bu bandın
     eklenmesinden ÖNCEKİ değerin aynısı: eklenen 52 px ile kısılan 52 px birbirini
     götürüyor, kural taşma açısından NÖTR.
     (O 76 px önceden de vardı: Android WebView'da `100vh` tarayıcı çubuğunun
     arkasını da sayar. Bu bandın konusu değil.) */
  body.edulive-cihaz .aa-kabuk {
    height: calc(100vh - var(--topbar-h) - 28px - var(--aa-geri-yuk, 52px));
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 32 · ANALİZ MODÜLÜ DİKEY RİTMİ (Tur 35)

   ŞİKÂYET (Mert): "ölçekler, aralardaki boşluklar çok sıkışık görünüyor…
   aşırı açmadan, araları toparlı güzel optimal gösterelim."

   ÖLÇÜM (Android emülatör, 411 px, üretim verisi, 6 rota). Sorun SIKIŞIKLIK
   DEĞİL, RİTİMSİZLİK — aynı sayfada yan yana duran kart→kart boşlukları:
       /analiz, /analiz/genel   [10, 10, 16 ×9]
       /analiz/pano             [10, 54, 63, 63]
       /analiz/tarama           [10,  8, 32, 32, 16]
       /analiz/tanimlar         [32, 16]
   Gözlenen tüm değerler: 0, 2, 4, 8, 10, 12, 14, 16, 18, 32, 54, 63.

   ÜÇ KÖK NEDEN, üçü de kaynakta doğrulandı:

   (a) BOŞLUĞUN İKİ SAHİBİ VAR. Kabın `gap`'i ile kartın `margin-bottom`'ı aynı
       aralığı ayrı ayrı üretiyor: `.ast-izgara` gap 16 + kart mb 16 = 32.
       `analiz.css:38` bunu `.azb` için ZATEN çözmüş (`.az-izgara > .azb
       { margin-bottom: 0 }`); bu bant o çözümü ölçülmüş beş ızgara kabına
       genelliyor ve boşluğu TEK sahibe (sonraki kardeşin üst marjı) veriyor.

   (b) CASCADE HATASI — 54/63 px'in gerçek kaynağı. `.au-section-title` İKİ
       dosyada tanımlı: `analiz.css:163` (`margin: 0 0 10px`) ve
       `planlama.css:330` (`margin: 28px 0 12px`, `:first-of-type` 20px).
       `App.razor`da planlama.css (satır 23) analiz.css'ten (satır 20) SONRA
       yükleniyor; özgüllük eşit olduğu için kaynak sırası kazanıyor ve
       analiz.css'in değeri HİÇ uygulanmıyor. Aritmetik birebir tutuyor:
       20 + ~22 (h2 kutusu) + 12 = 54  ·  28 + ~23 + 12 = 63.
       İLK TEŞHİSİM YANLIŞTI: bunu "meşru bölüm yapısı" sayıp geçmiştim.

   (c) İKİ FARKLI ADIM. KPI şeritleri 10, ızgaralar 16, filtre satırı 14.

   ÖLÇEK — dört adım, hepsi 4'ün katı ve hepsi sette ZATEN var:
       4  kart içi satır aralığı        (referans: `.au-title` alt marjı 4)
       8  SIKI GRUP: KPI ızgarası       (referans: `.at-tablo` dikey dolgusu 8)
       12 TEK RİTİM ADIMI: kart→kart    (referans: `.ak-kpi` dikey dolgusu 12)
       16 BÖLÜM SINIRI: yalnız başlık üstü ve boş durum
   12 seçildi çünkü kart sınırını zaten kenarlık + gölge çiziyor
   (`admin-users.css:264`); ayrımı boşluğun taşımasına gerek yok.
   16 ölçülen dağılımın MODU (33 kart→kart boşluğunun 20'si).

   NET ETKİ: altı rotanın HİÇBİRİ uzamıyor, toplam ≈ −280 px. Tek büyüme
   kalemi KPI kart içi 2→4 px; kazanılan yerin kart İÇİNE geri verilmesi.

   SIRA ÖNEMLİ: 20.2 genel ritmi kurar, 20.3/20.4 onu başlık için EZER ve
   özgüllükleri eşittir (0,4,1) — bu yüzden sonra yazılmaları zorunludur.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- 20.1 · BOŞLUĞUN TEK SAHİBİ OLSUN ------------------------------------
     Alt marjlar sıfırlanır; aralığı yalnız 20.2 verir. `.au-page`in 48 px alt
     dolgusu durduğu için sayfa sonunda çöküş olmaz. */
  body.edulive-cihaz .au-page > *,
  body.edulive-cihaz .az-izgara > .au-card,
  body.edulive-cihaz .ast-izgara > .au-card,
  body.edulive-cihaz .atn-izgara > .au-card,
  body.edulive-cihaz .az-kpi-serit > .au-card,
  body.edulive-cihaz .ap-kpi-grid > .au-card,
  body.edulive-cihaz .ast-kpi > .au-card {
    margin-bottom: 0;
  }

  /* ⚠ ÖLÇÜMDE GERİ ALINAN DENEME. /analiz/tanimlar kartları `.au-page`in
     DOĞRUDAN çocuğu değil (`.atn-izgara` ve isimsiz bir `div` içindeler), o
     yüzden ilk yazımda 20.2 oraya hiç uygulanmadı ve ölçülen [32, 16] kaldı.
     Kap adlarını saymak yerine `.au-page .au-card + .au-card` ile HER
     derinlikteki kartı hedeflemeyi denedim: tanimlar'ı düzeltti (-36 px) ama
     DİĞER DÖRT ROTAYI BÜYÜTTÜ (+24…+96 px), çünkü daha önce hiç marjı olmayan
     iç içe kartlara da 12 px ekliyordu. İsimli liste geri alındı ve yalnız
     `.atn-izgara` eklendi. tanimlar'da isimsiz `div` içindeki kartların 16 px'i
     BİLEREK bırakıldı: 16 zaten ölçekte var ve onu kapsamak için gereken genel
     kural dört rotayı bozuyor. */

  /* --- 20.2 · TEK RİTİM ADIMI ----------------------------------------------
     `:not(.amn)` KRİTİK, kozmetik değil: `AnalizModNav.razor.css:6` sekme
     şeridine `margin: calc(8px - var(--akn-alt-bosluk, 20px))` = 411 px'te
     −12 px BİLİNÇLİ negatif çekme veriyor. Dışlanmasaydı breadcrumb'lı her
     sayfada sekme şeridi 24 px aşağı kayardı. `:not()` ayrıca özgüllüğü
     (0,4,1)'e çıkarıp `admin-users.css:272`yi (0,2,0) kaynak sırasından
     bağımsız yener. 18.5b'nin ızgara-içi `margin-top: 0` kuralı YERİNDE KALIR
     (o daha özgül: `.X > .au-card + .au-card`). */
  body.edulive-cihaz .au-page > *:not(.amn) + *:not(.amn) {
    margin-top: 12px;
  }

  /* --- 20.3 · BÖLÜM BAŞLIĞI ÜSTÜ ------------------------------------------
     54/63 px'i 12'ye indirmek İMKÂNSIZ: o boşluğun içinde başlık METNİ var.
     İndirilebilen yalnız 28+12'lik çerçeve. 16 = bölüm sınırı; sayfadaki tek
     "büyük" ayrım burası olsun. */
  body.edulive-cihaz .au-page > .au-section-title:not(.amn) {
    margin-top: 16px;
  }

  /* --- 20.4 · BAŞLIK → KENDİ KARTI (yakınlık) ------------------------------
     16 üst / 8 alt asimetrisi olmadan başlık iki kartın tam ortasında asılı
     kalır ve hangi kartı etiketlediği okunmaz — /analiz/pano'da üç başlığın
     üçünde de ölçülen durum buydu. */
  body.edulive-cihaz .au-page > .au-section-title + *:not(.amn) {
    margin-top: 8px;
  }

  /* --- 20.5 · KPI ŞERİDİ: SIKI GRUP ---------------------------------------
     Ölçeğin tek anlamlı istisnası ve istisna HİYERARŞİ taşıyor: grup içi (8)
     < gruplar arası (12) görünür olur. KPI kartları tek bir okuma birimidir.
     Yan kazanç: 2 sütunlu ızgarada kart başına +1 px genişlik, 411 px'te uzun
     etiketlerin sarma riskini düşürür. 18.5 ile eşit özgüllükte (0,2,1)
     olduğu için bu bandın dosyada SONRA gelmesi gerekir — geliyor. */
  body.edulive-cihaz .az-kpi-serit,
  body.edulive-cihaz .ap-kpi-grid,
  body.edulive-cihaz .ast-kpi {
    gap: 8px;
  }

  /* --- 20.6 · IZGARA GAP'İ = KART→KART -------------------------------------
     411 px'te bu ızgaralar `analiz.css:34` ile ZATEN tek sütuna düşüyor
     (`max-width: 760px` → `1fr`), yani gap saf dikey boşluktur ve fiilen
     kart→kart boşluğudur. Tek sütuna düşmüş ızgara ile üst üste istiflenmiş
     kartlar arasında görsel fark yok; ikisinin de 12 olması kullanıcıyı
     "hangi kap hangisi" bilmek zorunda bırakmaz. */
  body.edulive-cihaz .az-izgara,
  body.edulive-cihaz .ast-izgara,
  body.edulive-cihaz .atn-izgara {
    gap: 12px;
  }

  /* --- 20.7 · KART DİKEY DOLGUSU ------------------------------------------
     İki ayrı kart-dolgu standardı var (14 px'lik 10 sayfa-yerel kopya vs
     `.azb` 18 px). ORTAK bileşenin değeri referans alınıyor:
     `AnalizKpi.razor.css:11` → `padding: 12px 14px`. Uydurma değil, mevcut
     ikisinden DÜŞÜK olanın seçimi; hiçbir kart dikeyde büyümez.
     `padding-block` longhand olduğu için düşük özgüllüklü `padding`
     shorthand'ini ezer.
     ⚠ YATAY DOLGUYA BİLEREK DOKUNULMUYOR: mobilde `.au-page` yatay dolgusu 0,
     yani karttaki 14/16 px sayfanın TEK yatay nefesi. Bu ölçek dikeydir. */
  body.edulive-cihaz .au-page .au-card {
    padding-block: 12px;
  }

  /* --- 20.8 · KPI KART İÇİ (ölçeğin tek büyüme kalemi) ---------------------
     `.ak-kpi__b` (.75rem etiket) ile `.ak-kpi__d` (1.45rem değer) arasındaki
     2 px iki satırı optik olarak tek bloğa yapıştırıyor; KPI'ın taranabilirliği
     tam da bu ayrışmaya bağlı. Maliyet ızgara satırı başına +2 px. */
  body.edulive-cihaz .ak-kpi,
  body.edulive-cihaz .ap-kpi {
    gap: 4px;
  }

  /* --- 20.9 · BOŞ DURUM DİKEY DOLGUSU -------------------------------------
     18. bandın 22 px'i ölçeğe alınıyor (16 = bölüm sınırı).
     ⚠ DENETİMDE ÇÜRÜTÜLEN İDDİA: tasarım incelemesi bu kuralın `!important`
     gerektirdiğini, çünkü `.at-bos`un `padding: 18px !important` olduğunu
     söylüyordu. Kaynakta DOĞRU DEĞİL: `AnalizTablo.razor.css:138` →
     `.at-bos { text-align: center; padding: 1rem .75rem; }` — `!important`
     YOK ve değer zaten 16 px. Normal özgüllük ((0,2,1) > scoped (0,2,0))
     yetiyor; `!important` sayacı 1'de kalıyor. */
  body.edulive-cihaz .at-bos,
  body.edulive-cihaz .abs,
  body.edulive-cihaz .az-durum,
  body.edulive-cihaz .au-bos,
  body.edulive-cihaz .ask-bos {
    padding-block: 16px;
  }
}

@media (hover: none) and (pointer: coarse) {

  body.edulive-cihaz .app-field .app-select {
    min-height: 44px;
  }
}

@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  body.edulive-cihaz:has(.topbar) .status-bar-safe-area {
    background: var(--ust-zemin);
  }




















}

/* ÜST BAR — YENİ DİL: personel kromu, telefon ve tablet. */
@media (max-width: 1023px), (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz:has(.topbar) { --topbar-h: var(--ust-h-genis); }
  body.edulive-cihaz .topbar,
  body.edulive-cihaz:has(.topbar) .status-bar-safe-area { background: var(--ust-zemin); }
  body.edulive-cihaz .topbar {
    height: var(--topbar-h);
    padding: 0 24px;
    gap: 18px;
    border: 0;
    box-shadow: var(--ust-golge);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body.edulive-cihaz .topbar::after { content: none; }
  body.edulive-cihaz .topbar .brand {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    min-width: 44px;
    height: 44px;
    flex: 0 0 44px;
  }
  body.edulive-cihaz .topbar .brand-logo__amblem {
    width: 32px;
    height: 32px;
    filter: var(--ust-amblem-golge);
  }
  body.edulive-cihaz .topbar .top-right { gap: 8px; flex: 0 0 auto; }
  body.edulive-cihaz .topbar .nbell .nbell__btn,
  body.edulive-cihaz .topbar .avatar,
  body.edulive-cihaz .topbar .ubg__btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    min-width: 36px;
    height: 36px;
    min-height: 36px;
    padding: 0;
    border-radius: 11px;
    border: 1px solid var(--ust-cizgi);
    background: var(--ust-cam);
    color: var(--ust-metin);
    transform: none;
    box-shadow: none;
  }
  body.edulive-cihaz .topbar .avatar { background: var(--ust-cam); color: var(--ust-metin); font: 700 14px var(--font-body); }
  body.edulive-cihaz .topbar .avatar::before { content: none; }
  body.edulive-cihaz .topbar .nbell__btn::after,
  body.edulive-cihaz .topbar .avatar::after,
  body.edulive-cihaz .topbar .ubg__btn::after { content: ""; position: absolute; inset: -4px; }
  body.edulive-cihaz .topbar .nbell__btn > svg { width: 18px; height: 18px; }
  body.edulive-cihaz .topbar .nbell .nbell__dot { background: var(--basari); box-shadow: var(--ust-nokta-halka); }
  body.edulive-cihaz .topbar .ubg { position: relative; display: inline-flex; }
  body.edulive-cihaz .topbar .ubg[hidden] { display: none; }
  body.edulive-cihaz .topbar .ubg__btn { width: 52px; gap: 6px; }
  body.edulive-cihaz .topbar .ubg__ad { display: none; }
  body.edulive-cihaz .topbar .pos,
  body.edulive-cihaz .topbar .nbell,
  body.edulive-cihaz .topbar .ubg { --acilir-kayma: calc((var(--topbar-h) - 36px) / 2); }
  body.edulive-cihaz .topbar .kurum-sec,
  body.edulive-cihaz .topbar .ou-switch { display: none; }
  body.edulive-cihaz .as-rozet { top: calc(env(safe-area-inset-top, 0px) + var(--topbar-h) + 150px); }
  body.edulive-cihaz .as-panel { top: calc(env(safe-area-inset-top, 0px) + var(--topbar-h) + 12px); }
  body.edulive-cihaz .as-rozet,
  body.edulive-cihaz .as-perde,
  body.edulive-cihaz .as-panel { --as-ust: calc(env(safe-area-inset-top, 0px) + var(--topbar-h) + var(--akn-yigin, 84px) + var(--amn-govde-ust, 16px)); }
  body.edulive-cihaz .akn,
  body.edulive-cihaz .ap-perde,
  body.edulive-cihaz .ap-pencereler { top: calc(env(safe-area-inset-top, 0px) + var(--topbar-h)); }
}
@media (max-width: 640px) {
  body.edulive-cihaz .topbar { padding-inline: 12px; gap: 8px; }
  body.edulive-cihaz .topbar .ubg__sayfa {
    position: fixed;
    inset: auto 0 0;
    width: auto;
    max-width: none;
    max-height: 76dvh;
    padding-bottom: calc(var(--sekme-h, 0px) + var(--sekme-alt, 0px) + 14px);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BANT 21 · ÖĞRETİM PLANLARI — DOKUNMA HEDEFİ (FAZ P8, 2026-09-17)
   ÖLÇÜM: OgretimPlanlariMobilOlcumTests (bUnit çıktısı + bu CSS zinciri,
   Chromium 360×780 / 412×892, dokunmatik). 9 sayfa tarandı; K2 yatay taşma
   SIFIR, K3'te üç kalıp kaldı — üçü de aşağıda.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1023px),
       (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {

  /* --- 21.1 · Kart moduna dönmüş tablo hücresindeki çıplak bağlantı ---------
     ÖLÇÜM: /ogretim-planlari/{kurs} ızgarası `td.pki-islenen > a` 190x26,
     /ogretim-planlari/yonetim `td > a` (kurs adı) ve karşılaştırma tablosu:
     BANT 14.1b'nin `::after`ı hücreyi kaplıyor ama kart modunda hücre 5+5 px
     dolguyla 36 px — vuruş alanı 306x36, 44'ün altında. (BANT 14.1 42-43 px'lik
     KLASİK satırları ölçmüştü; kart hücresi daha basıktır.)
     KARAR: yalnız bağlantılı hücre 44 px'e yükselir — metin büyümez, satır
     yalnız o hücrede 8 px uzar. Kapsam bu modülün iki tablo ailesi. */
  body.edulive-cihaz .op-tablo tbody td:has(> a:not([class])),
  body.edulive-cihaz .pki-tablo tbody td:has(> a:not([class])) {
    min-height: 44px;
    align-items: center;
  }

  /* --- 21.2 · Takvim düğmesi (AppDatePicker) ---------------------------------
     ÖLÇÜM: /ogretim-planlari/{kurs}/islenme `button.app-date__ac` 36x44
     (AppDatePicker.razor.css:254 dokunmatikte 36 px yazar; yükseklik BANT 2
     tabanından 44). Girdinin sağ dolgusu 42 px, 44 px'lik düğme yazıyı örterdi.
     KARAR: düğme 44x44, girdi sağ dolgusu 50 px. Kapsamlı seçici (0,4,1)'i
     (0,5,1) ile geçer; bileşenin kendi ölçüleri masaüstünde değişmez. */
  body.edulive-cihaz .app-field .app-date-wrap .app-date__ac {
    width: 44px;
    height: 44px;
    right: 1px;
  }

  body.edulive-cihaz .app-field .app-input.app-date[type="date"] {
    padding-right: 50px;
  }
}

@media (min-width: 900px) and (max-width: 1023px) {
  body.edulive-cihaz .topbar .ubg__ad { display: block; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  body.edulive-cihaz .topbar .ubg__btn { width: auto; padding-inline: 10px; }
}
@media (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz .topbar .ubg { display: none; }
  body.edulive-cihaz .topbar .kurum-sec,
  body.edulive-cihaz .topbar .ou-switch { display: inline-flex; --acilir-kayma: calc((var(--topbar-h) - 40px) / 2); }
  body.edulive-cihaz .topbar .topbar-tenant {
    position: relative;
    height: 40px;
    min-height: 40px;
    min-width: 180px;
    max-width: 280px;
    border-radius: 12px;
    background: var(--ust-cam);
    border: 1px solid var(--ust-cizgi);
    color: var(--ust-metin);
    transform: none;
  }
  body.edulive-cihaz .topbar .topbar-tenant::after { content: ""; position: absolute; inset: -2px 0; }
  body.edulive-cihaz .topbar .topbar-tenant__label { display: block; font-size: 11px; line-height: 1; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ust-metin-soluk); opacity: 1; }
  body.edulive-cihaz .topbar .topbar-tenant__name { font-size: 14px; font-weight: 650; line-height: 1.2; max-width: 180px; }
  body.edulive-cihaz .topbar .topbar-tenant__ikon { width: 28px; height: 28px; border-radius: 8px; background: var(--ust-cam-ikon); }
  body.edulive-cihaz .topbar .topbar-tenant__yazi { gap: 2px; padding-left: 9px; border-left: 1px solid var(--ust-ayrac); flex: 1; }
  body.edulive-cihaz .topbar .topbar-tenant__ok { margin-left: auto; }
}

/* ANALİZ GEZİNMESİ — cihaz bandı ve bölüm alt sayfası (B1). */
@media (max-width: 1023px), (min-width: 1024px) and (max-width: 1279px) and (hover: none) and (pointer: coarse) {
  body.edulive-cihaz .akn { top: calc(env(safe-area-inset-top, 0px) + var(--topbar-h)); }
}
@media (max-width: 719px) {
  body.edulive-cihaz .akn--bolum-acik { z-index: 73; }
  body.edulive-cihaz .akn-bolum__sayfa { display: block; z-index: 1; }
  body.edulive-cihaz .akn-bolum__perde {
    display: block; position: fixed; inset: 0; width: 100%; height: 100%; border: 0;
    background: var(--scrim); z-index: 0;
  }
  body.edulive-cihaz .akn-bolum__baslik h2 { margin: 0; color: var(--marka-700); font: 700 16px var(--font-display); }
  body.edulive-cihaz .akn-bolum__oge {
    display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 12px;
    border-left: 3px solid transparent; text-decoration: none; color: var(--fg); font-size: 15px;
  }
  body.edulive-cihaz .akn-bolum__oge--secili {
    border-left-color: var(--basari); color: var(--marka-600); font-weight: 700;
    background: color-mix(in srgb, var(--marka-500) 6%, var(--yuzey));
  }
  body.edulive-cihaz .akn-bolum__oge .akn-bolum__ikon svg { width: 18px; height: 18px; }
  body.edulive-cihaz .akn-bolum__onay { margin-left: auto; }
  body.edulive-cihaz .akn-bolum__oge:focus-visible,
  body.edulive-cihaz .akn-bolum__kapat:focus-visible { outline: 2px solid var(--marka-600); outline-offset: -2px; }
}
@media (prefers-reduced-motion: reduce) {
  body.edulive-cihaz .akn-bolum__sayfa { animation: none; }
}

/* Dar tablet: telefon alt sayfasının 641–719px devamı. */
@media (min-width: 641px) and (max-width: 719px) {
  body.edulive-cihaz .akn-bolum__sayfa {
    display: block; position: fixed; inset: auto 0 0; z-index: 1;
    max-height: 76dvh; overflow-y: auto; overscroll-behavior: contain;
    padding: 20px 16px calc(var(--sekme-h, 0px) + var(--sekme-alt, env(safe-area-inset-bottom, 0px)) + 14px);
    background: var(--yuzey); border-radius: var(--kose-sayfa);
    box-shadow: 0 -18px 44px -16px var(--scrim); animation: cihazAcilirSayfa .2s ease;
  }
  body.edulive-cihaz .akn-bolum__sayfa::before {
    content: ""; display: block; width: 38px; height: 4px; margin: -10px auto 12px;
    background: var(--n-300); border-radius: 2px;
  }
  body.edulive-cihaz .akn-bolum__baslik {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding-bottom: 8px; margin-bottom: 8px; border-bottom: 3px solid var(--basari);
  }
  body.edulive-cihaz .akn-bolum__kapat {
    position: relative; min-width: 44px; height: 36px; padding: 0 10px;
    border: 1px solid var(--hat-girdi); border-radius: var(--kose-dugme);
    background: var(--yuzey); color: var(--marka-600); font: 600 13px var(--font-body); cursor: pointer;
  }
  body.edulive-cihaz .akn-bolum__kapat::after { content: ""; position: absolute; inset: -4px 0; }
}
