@charset "UTF-8";
/* ==========================================================================
   AYDUKE · theme.css
   Tema temeli: tasarım tokenları, reset, tipografi, ortak bileşenler.
   Bu dosya tüm sayfalarda ortaktır. Sayfaya/bölüme özel stiller style.css'e.
   Yükleme sırası: bootstrap.min.css  →  theme.css  →  style.css
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · Tasarım tokenları
   -------------------------------------------------------------------------- */
:root {
    /* Marka — images/ayduke.png logosundan örneklendi */
    --brand:            #011E5A;
    --brand-hover:      #05307F;
    /* markanın hue'sundan (≈220°) türetilmiş vurgu tonu. --brand ile --ink
       neredeyse aynı koyulukta olduğu için metin vurgusu ancak bununla
       okunuyor; lacivertle akraba kalsın diye kasıtlı olarak bastırılmış. */
    --brand-accent:     #1C4AA8;
    --brand-soft:       #F1F4FA;
    --brand-tint:       rgba(1, 30, 90, .06);
    --brand-line:       rgba(1, 30, 90, .18);

    /* --- INSTAGRAM GEÇİŞİ  —  2026-09-25 -------------------------------
       KULLANICI KARARI: "Kullanım Kılavuzu butonunun rengi mavi değil,
       instagram renk tonu gibi geçişli bir instagram renk tonundan olsun."

       ⚠ BU, HERO'DAKİ SVG DEGRADESİNİN İKİZİ DEĞİL, KARDEŞİ. Orada
       (_hero.php → <linearGradient id="ayIg">) Instagram'ın resmî beş
       durağı olduğu gibi duruyor: #FEDA75 · #FA7E1E · #D62976 · #962FBF ·
       #4F5BD5. O ramp bir LOGO DOLGUSU, yani üstünde yazı taşımıyor.

       Burada düğmenin üstünde beyaz metin var ve resmî rampanın iki açık
       durağı onu okunmaz yapıyordu (beyaz/#FEDA75 ≈ 1,6:1 · beyaz/#FA7E1E
       ≈ 2,6:1 — WCAG AA normal metin eşiği 4,5:1). Bu yüzden sarı duraklar
       DÜŞTÜ ve turuncu koyulaştırıldı; kalan üç durak resmî değerlerde
       kaldı. Ölçülen kontrastlar (beyaz metinle):

           #B85210   4,94:1   ✓   (resmî #FA7E1E'in koyulaştırılmışı)
           #D62976   4,73:1   ✓
           #962FBF   6,08:1   ✓
           #4F5BD5   5,54:1   ✓

       Yani düğmenin HER noktasında beyaz yazı AA geçiyor. Resmî rampa
       aynen kullanılsaydı düğmenin ilk üçte biri okunmazdı.

       ⚠ 100deg, 90deg DEĞİL: dikey geçişte tek satırlık bir düğmede üç
       durak 50 pikselin içine sıkışıyor ve geçiş bir "bant" gibi görünüyor.
       Yatayda düğme 216-320 piksel geniş, geçiş yumuşak okunuyor. Açı tam
       yatay da değil — 10 derecelik eğim köşelerde hafif bir hareket
       bırakıyor, degradenin logoyla akraba olduğunu söyleyen şey o.

       RTL'DE AYNALANMIYOR ve bu bilinçli: degrade marka işareti, yön
       taşıyan bir ok ya da hiza değil. Arapça sayfada da Instagram'ın
       renk sırası aynı okunuyor. */
    --ig-grad:          linear-gradient(100deg, #B85210 0%, #D62976 38%, #962FBF 70%, #4F5BD5 100%);
    --ig-grad-hover:    linear-gradient(100deg, #9E460D 0%, #BE2268 38%, #83299F 70%, #414CC0 100%);
    /* Degrade inmezse (eski tarayıcı, forced-colors) altında duran düz
       zemin. Ortadaki durak seçildi: rampanın hem rengi hem kontrastı
       bakımından ortalaması. */
    --ig-solid:         #D62976;
    --ig-solid-hover:   #BE2268;

    /* Metin
       --ink-mute önceden #98A2B3 idi: beyaz üzerinde 2.58:1 kalıyor ve WCAG AA
       eşiğini (normal metin 4.5:1) geçmiyordu. Bu token gerçek metinlerde
       kullanılıyor (eski fiyat, "/ yıl", liste başlıkları, form ipucu, telif,
       yer tutucu), o yüzden tonu koyulaştırıldı: beyazda 4.99:1, --surface-2
       üzerinde 4.77:1, --brand-soft üzerinde 4.53:1 — hepsi eşiğin üstünde.
       Hiyerarşi korunuyor: --ink-soft (7.69:1) hâlâ belirgin biçimde koyu. */
    --ink:              #101828;
    --ink-soft:         #475467;
    --ink-mute:         #667082;
    --on-brand:         #FFFFFF;

    /* Yüzey */
    --surface:          #FFFFFF;
    --surface-2:        #F8FAFC;
    --glass:            rgba(255, 255, 255, .72);
    --glass-strong:     rgba(255, 255, 255, .92);
    --hairline:         rgba(16, 24, 40, .09);

    /* Tipografi */
    --font-sans:        -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
                        "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --fs-sm:            .875rem;
    --fs-base:          .9375rem;
    --fs-lg:            1.0625rem;

    /* Ölçü */
    --h:                92px;   /* header yüksekliği — scroll'da küçülür */
    --control-h:        38px;   /* buton / input ortak yüksekliği */
    --control-h-lg:     50px;

    /* Kimlik ekranlarındaki tek satırlık footer'ın yüksekliği (style.css
       § 18 → .ftr--mini). Token olarak duruyor çünkü iki yerde gerekiyor:
       şeridin kendisine ve kartı dikey ortalayan .auth--orta hesabına
       (§ 23c).
       İkisi elle yazılsa biri değişince diğeri sessizce kayardı. */
    --ftr-mini-h:       4.5rem;

    /* Köşe */
    --r-sm:             8px;
    --r-md:             11px;
    --r-lg:             16px;
    --r-pill:           999px;

    /* Gölge */
    --sh-1:             0 1px 2px rgba(16, 24, 40, .12);
    --sh-2:             0 4px 24px -10px rgba(16, 24, 40, .14);
    --sh-brand:         0 6px 16px -6px rgba(1, 30, 90, .45), var(--sh-1);
    --sh-pop:           0 12px 32px -8px rgba(16, 24, 40, .16),
                        0 2px 6px -2px rgba(16, 24, 40, .08),
                        0 0 0 1px rgba(16, 24, 40, .05);

    /* Hareket */
    --ease:             cubic-bezier(.4, 0, .2, 1);
    --ease-out:         cubic-bezier(.16, 1, .3, 1);
    --t-fast:           .18s;
    --t-base:           .25s;
    --t-slow:           .45s;

    /* Katman sırası */
    --z-float:          1030;   /* sabit WhatsApp düğmesi — header'ın altında */
    --z-header:         1040;
    --z-scrim:          1045;
    --z-drawer:         1050;
    --z-cine:           1060;   /* sinema modu — her şeyin üstünde (style.css § 15d) */
}

/* Scroll'da kompakt header (js/theme.js → html.hdr-compact) */
html.hdr-compact { --h: 82px; }

/* xl altında header hamburger moduna geçer (bkz. style.css § 4) */
@media (max-width: 1199.98px) {
    :root, html.hdr-compact { --h: 80px; }
}

/* --------------------------------------------------------------------------
   2 · Reset & temel
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { -webkit-tap-highlight-color: transparent; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--h) + 16px);
}

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.55;
    color: var(--ink);
    background: var(--surface);
    font-synthesis-weight: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
}

img, svg { vertical-align: middle; }
img { max-width: 100%; }

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 .5em;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.02em;
}

/* 2026-10-01 · border-radius KALDIRILDI: kural odaklanan HER öğenin
   köşesini 8px'e indiriyordu — hap biçimli düğme (.ay-btn, --r-pill)
   odakta köşeli bir kutuya dönüşüyor, 2px aralıklı çerçeveyle birlikte
   "çift kenarlık" gibi görünüyordu (panel/ekip.php boş durum düğmesi,
   tarayıcı Geri ile dönünce odak geri yükleniyor). Çerçeve artık öğenin
   kendi köşesini izliyor. */
:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.ay-btn:focus-visible { outline-offset: 3px; }

/* Metin seçimi marka renginde — varsayılan tarayıcı mavisi sayfanın
   lacivertiyle çakışıyordu */
::selection {
    background: rgba(1, 30, 90, .14);
    color: var(--ink);
}

/* --------------------------------------------------------------------------
   3 · Ortak bileşen: buton  (.ay-btn)
   -------------------------------------------------------------------------- */
.ay-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    height: var(--control-h);
    padding: 0 1.25rem;
    border-radius: var(--r-pill);
    font-size: var(--fs-base);
    font-weight: 600;
    letter-spacing: -.01em;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease),
                color var(--t-base) var(--ease),
                transform .3s var(--ease-out),
                box-shadow .3s var(--ease);
}

