/* The one place this product draws a focus ring and answers a reduced-motion
 * request.
 *
 * Four web stylesheets defined zero focus rules between them (M18) while the
 * Android shell defined one, and `prefers-reduced-motion` was honoured on
 * Android and on nothing here (L23) -- including two 320px blurred blobs
 * running `imp-drift` forever behind the panel header, with no pause control.
 * (Those blobs are deleted now; see the reduced-motion block below.)
 * Same widget, two answers, on two surfaces of one product.
 *
 * It also draws the one `::placeholder` rule, for the same reason: it was the
 * one text colour on the page nobody had chosen.
 *
 * Linked LAST by every page that renders chrome, and the declarations carry
 * `!important`, because /admin loads Tabler and Tabler's own focus rules say
 * `outline:0` at class-level specificity. An accessibility floor a vendor sheet
 * can switch off is not a floor. Mobile keeps its own copy because the shell
 * ships inside the APK and cannot reach this origin's stylesheet;
 * tests/interaction.mjs fails when the two stop agreeing.
 */

/* `hidden` must actually hide, on every page, whatever the page's own CSS says.
 *
 * The attribute's only defence is a UA rule at the lowest specificity there is,
 * so ANY author rule that sets `display` on the element beats it silently — and
 * a plain `form { display: grid }` is enough. /consumer shipped exactly that:
 * both auth forms on screen at once, the one carrying `hidden` rendering 253px
 * tall, so the "Kayıt olun" link offered to reveal fields already on screen.
 *
 * This rule existed in styles.css with its reason written above it, and
 * consumer.css had a one-class version of it (`.form-error[hidden]`) — a bug
 * patched where it was noticed rather than where it lives. It belongs here,
 * loaded last by every page, because the page that gets this wrong is always
 * the next one somebody writes.
 *
 * `!important` is not laziness here: an attribute that means "not rendered"
 * losing to a layout rule is not a cascade the author should have to win again
 * on every page. Same reasoning as the focus ring below. */
[hidden] { display: none !important; }

/* --- Odak halkası ----------------------------------------------------------
 *
 * Çift tonlu, bilerek. Tek açık bir halka soluk bir kiracı markasının üstünde
 * kayboluyor, ve `--accent` işletme sahibinin yazdığı bir değer — sunucu
 * `#ffffff`i kabul ediyor (M19). Çift ton, arkada ne olursa olsun ikisinden
 * birinin görünmesini garantiliyor; Chrome ve Safari'nin kendi halkalarını iki
 * tonlu çizmesinin sebebi de bu.
 *
 * DEĞİŞEN ŞEY (2026-08-20): hangi tonun içeride hangisinin dışarıda olduğu
 * artık temaya bağlı. Eskiden tek bir cevap vardı ve o cevap koyu tema için
 * tasarlanmıştı: #9ab4ff beyaz zeminde 2,03:1, #f4f6f9 üstünde 1,87:1 — yani
 * açık bir sayfada halkayı ayakta tutan tek şey dışındaki neredeyse siyah 6px
 * haleydi, ve o hale açık bir sayfada odaklanan her denetimin etrafına kalın
 * siyah bir bant çiziyordu.
 *
 * Ölçüldü, WCAG 2.2 1.4.11 (odak göstergesi komşu renge karşı 3:1); her
 * yüzeyde İKİ TONDAN İYİSİ alınıyor, çünkü görünürlüğü sağlayan o:
 *   koyu tema (#9ab4ff + rgba(4,7,13,.9)) — sayfa #080b12 9,70:1 · kart
 *     #121a26 8,61:1 · ikincil yüzey #1b2534 7,60:1 · birincil düğme #436ad9
 *     3,86:1 (hale) · beyaz kiracı düğmesi 16,34:1 (hale) · yeşil #22c55e
 *     7,89:1 · dolgulu kırmızı #c2183a 3,21:1  → en kötü 3,21:1
 *   açık tema (#3757b3 + rgba(255,255,255,.9)) — sayfa #f4f6f9 6,11:1 · kart
 *     #ffffff 6,61:1 · ikincil yüzey #eef1f6 5,84:1 · birincil düğme #436ad9
 *     4,28:1 (hale) · siyah kiracı düğmesi 16,83:1 (hale) · yeşil #14762f
 *     4,97:1 · kırmızı #c2183a 5,10:1  → en kötü 4,28:1
 * İki tonun birbirine karşı oranı da ölçüldü — koyuda 9,94:1, açıkta 6,61:1 —
 * çünkü birbirinden ayırt edilemeyen iki ton tek tonlu bir halkadır.
 *
 * NEDEN DEĞERLER tokens.css'ten OKUNMUYOR: bu dosyayı yükleyen beş sayfanın
 * ikisi (admin.html ve legalPages.mjs'in ürettiği hukuk sayfaları) tokens.css'i
 * BİLEREK yüklemiyor (gerekçe admin.css'in başında: Tabler sertçe koyu). Orada
 * `var(--focus-ring)` tanımsız kalır ve tanımsız bir `var()` fallback'siz
 * kullanıldığında bütün bildirimi geçersiz kılar — yani halka tamamen kaybolur.
 * Erişilebilirlik tabanı, yüklenmesi tesadüfe kalmış bir dosyaya bağlanamaz.
 * Bu yüzden tonlar burada tanımlanıyor ve BURASI onların tek kaynağı;
 * tests/interaction.mjs ikinci bir tanımın ortaya çıkmasını yakalıyor.
 *
 * `:focus-visible`, `:focus` değil: fareyle basılan bir düğme arkasında halka
 * bırakmamalı, yoksa halka "klavye burada" anlamını kaybediyor. */