.ay-btn:active { transform: translateY(0) scale(.98); }

/* dolu — marka */
.ay-btn--primary {
    background: var(--brand);
    color: var(--on-brand);
    box-shadow: var(--sh-1);
}

.ay-btn--primary:hover,
.ay-btn--primary:focus-visible {
    background: var(--brand-hover);
    color: var(--on-brand);
    transform: translateY(-1px);
    box-shadow: var(--sh-brand);
}

/* çerçeveli / şeffaf */
.ay-btn--ghost {
    border: 1px solid var(--hairline);
    background: rgba(255, 255, 255, .6);
    color: var(--ink);
    font-size: var(--fs-sm);
    letter-spacing: .01em;
}

.ay-btn--ghost:hover,
.ay-btn--ghost:focus-visible,
.ay-btn--ghost[aria-expanded="true"] {
    background: var(--brand-soft);
    border-color: var(--brand-line);
    color: var(--brand);
}

/* boyut / genişlik

   --sm panel içindir: liste satırındaki eylem düğmeleri 38 px'te satırı
   şişiriyor. 32 px hâlâ dokunulabilir sınırın (44 px) ALTINDA görünüyor
   ama düğmenin çevresindeki satır boşluğu dokunma hedefini tamamlıyor;
   mobilde eylemler ayrıca alt satıra geçiyor (style.css § 24e).

   Sınıf _panel.php'de (oturumu kapat) kullanılıyordu ama TANIMSIZDI: düğme
   tam boy basılıyordu, üst şerit olduğundan büyük görünüyordu. */
.ay-btn--sm { height: 32px; padding: 0 .85rem; font-size: var(--fs-sm); }
.ay-btn--lg { height: var(--control-h-lg); font-size: 1rem; }
.ay-btn--block { display: flex; width: 100%; }

/* Dokunmatik: :hover parmağı kaldırdıktan sonra butonun üzerinde kalıyor,
   buton havada asılı ve koyu renkte donuyordu. İmleçsiz aygıtlarda kalkma ve
   hover rengi geri alınıyor; dokunma geri bildirimini :active veriyor.
   :not(:active) şart — yoksa bu kural basma animasyonunu da ezer. */
@media (hover: none) {
    .ay-btn:hover:not(:active) { transform: none; }

    .ay-btn--primary:hover:not(:active) {
        background: var(--brand);
        box-shadow: var(--sh-1);
    }

    .ay-btn--ghost:hover:not(:active) {
        background: rgba(255, 255, 255, .6);
        border-color: var(--hairline);
        color: var(--ink);
    }
}

/* --------------------------------------------------------------------------
   4 · Ortak bileşen: ikon butonu  (.ay-iconbtn)
   -------------------------------------------------------------------------- */
.ay-iconbtn {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--r-md);
    color: var(--brand);
    cursor: pointer;
    transition: background-color var(--t-base) var(--ease);
}

.ay-iconbtn:hover { background: var(--brand-soft); }

/* İkon 18px. Eskiden width/height ile veriliyordu (SVG); Font Awesome ikonu
   bir yazı karakteri olduğu için ölçü font-size'dan geliyor (bkz. § 7b).
   svg seçicisi KALIYOR: hamburger düğmesi üç <i> çizgisiyle çalışıyor ama
   platform marka logoları (_platformlar.php) hâlâ gerçek SVG. */
.ay-iconbtn svg { width: 18px; height: 18px; }
.ay-iconbtn .ay-ico { font-size: 18px; }

/* --------------------------------------------------------------------------
   5 · Ortak bileşen: cam yüzey & popover  (.ay-glass, .ay-pop)
   -------------------------------------------------------------------------- */
.ay-glass {
    background: var(--glass);
    -webkit-backdrop-filter: saturate(185%) blur(20px);
    backdrop-filter: saturate(185%) blur(20px);
}

.ay-pop {
    position: absolute;
    z-index: 10;
    margin: 0;
    padding: .375rem;
    list-style: none;
    background: var(--glass-strong);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-pop);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px) scale(.97);
    transition: opacity var(--t-base) var(--ease),
                transform .32s var(--ease-out),
                visibility var(--t-base) var(--ease);
}

.is-open > .ay-pop {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}

.ay-pop__item {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5625rem .625rem;
    border-radius: var(--r-md);
    font-size: var(--fs-base);
    font-weight: 500;
    letter-spacing: -.01em;
    color: var(--ink);
    transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.ay-pop__item:hover,
.ay-pop__item:focus-visible { background: var(--brand-soft); color: var(--brand); }
.ay-pop__item.is-active { font-weight: 600; color: var(--brand); }

/* --------------------------------------------------------------------------
   6 · Ortak bileşen: segmented control  (.ay-seg)
   -------------------------------------------------------------------------- */
.ay-seg {
    display: flex;
    gap: 3px;
    padding: 3px;
    border-radius: 12px;
    background: var(--brand-tint);
}

.ay-seg > * {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--control-h);
    border-radius: 9px;
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--ink-soft);
    cursor: pointer;
    transition: background-color var(--t-base) var(--ease),
                color var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease);
}

.ay-seg > .is-active {
    background: var(--surface);
    color: var(--brand);
    box-shadow: 0 1px 3px rgba(16, 24, 40, .12);
}

/* --------------------------------------------------------------------------
   7 · Ortak bileşen: rozet & chevron  (.ay-badge, .ay-chev)
   -------------------------------------------------------------------------- */
.ay-badge {
    flex: 0 0 auto;
    min-width: 30px;
    padding: .1875rem .25rem;
    border-radius: 6px;
    background: var(--brand-tint);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-align: center;
    color: var(--brand);
}

.ay-chev {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-right: 1.75px solid rgba(16, 24, 40, .28);
    border-bottom: 1.75px solid rgba(16, 24, 40, .28);
    transform: rotate(-45deg);
    transition: transform .3s var(--ease-out);
}

/* --------------------------------------------------------------------------
   7b · Ortak bileşen: İKON  (.ay-ico)

   Projedeki bütün ikonların taşıyıcısı. Etiketi PHP üretiyor
   (_ikon.php → ay_ikon), bu kural da ölçü/hizalama sözleşmesini kuruyor:

       <i class="ay-ico fa-solid fa-gauge-high" aria-hidden="true"></i>

   ⚠ İKON ARTIK BİR YAZI KARAKTERİ, ÇİZİM DEĞİL. Eskiden her ikon satır içi
   bir <svg>'ydi ve boyutu width/height ile veriliyordu. Font Awesome ikonu
   ::before içeriği olarak basılıyor, yani BOYUTU font-size BELİRLİYOR.
   Bağlama özel kuralların hepsi bu yüzden font-size yazıyor; width/height
   yazan eski kurallar bir şey yapmaz (FA'nın kendi genişliği --fa-width
   üzerinden gelir).

   --------------------------------------------------------------------------
   NEDEN BU KURAL ÜÇ SATIRDAN FAZLA DEĞİL

   FA'nın kendi taban kuralı zaten display:inline-block, line-height:1,
   text-align:center ve font-style:normal veriyor. Burada yalnızca FA'nın
   BİLMEDİĞİ üç şey ekleniyor:

     flex        İkonların çoğu flex bir satırın içinde (düğme, menü öğesi,
                 iletişim satırı). Kap daraldığında flex öğeleri küçülür ve
                 ikon eziliyordu — özellikle uzun etiketli menü satırlarında.
                 Eski SVG'ler bunu her yerde ayrı ayrı çözüyordu.

     font-size   inherit DEĞİL, 1em değil: hiç yazılmıyor. Yazılsaydı bağlama
                 özel kurallar (.pnl__ikon, .ftr__ico .ay-ico …) aynı
                 özgüllükte çakışırdı. Varsayılan zaten kalıtım.

     vertical-align
                 FA glifleri taban çizgisinin biraz üstünde oturuyor; metnin
                 içinde AKAN ikonlar (güven satırı, "TAX:" satırı) bu yüzden
                 yüksek görünüyordu. -.1em optik düzeltme.
                 ⚠ Flex kaplarda bu özellik yok sayılır — orada hizayı
                 align-items yapıyor, yani kural iki durumda da doğru.

   --------------------------------------------------------------------------
   GENİŞLİK: FA 7'DE SABİT GENİŞLİK VARSAYILAN

   FA 6'da ikon kutusu glifin kendi genişliğindeydi ve hizalamak için
   'fa-fw' eklenirdi. FA 7'de varsayılan width: var(--fa-width, 1.25em),
   yani HER ikon aynı genişlikte. Menülerde ve alt alta dizilen listelerde
   istediğimiz tam bu: metinler aynı sol kenardan başlıyor.

   Değiştirilmedi çünkü daraltmanın bedeli var: 1em'e indirildiğinde
   yataya geniş gliflerde (fa-users, fa-comments) çizim kutusunun dışına
   taşıyor ve komşu metne yaklaşıyor.

   Dar kutu gereken tek durum metnin İÇİNDE akan ikon — orada 1.25em'lik
   kutu kelimeler arasında fazla boşluk bırakıyor. .ay-ico--dar onun için.
   -------------------------------------------------------------------------- */
.ay-ico {
    flex: 0 0 auto;
    vertical-align: -.1em;
}

/* Metnin içinde akan ikon: kutu glifin genişliğine iniyor.
   ⚠ 'fa-width-auto' (FA'nın kendi sınıfı) yerine kendi sınıfımız
   kullanılıyor: FA'dan SONRA yüklendiğimiz için aynı özgüllükteki iki
   kuralda bizimki kazanıyor, yani FA'nın sınıfını yazan biri sessizce
   ezilirdi. Tek sözlük daha güvenli. */
.ay-ico--dar { --fa-width: auto; }

/* --------------------------------------------------------------------------
   8 · Ortak bileşen: kart  (.ay-card)

   Hero ile footer arasındaki bölümlerin taşıyıcısı: özellik kartları,
   adım kartları, paket kartları ve SSS satırları aynı yüzeyi kullanır.
   Böylece köşe yarıçapı, çerçeve, hover davranışı tek yerden yönetiliyor.

   Durağan hâli sakin: beyaz zemin + tek hairline, gölge yok. Gölge, üst
   kenardaki marka çizgisi ve 2px kalkma yalnızca hover/focus'ta geliyor —
   sayfa dururken gürültü yapmıyor, imleç değdiğinde canlanıyor.

   Varyantlar:
     .ay-card--flush  dolgusuz (dolguyu bölüm kendi verir, örn. SSS satırı)
     .ay-card--brand  marka çerçevesi + hafif lacivert parıltı (öne çıkan)
   -------------------------------------------------------------------------- */
.ay-card {
    /* dolgu değişkende: kartın içindeki öğeler (örn. adım bağlantı hattı)
       kenara göre hizalanabilsin */
    --card-pad: clamp(1.25rem, 2.2vw, 1.75rem);

    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: var(--card-pad);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    background: var(--surface);
    transition: border-color var(--t-base) var(--ease),
                box-shadow .32s var(--ease),
                transform .32s var(--ease-out);
}

/* Not: kartların üst kenarında hover'da açılan marka çizgisi KALDIRILDI.
   Hover geri bildirimi artık yalnızca çerçeve rengi, gölge ve 2px kalkma —
   sakin ve tek katman. */

/* Kalkma (transform) yalnızca gerçek imleçli aygıtlarda: dokunmatikte
   :hover tıklamadan sonra üzerinde kalıyor ve kart havada asılı duruyordu.
   @media (hover: hover) bu durumu tamamen kapatıyor. */
@media (hover: hover) and (pointer: fine) {
    .ay-card:hover {
        border-color: var(--brand-line);
        /* --sh-2 kalkan kart için fazla yumuşaktı: kart 2px yükseliyor ama
           gölge yerinde duruyor gibi görünüyordu. Aşağı doğru daha uzun,
           yayvan bir gölge kalkmayı okunur kılıyor. */
        box-shadow: 0 18px 34px -18px rgba(16, 24, 40, .24),
                    0 2px 6px -3px rgba(16, 24, 40, .08);
        transform: translateY(-2px);
    }
}

/* Klavye/odak geri bildirimi: çerçeve ve gölge var, KALKMA YOK. Form kartında
   alandan alana geçerken kartın 2px zıplaması yazmayı rahatsız ediyordu. */
.ay-card:focus-within {
    border-color: var(--brand-line);
    box-shadow: var(--sh-2);
}

.ay-card--flush { padding: 0; }

.ay-card--brand {
    border-color: var(--brand);
    box-shadow: 0 26px 52px -30px rgba(1, 30, 90, .40);
}

.ay-card--brand:hover { border-color: var(--brand); }

/* --------------------------------------------------------------------------
   9 · Ortak bileşen: form alanları  (.ay-field, .ay-input, .ay-alert)

   İletişim formu ile başlıyor, giriş/kayıt ekranlarında da aynı alanlar
   kullanılacak. Ölçüler --control-h-lg token'ına bağlı, böylece butonlarla
   aynı yükseklikte kalıyorlar.

   Odak halkası :focus ile veriliyor (:focus-visible değil): metin alanına
   imleçle girildiğinde de sınırın belirmesi gerekiyor.
   -------------------------------------------------------------------------- */
.ay-field {
    display: flex;
    flex-direction: column;
    gap: .375rem;
    min-width: 0;
    margin: 0;
}

/* --------------------------------------------------------------------------
   Alanlar arasındaki DİKEY boşluk .ay-field'ın işi değil

   `margin: 0` bilinçli: bileşen kendi dış boşluğunu taşımıyor, onu KAPSAYICI
   veriyor (iletişim formunda .cnt__form'un grid gap'i). Ama Bootstrap ızgarası
   boşluğu NEGATİF margin ile kuruyor:

       .row       { margin-top: calc(-1 * var(--bs-gutter-y)) }   → g-3'te -1rem
       .row > *   { margin-top: var(--bs-gutter-y) }              → g-3'te +1rem

   İkisi birbirini götürüyor. `.ay-field { margin: 0 }` ise çocuğun +1rem'ini
   EZİYORDU: iki seçici de 0,1,0 özgüllükte ve theme.css bootstrap'tan sonra
   yüklendiği için sonraki kazanıyor. Satırın kendi -1rem'i yerinde kalıyor,
   karşılığı gitmiş oluyordu.

   Görünen sonuç kayıt formundaydı (panel/kayit.php): .ay-field içeren her
   .row 16px yukarı kayıyor, "Telefon" ve "Şifre" etiketleri bir üstteki
   alanın içine biniyordu — ölçülen çakışma 4 alanda 16px.

   Özgüllük 0,2,0 olduğu için .ay-field'ı geçiyor; kural yalnızca ızgara
   çocuğu olan alanlara bakıyor, tek başına duran .ay-field'a dokunmuyor.
   -------------------------------------------------------------------------- */
.row > .ay-field,
.row > .ay-check { margin-top: var(--bs-gutter-y); }

.ay-label {
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--ink);
}

/* Etiketin İÇİNDEKİ İKİNCİL NOT: "(isteğe bağlı)", "(en fazla 25 MB; jpg,
   png, webp, gif, mp4)".

   ⚠ ÖLÇÜ EKSİKTİ — 2026-09-25 (kullanıcı: medya.php'nin "görünüm orantı
     sorunlarını gider"). Kural yalnızca AĞIRLIK ve RENK veriyordu; font-size
     yazılmadığı için not, annotasyonu olduğu etiketle AYNI 14 pikselde
     basılıyordu. İki ton (600 → 500) ve soluk renk 14 pikselde hiyerarşi
     kurmaya yetmiyor.

     En keskin göründüğü yer panel/medya.php'nin yükleme etiketi, çünkü not
     etiketten UZUN:

         "Görsel ya da video seçin"                    24 karakter
         "(en fazla 25 MB; jpg, png, webp, gif, mp4)"  42 karakter

     ÖLÇÜLDÜ (Chrome): etiket 163,04px · not 269,97px → not, ait olduğu
     etiketin 1,66 KATI genişlikte. Yani alanın adı, parantez içindeki teknik
     notun yanında ikincil görünüyordu — hiyerarşi tam TERSİNE dönmüştü. Ekran
     görüntüsünde iki metin tek bir uzun cümle gibi okunuyor.

     .75rem sonrası: not 235,98px, oran 1,45×. Oran 1'in altına İNMİYOR ve
     inmesi de beklenmemeli — not basitçe uzun (42 karaktere karşı 24). Amaç
     notu kısaltmak değil, PUNTO BASAMAĞI kurmak: 14 → 12 artık ilk bakışta
     hangisinin başlık hangisinin dipnot olduğunu söylüyor.

     Not uzadıkça kusur büyüyor: sınır 2 MB'dan kotaya bağlandığı için metin
     artık "25 MB" yerine "1 GB" / "2,3 GB" da yazabiliyor, ama uzunluğu
     belirleyen tür listesi sabit ve uzun.

   .75rem, panelde ikincil metnin zaten kullandığı basamak (style.css:
   .mdy__alt, .mdy__sil ve sekiz yer daha). --fs-xs token'ı YOK: token seti
   üç ölçü tutuyor (sm/base/lg) ve bu punto uygulamada literal olarak yazılı —
   aynı gerekçe .mdy__alt'ta da duruyor, dördüncü bir token açmak için tek
   kullanım yeterli değil.

   ⚠ WCAG: 12 piksel ALT SINIRDA. Kabul edilebilir olmasının sebebi notun
     TEKRAR OLMAMASI değil, TAMAMLAYICI olması — asıl sınır her hâlde
     sunucuda ve aşılırsa hata mesajı tam puntoda basılıyor (mdy.err.kota).
     Renk kontrastı değişmedi ve HESAPLANDI: --ink-mute #667082, --surface
     #FFFFFF üstünde 4,99:1 — normal metin için AA eşiği 4.5:1, geçiyor
     (AAA 7:1 değil). Daha küçüğe (11px) inilmedi.

   13 ETİKETİ BİRDEN ETKİLİYOR (tarandı): agent.php ×3, agent-bilgi.php ×2,
   gonderi.php ×3, kayit.php ×2, ayarlar.php, _iletisim.php, medya.php.
   Hepsi aynı rolde — "isteğe bağlı" ya da alanın notu. Birincil içerik taşıyan
   tek bir span yok, o yüzden kural bileşen katmanında kaldı, ekrana
   özelleştirilmedi. */