:root {
  --focus-ring: #9ab4ff;
  --focus-halo: rgba(4, 7, 13, .9);
}

/* Açık temanın kapsamı tokens.css'in açık bloklarıyla BİREBİR aynı olmak
   zorunda, yoksa halka sayfanın geri kalanından farklı bir temaya inanır.
   `[data-bs-theme="dark"]` istisnası admin.html için: o sayfa sertçe koyu ve
   tokens.css'i hiç yüklemiyor, yani işletim sistemi açıkken bu blok ona
   ulaşırsa koyu bir konsola açık tema halkası çizilir.
   Hukuk sayfaları bu işareti taşımıyor (apps/api/legalPages.mjs, bu turun
   dosyaları arasında değil): orada sistem açıkken halka açık tema tonunu
   alıyor. Ölçüldü, bu bir erişilebilirlik kusuru DEĞİL — çift ton bu durumda
   da 3:1'i tutuyor (#080b12 üstünde beyaz hale ~16:1) — yalnız görsel olarak
   ters okunuyor. Kalıcı çözüm o dosyanın <html>'ine data-theme="dark" yazmak. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]):not([data-bs-theme="dark"]) {
    --focus-ring: #3757b3;
    --focus-halo: rgba(255, 255, 255, .9);
  }
}

:root[data-theme="light"] {
  --focus-ring: #3757b3;
  --focus-halo: rgba(255, 255, 255, .9);
}

/* `!important` tembellik değil: /admin Tabler'ı yüklüyor ve Tabler'ın kendi
   odak kuralları sınıf özgüllüğünde `outline:0` diyor. Bir satıcı stil
   sayfasının kapatabildiği erişilebilirlik tabanı taban değildir. */
:focus-visible {
  outline: 3px solid var(--focus-ring) !important;
  outline-offset: 2px !important;
  box-shadow: 0 0 0 6px var(--focus-halo) !important;
}

/* Yer tutucu metin, iki temada da okunabilir bir tonda ve OPAKLIĞI ELDE.
 *
 * Bütün apps/web ağacında `::placeholder` kuralı YOKTU (harita §8, satır 23),
 * yani her tarayıcının kendi varsayılanı geçerliydi. Firefox'un varsayılanı
 * metni ayrıca soluklaştırıyor (`opacity` uyguluyor), yani aynı ipucu Chrome'da
 * başka Firefox'ta başka bir kontrast veriyordu — ölçülemez bir değer.
 * `opacity: 1` bunun için ŞART, rengin kendisi kadar önemli.
 *
 * Renk token'dan geliyor, sabit yazılmıyor: `--muted` bu paletin "sessiz ton"
 * cevabı ve tokens.css onu temaya göre değiştiriyor. Fallback (#9aa4b2) bu
 * dosyayı tokens.css'siz yükleyen iki sayfa için, ve ikisi de koyu.
 * Ölçüldü — yer tutucu girdinin içinde duruyor, yani zemin `--field`:
 *   koyu: #9aa4b2 / #1e2531 (%5 beyaz, #121a26 kartın üstünde) = 6,10:1;
 *         kartın kendisinde 6,93:1, sayfada 7,80:1
 *   açık: #5a6675 / #f4f6f9 = 5,40:1; beyaz kartta 5,85:1
 * Hepsi 4,5:1'in üstünde. Yer tutucu WCAG'nin muaf tuttuğu bir metin değil:
 * 1.4.3'ün muafiyeti devre dışı denetimler için, yazılabilir bir alanın ipucu
 * için değil. */
::placeholder {
  color: var(--muted, #9aa4b2);
  opacity: 1;
}

/* Reduced motion is a request from the operating system, not a preference this
 * product weighs. Written as the blanket rule rather than one selector per
 * animation, because the failure mode is the animation somebody adds next and
 * nobody remembers to list here. `.01ms` rather than `0`: a zero-length
 * animation never fires `animationend`, and code waiting on it would hang.
 * `1` iteration is the declaration that actually stops an `infinite` animation.
 * `imp-drift` -- the two 320px blurred blobs behind the panel header -- is what
 * this block was written against, and it is GONE now (2026-08-20, design map §8
 * row 19: `mix-blend-mode: screen` made it nearly invisible on a light ground,
 * so the decoration was dying quietly in one of the two themes). The block
 * stays: it was never written for that one animation, it was written for the
 * next one somebody adds. The Android shell's `drift` is still `infinite` and
 * its own copy of this block is still what stops it. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

/* A closed panel is closed for the pointer too. `inert` is what the dialog
 * helper sets (M17, L22); this only keeps the cursor from inviting a click on
 * something that will not answer. Focus and the accessibility tree are `inert`'s
 * own job -- that is the whole reason it replaced the attribute juggling. */
[inert] {
  cursor: default;
  user-select: none;
}