.ay-label span {
    font-size: .75rem;
    font-weight: 500;
    color: var(--ink-mute);
}

/* 2026-10-01 · .ay-select ve .ay-textarea da TEMEL kutuyu alıyor. İkisi
   değiştirici olarak yazılmıştı (class="ay-input ay-select"); tek başına
   class="ay-select" yazılan liste (panel/ekip.php → Rol) kutusuz kalıp
   tarayıcının ince siyah çerçeveli, köşeli, kısa kontrolüne düşüyordu. */
.ay-input,
.ay-select,
.ay-textarea {
    width: 100%;
    height: var(--control-h-lg);
    padding: 0 .875rem;
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    background: var(--surface);
    font: inherit;
    font-size: var(--fs-base);
    color: var(--ink);
    transition: border-color var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease);
}

.ay-input::placeholder,
.ay-textarea::placeholder { color: var(--ink-mute); }

.ay-input:hover,
.ay-select:hover,
.ay-textarea:hover { border-color: var(--brand-line); }

.ay-input:focus,
.ay-select:focus,
.ay-textarea:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(1, 30, 90, .12);
}

/* Odak halkası box-shadow ile veriliyor; genel :focus-visible çerçevesi
   (§ 2) üstüne binince alanın etrafında iki halka oluşuyordu. Alanlarda
   dıştaki kapatılıyor — görünürlük kalın halkayla korunuyor. */
.ay-input:focus,
.ay-input:focus-visible,
.ay-select:focus,
.ay-select:focus-visible,
.ay-textarea:focus,
.ay-textarea:focus-visible { outline: none; }

/* çok satırlı alan: yükseklik sabit değil, dikeyde büyütülebilir */
.ay-textarea {
    height: auto;
    min-height: 132px;
    padding: .75rem .875rem;
    line-height: 1.6;
    resize: vertical;
}

/* açılır liste: yerleşik ok yerine marka renginde chevron (data URI) */
.ay-select {
    -webkit-appearance: none;
       -moz-appearance: none;
            appearance: none;
    padding-inline-end: 2.25rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' stroke='%23011E5A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .875rem center;
    cursor: pointer;
}
/* RTL: dolgu mantıksal (padding-inline-end → solda) ama ok fiziksel olarak
   sağdaydı; Arapçada ok metnin ÜSTÜNE biniyordu ve boşluk karşı tarafta
   kalıyordu (2026-09-27, panel/agent.php'de ölçüldü). */
[dir="rtl"] .ay-select { background-position: left .875rem center; }

/* --------------------------------------------------------------------------
   DOSYA SEÇME ALANI  —  2026-09-25 (kullanıcı: medya.php'nin "tasarım &
   style sorunlarını gider")

   ⚠ NE VARDI: hiçbir şey. <input type="file"> yalnızca .ay-input alıyordu,
   yani ürünün kutusunu (50px yükseklik, --r-md köşe, beyaz zemin) ama
   İÇİNDEKİ KONTROLÜ İŞLETİM SİSTEMİ ÇİZİYORDU. Ölçüldü (Chrome/macOS,
   ::file-selector-button'ın hesaplanmış değerleri):

       zemin   rgb(239, 239, 239)     gri
       çerçeve 2px OUTSET             90'ların kabartmalı kenarı
       köşe    0px                    ürünün her köşesi yuvarlak
       imleç   default                tıklanabilir görünmüyor
       yazı    15px, ağırlık normal

   Yani ürünün kendi --r-md köşeli beyaz kutusunun içinde kare köşeli,
   kabartmalı, gri bir sistem düğmesi duruyordu; yanında da "Dosya
   seçilmedi" sistem metni. Kullanıcı ekran görüntüsünde tam bunu
   işaretledi.

   İKİNCİ ÖLÇÜLEN KUSUR: alan 939 piksel genişken kontrol ~200 piksel
   kullanıyordu, yani 740 piksel ölü alan — ve alanın kendi imleci
   'default' olduğu için o 740 pikselin tıklanabilir olduğu (tıklanıyor:
   input'un her yeri dosya penceresini açar) hiçbir şekilde
   anlaşılmıyordu.

   ⚠ ÖZEL BİR "SÜRÜKLE-BIRAK" BİLEŞENİ YAZILMADI. O, JavaScript demek ve
   panelde <script> yok (aynı kısıt style.css § 24f'de de yazılı). Burada
   yapılan tek şey YERLEŞİK kontrolü ürünün diline çevirmek: düğme
   .ay-btn--ghost'un görünümünü alıyor, kutu da tıklanabilir olduğunu
   imleçle söylüyor. Davranış değişmiyor — aynı <input>, aynı 'multiple',
   aynı 'accept', aynı sunucu denetimi (config/medya.php).

   KULLANILDIĞI YERLER: panel/medya.php (kütüphaneye yükleme) ve
   panel/gonderi.php (gönderi yazarken satır içi yükleme). Kural bileşen
   katmanında (§ 9), ekranın kendi bölümünde DEĞİL: iki ekranın dosya
   alanı farklı görünmesin.
   -------------------------------------------------------------------------- */
.ay-input[type="file"] {
    /* ⚠ BU İKİSİ ORTALAMAYI YAPMIYOR — ÖLÇÜLDÜ, 2026-09-25 (kullanıcı:
       "input içindeki dosyaları seç kartı yükseklik olarak da ortalı ve
       orantılı olsun").

       ESKİ YORUM BURADA YANLIŞ BİR ŞEY SÖYLÜYORDU: "Flex satırı düğme +
       'dosya seçilmedi' metnini birlikte dikeyde ortalıyor." Ortalamıyordu.
       Chrome'da basılı piksel taranarak ölçüldü (aşağıdaki § ORTALAMA):
       düğme kutunun TEPESİNE YAPIŞIKTI — üstte 0px, altta 14px.

       Niye fark edilmemiş: getComputedStyle sözde öğenin YÜKSEKLİĞİNİ veriyor
       ama KONUMUNU vermiyor, getBoundingClientRect ise gölge DOM sözde
       öğesinde hiç çalışmıyor. Aradaki boşluk "(kutu − çerçeve − düğme) / 2"
       diye HESAPLANMIŞTI ve o formül ortalanmış olduğunu baştan varsayıyor.

       align-items YOK SAYILIYOR, çünkü Chrome file input'un gölge içeriğini
       flex öğesi olarak YERLEŞTİRMİYOR. İki bağımsız kanıt: (1) sözde öğeye
       'align-self: center' verildi, hiçbir şey değişmedi; (2) kural
       'display: block' yapıldı, ölçüm birebir AYNI çıktı.

       ⚠ NİYE SİLİNMEDİ. Chrome'da kanıtlanmış bir NO-OP, ama davranışı
         ölçemediğim motorlar var (Firefox, Safari — bu makinede sınanamadı)
         ve orada gölge içeriği gerçekten flex öğesi olabilir. Durması
         zararsız; ORTALAMA ARTIK BUNLARA BAĞLI DEĞİL, aşağıdaki dolgudan
         geliyor ve dolgu her motorda uygulanıyor. Başka bir motorda da
         no-op olduğu ölçülürse bu iki satır silinebilir. */
    display: flex;
    align-items: center;

    /* --------------------------------------------------------------------
       § ORTALAMA — DOLGUDAN, TÜRETİLEREK

       Düğmenin dikey boşluğu SABİT YAZILMIYOR, kutu yüksekliği ile düğme
       yüksekliğinden HESAPLANIYOR:

           dolgu = (kutu − çerçeveler − düğme) / 2
                 = (50 − 2 − 32) / 2  =  8px

       Sabit '8px' yazmak, iki değerden birinin değiştiği gün ortalamayı
       sessizce bozardı — kusurun ilk hâli tam olarak böyle bir sessiz
       kaymaydı. Türetme SINANDI: değişken 40px'e çekildiğinde boşluk
       kendiliğinden 4/4, kutu 64px'e çekildiğinde 15/15 oldu. Yani
       ortalama artık bir sayının doğru yazılmasına bağlı değil.

       ÖLÇÜLEN SONUÇ: üst 8px · alt 8px · fark 0 → ortalı.

       ⚠ '2px' çerçevelerin toplamı (.ay-input → border: 1px). Tek elle
         yazılan sayı bu; kenar kalınlığı token değil, o kuralda literal.

       DÜĞME 34px DEĞİL 32px — "orantılı" isteğinin karşılığı. 34 keyfi bir
       sayıydı (önceki tur onu yalnızca "38 olmasın" diye seçmiş). 32,
       ürünün KÜÇÜK DÜĞME ölçüsü (.ay-btn--sm, § 3) — yani sistemde zaten
       var olan bir basamak, uydurulmuş bir değer değil. Yan kazanç:
       dikey iç boşluk 7 → 8 pikselle yataydaki 12 piksellik dolguya
       yaklaşıyor, iç içe iki kutunun boşlukları daha eşit okunuyor.
       Düğme / iç kutu oranı %70,8 → %66,7.

       Üç oran basılıp gözle karşılaştırıldı (34/7 · 32/8 · 30/9): 34 kutuyu
       fazla dolduruyor, 30 kutunun içinde yüzüyor.
       -------------------------------------------------------------------- */
    --dosya-dugme-h: 32px;
    padding-block: calc((var(--control-h-lg) - 2px - var(--dosya-dugme-h)) / 2);
    /* KUTU İÇERİĞİYLE ORANTILI  —  2026-09-25 (kullanıcı: "görünüm orantı
       sorunlarını gider")

       ⚠ BU, YUKARIDA "İKİNCİ ÖLÇÜLEN KUSUR" DİYE YAZILIP YARIM BIRAKILAN
         ŞEYİN KALAN YARISI. O not alanın 939 piksel genişken kontrolün ~200
         piksel kullandığını, yani 740 piksel ölü alan olduğunu tespit etmiş;
         ama çözüm olarak yalnızca `cursor: pointer` eklenmiş — yani ölü alanın
         TIKLANABİLİR OLDUĞU söylenmiş, ölü alanın KENDİSİ kaldırılmamış.
         Ekran görüntüsünde kalan tam bu: içeriği solda kümelenmiş, kartın
         sonuna kadar uzanan boş bir kutu.

       İÇERİĞİN GERÇEKTE İSTEDİĞİ GENİŞLİK — ÖLÇÜLDÜ (Chrome, kartın iç
       genişliği 938,81px; önceki notun kaydettiği 939 ile aynı zemin):

           ::file-selector-button  121,46px   (ölçülen, hesaplanan değil)
           margin-inline-end         12px
           "Dosya seçilmedi"       ~104,7px   (aynı puntoda kanvasla ölçüldü)
           kutu dolgusu + çerçeve    26px     (2×.75rem + 2×1px)
           --------------------------------
                                   ~264px

       938,81 piksellik kutuda 674,65 piksel boş. Oran 3,55:1 — kutu,
       içeriğinin üç buçuk katı. Diğer alanlarda (ad, e-posta) tam genişlik
       DOĞRU, çünkü içerik kutuyu dolduruyor; burada içerik sabit ve kısa.

       30rem = 480px. Ölçülen sonuç: kontrolden sonra metne 320,53 piksel,
       yani 14 pikselde ~46 karakter kalıyor; ölü alan 674,65 → 215,83
       piksele iniyor.

       ⚠ NİYE İÇERİĞE TAM OTURTMADIM (≈17rem, "Dosya seçilmedi" kadar). İki
         sebep. (1) Dosya adı bir ONAY: kullanıcı doğru dosyayı seçtiğini
         oradan görüyor, o yüzden kutuda adın okunacağı yer AYRILIYOR —
         boş hâlde "fazla" görünen 216 piksel tam olarak o. (2) width:
         fit-content denenmedi çünkü kutu seçim anında genişlerdi: yerleşim
         kayması (CLS), panelde kaçınılan şey (aynı gerekçe medya
         ızgarasında width/height verilmesinde yazılı).

       ⚠ UZUN AD KIRPILMIYOR, ORTADAN KISALIYOR — ÖLÇÜLDÜ. 53 karakterlik bir
         ad (377,8px) 341,63 piksellik yere sığmıyor, ama Chrome file input'un
         metnini ORTADAN üç noktayla kısaltıyor:
         "2026-09-25-instagram-…ya-gorseli-son-hali-v3.jpg" — yani hem ad
         başı hem UZANTI okunur kalıyor. Kaba bir kesme olacağı varsayımıyla
         daha geniş bir sınır seçilecekti; tarayıcıda bakılınca gerek kalmadı.

       ⚠ width DEĞİL max-width. Dar ekranda kutu yine kolonu dolduruyor ve
         ayrıca bir taşıyıcı sorgu (media query) gerekmiyor. Aynı karar
         panelde zaten üç yerde verilmiş (style.css: .ajn__sayi 8rem,
         .ajn__orta 22rem, .ajn__grup 34rem) — yeni bir kalıp icat edilmedi,
         dördüncü ölçü o sıraya eklendi.

       BİLEŞEN KATMANINDA, EKRANDA DEĞİL: kural iki ekranı birden düzeltiyor
       (panel/medya.php ve panel/gonderi.php). Bu dosyanın başındaki
       "iki ekranın dosya alanı farklı görünmesin" kararının devamı —
       .mdy__form'a yazılsaydı gönderi ekranındaki alan tam genişlikte kalırdı.

       ÇAKIŞMA YOK: .mdy__form .ay-field { width: 100% } alanın SARMALAYICISINI
       tam genişlikte tutuyor, bu sınır İÇ KONTROLE ait. Etiket ve notu satırın
       tamamını kullanmaya devam ediyor, yalnızca kutu daralıyor. */
    max-width: 30rem;
    /* Dolgu daralıyor: düğmenin kendi dolgusu var, ikisi üst üste binince
       kutunun solunda 14+12 = 26 piksel boşluk kalıyordu.

       ⚠ 'padding' DEĞİL 'padding-inline'. Kısa yazım (padding: 0 .75rem)
         dikey değeri de 0'a çekiyor ve YUKARIDAKİ padding-block'u ezerdi —
         sıralama gereği sessizce, çünkü bu bildirim sonra geliyor. Ortalama
         dikey dolguyla kurulduğu için iki eksen ayrı ayrı yazılıyor. */
    padding-inline: .75rem;
    /* "Dosya seçilmedi" alanın KENDİ metni: --ink yerine soluk ton, çünkü
       bir yer tutucu (::placeholder ile aynı rol, aynı renk). */
    color: var(--ink-mute);
    font-size: var(--fs-sm);
    /* Kutunun her yeri dosya penceresini açıyor; imleç de onu söylüyor. */
    cursor: pointer;
}

/* DÜĞME ÜRÜNÜN İKİNCİL DÜĞMESİ GİBİ.

   Değerler .ay-btn--ghost'tan (§ 7) alındı ama kopyalanmadı: seçicinin
   içine .ay-btn yazılamıyor (gölge DOM'da bir sınıf yok), o yüzden aynı
   üçlü — marka çizgisi + marka yazısı + hafif marka zemini — burada
   yeniden veriliyor. Ölçü --control-h (38px) DEĞİL 34px: kutu 50 piksel ve
   38 piksellik bir düğme çerçeveye 6 piksel kalıyor, yani kutunun içinde
   sıkışmış görünüyor.

   ⚠ appearance: none ŞART. Yalnızca zemin/çerçeve verilse macOS'ta outset
   kenar ve kabartma gölgesi ÜSTTE kalıyor; sıfırlanmadan biçim tutmuyor. */
.ay-input[type="file"]::file-selector-button {
    -webkit-appearance: none;
            appearance: none;
    /* Yükseklik kutunun dikey dolgusuyla AYNI değişkenden okunuyor: ikisi bir
       arada ortalamayı kuruyor (§ ORTALAMA). Ayrı sayılar olsaydı biri
       değişirken diğeri unutulur ve düğme yeniden kayardı.
       ⚠ Custom property'nin sözde öğeye geçtiği SINANDI: değişken 40px
         yapıldığında düğme 40px ölçüldü. */
    height: var(--dosya-dugme-h);
    margin-inline-end: .75rem;
    padding: 0 .875rem;
    border: 1px solid var(--brand-line);
    border-radius: var(--r-sm);
    background: var(--brand-soft);
    font: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--brand);
    cursor: pointer;
    transition: background-color var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease);
}

/* Hover İMLEÇ KUTUNUN HER YERİNDEYKEN tetikleniyor (ata seçici), yalnızca
   düğmenin üstündeyken değil: kutunun tamamı tek bir tıklama hedefi ve
   geri bildirimin de tamamını kapsaması gerekiyor. */
.ay-input[type="file"]:hover::file-selector-button,
.ay-input[type="file"]:focus::file-selector-button {
    border-color: var(--brand);
    background: var(--brand-tint);
}

/* hatalı alan — kırmızı yalnızca hata durumunda girer */
.ay-input[aria-invalid="true"] {
    border-color: #D92D20;
    box-shadow: 0 0 0 3px rgba(217, 45, 32, .10);
}

.ay-error {
    font-size: var(--fs-sm);
    font-weight: 500;
    color: #B42318;
}

/* onay kutusu satırı */
.ay-check {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    margin: 0;
    font-size: var(--fs-sm);
    line-height: 1.55;
    color: var(--ink-soft);
}

/* 20px: zorunlu bir onam kutusu için 18px dokunmada küçük kalıyordu.
   Etiket de kutuyu işaretlediği (label[for]) için asıl dokunma alanı satırın
   tamamı; bu ölçü kutunun kendisini rahat hedeflenebilir yapıyor. */
.ay-check input {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin: .0625rem 0 0;
    accent-color: var(--brand);
    cursor: pointer;
}

.ay-check label { cursor: pointer; }

/* durum şeridi — form sonucu, uyarı, bilgi */
.ay-alert {
    /* position: relative — kapatma düğmesinin çıpası (aşağıda). Düğme akışta
       DEĞİL: .ay-alert bir satır, .ay-alert--blok bir kolon, ve düğmenin iki
       yerleşimde de sağ ÜST köşede durması gerekiyor. Akışta kalsaydı kolon
       kipinde en alta düşerdi. */
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin: 0;
    padding: .8125rem .9375rem;
    border-radius: var(--r-md);
    font-size: var(--fs-base);
    line-height: 1.55;
}

/* Şeridin BAŞINDAKİ durum ikonu. margin-top: şerit align-items: flex-start
   ile hizalı (ikon çok satırlı metnin ortasına değil ilk satırına oturmalı),
   o .1875rem ikonu ilk satırın optik merkezine indiriyor. */
.ay-alert svg {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: .1875rem;
}

.ay-alert > .ay-ico {
    font-size: 16px;
    margin-top: .1875rem;
}

/* Şeridin içinde metnin ALTINDA bir eylem olduğunda (düğme, bağlantı).

   .ay-alert bir flex SATIRI: içine paragraf + form konulduğunda ikisi yan
   yana diziliyor, paragraf en küçük genişliğe sıkışıyor ve metin kelime
   kelime alt alta kırılıyordu (panodaki doğrulama ve deneme şeritlerinde
   böyle görüldü). Bu değiştirici yığını dikeye çeviriyor.

   Satır içi stil ya da tek kullanımlık sınıf yazılmadı: şerit ortak bileşen
   (theme.css § 9) ve aynı ihtiyaç başka ekranlarda da çıkacak. */
.ay-alert--blok {
    flex-direction: column;
    align-items: stretch;
    gap: .625rem;
}

/* Dikey şeritte düğme satırın tamamını kaplamasın. */
.ay-alert--blok .ay-btn { align-self: flex-start; }

.ay-alert--blok > p { margin: 0; }

.ay-alert a {
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Şeridin içindeki DÜĞME bir bağlantı değil, düğme gibi görünmeli: üstteki
   kural <a class="ay-btn">'ı da yakalıyor ve dolu düğmenin yazısının altını
   çiziyordu (pano deneme şeridi "Paket seç ve devam et", paket-sec.php
   "Panele dön"). Metin içi bağlantılar çizgili kalıyor. */
.ay-alert a.ay-btn { text-decoration: none; }

.ay-alert--ok {
    background: #ECFDF3;
    color: #05603A;
    box-shadow: inset 0 0 0 1px rgba(5, 96, 58, .12);
}

.ay-alert--err {
    background: #FEF3F2;
    color: #B42318;
    box-shadow: inset 0 0 0 1px rgba(180, 35, 24, .12);
}

/* --- Kapatma düğmesi  (.ay-alert__kapat)  —  KULLANICI KARARI (2026-09-24)
       "allertler kapatmalı olsun. sağında x olsun." -----------------------

   DÜĞMEYİ PHP DEĞİL JS BASIYOR (js/theme.js → AlertKapat, main.js'te tüm
   .ay-alert öğelerine bağlanıyor). Sebep sayılabilir: şerit uygulamada 30
   dosyada 204 kez basılıyor. Her birine elle düğme eklemek 204 dokunuş ve
   204 kaçırma fırsatı demekti; üstelik yeni bir şerit yazan kişi düğmeyi
   eklemeyi unuttuğunda kusur sessiz olurdu. Tek yerden bağlanınca her şerit
   kendiliğinden kapatılabilir oluyor.

   ⚠ SINIF DA JS TARAFINDAN EKLENİYOR (.ay-alert--kapatilir). Dolguyu
   koşulsuz vermek olmazdı: JS kapalıysa düğme yok ve o zaman sağda 2.25rem
   sebepsiz boşluk kalırdı. Sınıf düğmeyle BİRLİKTE geliyor, yani ikisi
   ayrılamıyor.

   ⚠ KAPATMA HATIRLANMIYOR — bilinçli. Şeridi kapatmak yalnızca o sayfa
   görüntüsü için geçerli; yenilemede geri geliyor. Sebebi: şeritlerin çoğu
   GEÇİCİ DEĞİL DURUM bildiriyor (deneme bitti · havale onay bekliyor ·
   e-posta doğrulanmadı). Kalıcı olarak susturulsalar müşteri neden panele
   giremediğini hiçbir yerde okuyamaz hâle gelirdi. Kapatma bir "okudum,
   şimdi ekranı temizle" jesti; kalıcı bir tercih değil.

   ÖLÇÜ 28×28: WCAG 2.5.8 (AA, WCAG 2.2) en az 24×24 istiyor. 44'e çıkarmak
   (2.5.5, AAA) tek satırlık bir şeridi kendi düğmesi yüzünden uzatıyordu. */
.ay-alert--kapatilir {
    /* Düğmeye yer: metin onun altına girmiyor. 28px düğme + .5rem kenar
       payı + .25rem nefes = 2.75rem. */
    padding-inline-end: 2.75rem;
}

/* ⚠ DİKEY KONUM METNİN İLK SATIRINDAN HESAPLANIYOR (2026-09-26 · kullanıcı:
   "x iconu yükseklik olarak tam ortalı olsun, yukarı kaymış duruyor").

   Eskiden sabit 'top: .3125rem' (5px) idi. Tek satırlık şeritte metin satırının
   ortası 13px dolgu + 23,25px satırın yarısı ≈ 24,6px'te, 28px'lik düğmenin
   ortası ise 5 + 14 = 19px'teydi — çarpı ~5,6px YUKARIDA duruyordu.

   Şimdi: şeridin üst dolgusu (.8125rem) + (satır yüksekliği − düğme) / 2.
   Satır yüksekliği 1.55em ve em DÜĞMENİN yazı boyu — o yüzden font-size
   inherit ŞART (düğmeler tarayıcıda kendi 13,33px'ini alıyor). Böylece:
     · tek satırlık şeritte çarpı tam ortada,
     · çok satırlı şeritte (--blok) ilk satırla aynı hizada — ortada değil,
       çünkü uzun bir şeridin ortasındaki çarpı içerikten kopuk görünür.
   Yatay kenar payı da aynı değere çekildi: köşeye yapışık değil, dikey
   boşlukla dengeli. Dolgu (.8125rem) ya da line-height (1.55) değişirse
   buradaki iki sayı da birlikte değişmeli. */
.ay-alert__kapat {
    position: absolute;
    inset-block-start: calc(.8125rem + (1.55em - 28px) / 2);
    inset-inline-end: .5rem;
    font-size: inherit;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: var(--r-sm);
    background: transparent;
    /* Şeridin kendi mürekkebi: düğme --ok'ta yeşil, --err'de kırmızı, panelde
       --uyari'da kehribar oluyor. Tek renk vermek dört tonda dördünde de
       yanlış görünürdü. */
    color: inherit;
    cursor: pointer;
    opacity: .55;
    transition: opacity .18s var(--ease-out), background-color .18s var(--ease-out);
}

.ay-alert__kapat:hover,
.ay-alert__kapat:focus-visible {
    opacity: 1;
    /* Zemin şeridin mürekkebinden türüyor (%10): her tonda kendi rengiyle
       koyulaşıyor, sabit bir gri hiçbirine uymuyordu. */
    background: color-mix(in srgb, currentColor 10%, transparent);
}

/* ⚠ .ay-alert > .ay-ico KURALINI EZİYOR. O kural şeridin BAŞINDAKİ ikon için
   yazıldı (16px + margin-top: .1875rem, metnin ilk satırıyla hizalı). Kapatma
   ikonunun hizası düğmenin kendisinden geliyor (inline-flex + center); üstten
   margin alsaydı çarpının merkezi kaymış olurdu.

   Seçici '>' ile DOĞRUDAN ÇOCUK değil: kapatma ikonu düğmenin içinde, yani
   şeridin torunu. O yüzden yukarıdaki kural ona hiç değmiyor — buradaki
   margin: 0 yalnızca emniyet. */
.ay-alert__kapat .ay-ico {
    font-size: 13px;
    margin: 0;
}

/* --------------------------------------------------------------------------
   9b · Ortak bileşen: KİP (.ay-modal) ve SİLME ONAYI (.ay-onay)
        2026-09-25 · KULLANICI KARARI

     "düzenlemeyi modal içinde yap."
     "tüm silme işlemlerini de sweetalert ile, silmek istediğinizden
      eminmisiniz şeklinde yap."

   --------------------------------------------------------------------------
   ⚠ SWEETALERT2 KÜTÜPHANESİ GETİRİLMEDİ — DAVRANIŞI GETİRİLDİ

   Aynı karar bu projede bir kez daha verildi ve kullanıcı onu kabul etti:
   "fancybox gibi göster" istendiğinde kütüphane yerine § 24r-2c'deki ışık
   kutusu yazıldı (gerekçesi panel/medya.php'de). Sebepler burada da aynı ve
   biri ek:

     · CSP'de style-src 'unsafe-inline' YOK (config/ayarlar.php). SweetAlert2
       konumlandırma ve animasyon için öğelerin style özelliklerine yazıyor;
       bu politikada davranışı garanti değil. Bizim bileşenimiz .style'a HİÇ
       dokunmuyor — açık/kapalı hâli 'hidden' özniteliği ve <html>'e eklenen
       bir sınıfla yönetiliyor (aynı kalıp .tur ve .mdy__isik'te de var).
     · ~60 KB JS + ~24 KB CSS'in getirdiği tek şey bir onay kutusu; aç/kapat,
       Esc, odak yönetimi ve örtü zaten Tur/Isik bileşenlerinde çözülmüş.
     · SİLME ONAYI GÜVENLİK AKIŞININ PARÇASI. Üçüncü taraf bir CDN dosyası
       yüklenemezse (ad çözümlemesi, abonelik bitişi, bölgesel engel) diyalog
       hiç açılmaz. Kendi dosyamız panelin zaten yüklediği js/theme.js'in
       içinde; ayrıca JS hiç çalışmasa bile silme SUNUCU ONAY EKRANINDAN
       geçmeye devam ediyor (bağlantılar o adrese bakmayı sürdürüyor).

   --------------------------------------------------------------------------
   İKİ KULLANIM, TEK KABUK

     .ay-modal            genel kip kabuğu — medya "Dosyayı değiştir" formu
     .ay-modal--onay      daralmış hâli   — silme onayı (.ay-onay* içerikle)

   ⚠ .mdy__isik (ışık kutusu) BU KABUĞA TAŞINMADI ve bu bilinçli bir borç:
   o bileşenin üç kuralı araclar/surum-imzalari.php'de imzalı ve tam ekran
   sahne + koyu zemin + oklar için kendi ölçülerini taşıyor. Ortaklaştırmak
   ayrı bir tur ve ayrı bir sınama işi; not olarak bırakıldı.

   z-index 1300: yapışık üst şerit 1000, drawer 1100, ışık kutusu 1200
   (§ 24c ve § 24r-2c). Onay diyalogu hepsinin ÜSTÜNDE olmak zorunda —
   altında kalırsa "emin misiniz?" sorusu şeridin arkasında duruyor.
   -------------------------------------------------------------------------- */
.ay-modal {
    position: fixed;
    inset: 0;
    z-index: 1300;
    display: grid;
    place-items: center;
    padding: 1rem;
}

/* ⚠ [hidden] AÇIKÇA YAZILIYOR: yukarıdaki display: grid, tarayıcının hidden
   için uyguladığı display: none'ı EZİYOR. Bu satır olmadan kip sayfa
   açılışında AÇIK duruyor (aynı tuzak .mdy__isik ve .tur köklerinde de var,
   ikisinde de açıkça yazılı). */
.ay-modal[hidden] {
    display: none;
}

/* ÖRTÜ BİR <button>: tıklayınca kapanıyor ve klavyeyle de erişilebiliyor.
   <div> + onclick klavyeye kapalı olurdu. */
.ay-modal__ortu {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: rgba(2, 12, 33, .62);
    cursor: pointer;
    /* Odak halkası içe alınıyor: dış halka ekran kenarında kırpılıyor. */
    outline-offset: -3px;
}

.ay-modal__kart {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(34rem, 100%);
    max-height: 92vh;
    overflow: hidden;
    border-radius: var(--r-lg);
    background: var(--surface);
    box-shadow: 0 24px 64px rgba(2, 12, 33, .45);
}

/* --- AÇILIŞ / KAPANIŞ HAREKETİ ------------------------------------------

   İKİ KADEME, BİRBİRİNİ EZİYOR — sebebi 'hidden' özniteliği.

   Kip display: none'dan geliyor ve display'i klasik geçişle animasyonlamak
   mümkün değil. Bu yüzden:

     TABAN      açılışta @keyframes. Her tarayıcıda çalışıyor ve projenin
                mevcut kalıbı bu (.tur__panel → turGir, .drawer → drawerIn).
                KAPANIŞI animasyonlayamıyor: öğe hidden olduğu anda gidiyor.

     @supports (transition-behavior: allow-discrete)
                açılış VE kapanış geçişle yapılıyor; display de geçiş
                listesinde (allow-discrete) olduğu için öğe kapanış
                animasyonu bitene kadar ekranda kalıyor. @starting-style
                display: none'dan gelirken başlangıç değerini veriyor.

   ⚠ İKİNCİ KADEMEDE 'animation: none' ŞART: keyframe 'both' ile bitiş
   değerlerini sabitliyor ve geçişle çakışıyordu. Aynı düzeltme § 23'teki
   hero bloklarında da yazılı.

   DESTEKLEMEYEN TARAYICIDA DAVRANIŞ AYNI KALIYOR: kip açılırken beliriyor,
   kapanırken anında gidiyor — yani kusur değil, eksik cila. Aynı kalıp
   (özellik varsa cila, yoksa sade davranış) style.css § 16'daki SSS
   akordiyonunda da kullanılıyor (::details-content + interpolate-size).

   HAREKET AZALTMA TERCİHİ ayrıca ele alınmıyor: § 11'deki genel blok hem
   animation-duration'ı hem transition-duration'ı .01ms'ye indiriyor, yani
   iki kademe de kendiliğinden kapanıyor. */
@keyframes ayKipOrtu {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes ayKipKart {
    from { opacity: 0; transform: translateY(6px) scale(.97); }
    to   { opacity: 1; transform: none; }
}

.ay-modal {
    animation: ayKipOrtu var(--t-fast) var(--ease-out) both;
}
.ay-modal__kart {
    animation: ayKipKart var(--t-base) var(--ease-out) both;
}

@supports (transition-behavior: allow-discrete) {
    .ay-modal {
        animation: none;
        opacity: 1;
        /* ⚠ İKİ SÜRE FARKLI VE FARKLI OLMAK ZORUNDA. Örtü --t-fast'ta (.18s)
           sönüyor ama display --t-base'de (.25s) kesiliyor: display kökün
           içindeki KARTIN geçişinden önce 'none'a düşerse kart kapanış
           animasyonunu tamamlayamadan ekrandan siliniyor (kart geçişi de
           --t-base). Yani buradaki süre kartın süresinden KISA OLAMAZ. */
        transition: opacity var(--t-fast) var(--ease),
                    display var(--t-base) allow-discrete;
    }

    /* Kapalı hâlin değerleri: kapanış geçişinin hedefi ve @starting-style'ın
       eşi. (0,2,0) seçici, yukarıdaki tek sınıflı kuralı geçiyor. */
    .ay-modal[hidden] {
        opacity: 0;
    }

    @starting-style {
        .ay-modal { opacity: 0; }
    }

    .ay-modal__kart {
        animation: none;
        opacity: 1;
        transform: none;
        transition: opacity var(--t-base) var(--ease-out),
                    transform var(--t-base) var(--ease-out);
    }

    .ay-modal[hidden] .ay-modal__kart {
        opacity: 0;
        transform: translateY(6px) scale(.97);
    }

    @starting-style {
        .ay-modal .ay-modal__kart {
            opacity: 0;
            transform: translateY(6px) scale(.97);
        }
    }
}

.ay-modal__ust {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex: 0 0 auto;
    padding: .8rem .95rem;
    border-bottom: 1px solid var(--hairline);
}

/* Başlık iki parça: sabit etiket ("Dosyayı değiştir") ve JS'in yazdığı dosya
   adı. Ad uzun olduğunda kapatma düğmesini dışarı itmesin. */
.ay-modal__h {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    color: var(--ink);
    font-size: var(--fs-base);
    font-weight: 650;
    letter-spacing: -.01em;
}
.ay-modal__ad {
    display: block;
    overflow: hidden;
    color: var(--ink-mute);
    font-size: var(--fs-sm);
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Gövde kendi içinde kayıyor: uzun bir form ya da büyük bir önizleme kartı
   ekranın dışına taşırmasın. */
.ay-modal__gov {
    flex: 1 1 auto;
    min-height: 0;
    padding: .95rem;
    overflow-y: auto;
}

.ay-modal__dip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    flex: 0 0 auto;
    padding: .8rem .95rem;
    border-top: 1px solid var(--hairline);
}

/* Kapatma düğmesi — ölçü .mdy__isik_kapat ile aynı aileden (2rem kare) ama
   ayrı sınıf: o ışık kutusunun koyu kabuğunda duruyor, bu beyaz kartta. */
.ay-modal__kapat {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--ink-soft);
    cursor: pointer;
    transition: border-color var(--t-fast) var(--ease),
                color var(--t-fast) var(--ease);
}
.ay-modal__kapat:hover,
.ay-modal__kapat:focus-visible {
    border-color: var(--brand-line);
    color: var(--brand);
}

/* --- SİLME ONAYI --------------------------------------------------------

   Kart daha dar ve başlık şeridi YOK: soru zaten kartın ilk satırı, ikinci
   bir başlık çubuğu aynı şeyi iki kez söylerdi. */
.ay-modal--onay .ay-modal__kart {
    width: min(26rem, 100%);
}

.ay-onay__gov {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: .25rem .85rem;
    padding: 1.1rem 1.15rem .35rem;
}

/* İKON YUVARLAK VE HATA TONUNDA — ama tek taşıyıcı DEĞİL: soru metni de
   "silmek" diyor ve düğmenin yazısı "Evet, sil" (WCAG 1.4.1). */
.ay-onay__sim {
    grid-row: 1 / span 2;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--r-pill);
    background: var(--st-hata-bg);
    color: var(--st-hata-ink);
    font-size: 18px;
}

.ay-onay__h {
    margin: 0;
    align-self: center;
    color: var(--ink);
    font-size: 1.05rem;
    font-weight: 680;
    letter-spacing: -.01em;
}

.ay-onay__m {
    margin: .15rem 0 0;
    color: var(--ink-soft);
    font-size: var(--fs-sm);
    line-height: 1.55;
}
/* Ekran kendi cümlesini vermediyse metin boş kalıyor; boş bir paragraf
   satır boşluğu bırakmasın. */
.ay-onay__m:empty {
    display: none;
}

/* Düğmeler: YIKICI OLAN SOLDA DEĞİL SAĞDA değil — ikisi de solda, okuma
   yönünde. "Evet, sil" birincil ama KIRMIZI: onay diyalogunda marka rengi
   kullanmak, yıkıcı eylemi sıradan bir onaya benzetirdi (aynı karar
   § 24m'deki .yrm__sil_btn'de de alınmıştı, oradan buraya taşındı). */
.ay-onay__dip {
    justify-content: flex-end;
    border-top: 0;
    padding-top: .35rem;
}

.ay-onay__evet {
    background: var(--st-hata-ink);
    border-color: var(--st-hata-ink);
    color: #fff;
}
.ay-onay__evet:hover,
.ay-onay__evet:focus-visible {
    filter: brightness(1.08);
    color: #fff;
}

/* SAYFA KAYDIRMASI KİLİTLENİYOR: kip açıkken arkadaki sayfanın kayması,
   kapanınca kullanıcıyı bambaşka bir yerde bırakıyor. Kural <html> üzerinde
   (aynı kalıp html.ay-isik-acik'te de var). */
html.ay-modal-acik,
html.ay-modal-acik body {
    overflow: hidden;
}

/* Telefonda kip kenarlara yaklaşıyor ve düğmeler tam genişlik: 360 piksellik
   ekranda "Evet, sil" ile "Vazgeç" yan yana 150 pikselin altına düşüyor. */
@media (max-width: 640px) {
    .ay-modal {
        padding: .5rem;
    }

    .ay-onay__dip .ay-btn,
    .ay-modal__dip .ay-btn {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* --------------------------------------------------------------------------
   10 · Yardımcılar
   -------------------------------------------------------------------------- */
.ay-hairline { background: var(--hairline); }
.ay-scroll-lock { overflow: hidden; }

/* İçeriğe geç — yalnızca klavyeyle odaklanınca görünür. Ekranda yer
   kaplamaması için sayfanın üstüne çekiliyor, odakta aşağı iniyor. */
/* Solda: sekme sırasının ilk öğesi olduğu için sayfanın sol üst köşesi doğal
   yeri. Ortada dursa odaklanınca menü bağlantılarının üzerine biniyordu. */
/* inset-inline-start: fiziksel 'left' yazıldığında Arapça (dir="rtl")
   sayfada bağlantı sol üstte kalıyordu — sekme sırasının ilk öğesi olduğu
   için doğal yeri metnin BAŞLADIĞI köşe, yani RTL'de sağ üst. */
.ay-skip {
    position: fixed;
    top: 0;
    inset-inline-start: 1rem;
    z-index: calc(var(--z-cine) + 1);
    padding: .625rem 1.25rem;
    border-radius: 0 0 var(--r-md) var(--r-md);
    background: var(--brand);
    color: var(--on-brand);
    font-size: var(--fs-sm);
    font-weight: 600;
    text-decoration: none;
    transform: translateY(-110%);
    transition: transform var(--t-base) var(--ease-out);
}

.ay-skip:focus {
    transform: translateY(0);
    color: var(--on-brand);
    outline: none;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .9), 0 6px 18px -6px rgba(1, 30, 90, .6);
}

.ay-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   11 · Hareket azaltma tercihi
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

/* --------------------------------------------------------------------------
   Japonca yazı tipi (2026-09-29 · /ja)
   Genel yığında Japonca glif yok; Windows'ta tarayıcı Segoe UI'dan sonra
   rastgele bir CJK yedeğine (ör. MS UI Gothic ya da Çince glifli bir yazı
   tipi) düşebiliyor. Japonca sistem yazı tipleri Latin adların hemen
   ardına konuyor: Latin harfler yine
   SF/Segoe ile, kana ve kanji Hiragino / Yu Gothic / Meiryo ile çiziliyor.
   Web yazı tipi yüklenmiyor (CSP font-src 'self'; ek indirme yok).
   -------------------------------------------------------------------------- */
:root:lang(ja) {
    --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
                 "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI",
                 "Yu Gothic", YuGothic, Meiryo, "Noto Sans JP", sans-serif;
}

/* Japoncada kelime arası boşluk yok; uzun satırlar noktalama kuralına göre
   kırılsın (satır başına 、。 düşmesin). */
:lang(ja) body {
    line-break: strict;
    overflow-wrap: anywhere;
}
