/* URETILMIS DOSYA — ELLE DUZENLENMEZ (TASK-195; DEC-146 dalga 3).
 *
 * Kaynak: apps/web/src (asagida her blogun basinda dosya adiyla yazili).
 * Uretici: apps/web/scripts/ilkeller-css.mjs  —  `npm run ilkeller`
 *
 * Bu dosya admin ve portal Blade kabuklarinin ilkel setidir: Panel, Field,
 * Table, Toolbar, EmptyState, Drawer, Popover, hesap menusu ve iskelet
 * yardimcilari SPA ile AYNI sinif adlarini ve AYNI kurallari tasir. Bir kural
 * burada elle degistirilirse IlkelSetParitesiTest bayt farkini KIRMIZI
 * dondurur; dogru yol kaynagi degistirip ureticiyi yeniden kosmaktir.
 *
 * TOKEN BILDIRIMI YOKTUR: `var(--*)` degerleri yuzeyin kendi stil dosyasindan
 * (admin.css / portal.css) gelir ve orada token paritesiyle korunur.
 *
 * SPA'YA OZGU SECICILER DE GELIR (or. `.account-nav a`, `.status-chip`):
 * kaynagi bloklara ayirip suzmek, "hangi kural hangi yuzeye ait" karari
 * dogururdu ve o karar iki bildirim demekti. Eslesmeyen secici bir maliyet
 * degil, paritenin kanitidir.
 */

/* ===== src/styles/layout.css ===== */

/* İSKELET İLKELLERİ — responsive davranış sayfalarda değil BURADA yaşar
   (TASK-193; DEC-146, DESIGN.md §Responsive iskelet).

   TASARIM İLKESİ: kırılma noktası SON çaredir, ilk çare değil. Aşağıdaki
   ilkellerin çoğu hiç medya sorgusu kullanmaz — genişliğe `minmax()`,
   `flex-wrap` ve `min()` ile İÇKİN olarak uyum sağlarlar. Sayfa CSS'i bir
   medya sorgusu yazmak zorunda kaldığında, önce bu ilkellerden birinin
   yetmediği doğrulanır: 40 sayfaya dağılmış kırılma noktası, tek yerden
   yönetilemeyen bir yerleşim demektir.

   GÖVDE ASLA YATAY KAYMAZ. Kural `overflow-x: hidden` ile KAPATILMAZ — o,
   belirtiyi gizler, `position: sticky` öğeleri bozar ve en kötüsü ölçümü
   ANLAMSIZLAŞTIRIR: gövdeyi kırpan bir sayfada "gövde kaymıyor" sondası her
   zaman yeşil döner ve hiçbir şey kanıtlamaz. Doğru yol taşan içeriği KENDİ
   kutusuna koymaktır (`.layout-scroll-x`). */

/* GÖVDE ASLA YATAY KAYMAZ — İKİ YAPISAL DAYANAK (TASK-195'te base.css'ten
   BURAYA taşındı; DESIGN.md §Gövde asla yatay kaymaz).

   Bu iki kural taşmanın en sık iki yapısal nedenini kapatır: kutusundan geniş
   gömülü içerik ve kırılmayan uzun dize (mono takip numarası, e-posta, URL,
   uç yolu). Skeleton dosyasında olmalarının sebebi ölçüldü: `base.css`
   yalnız SPA'ya yüklenir, dolayısıyla admin ve portal bu iki dayanaktan
   YOKSUNDU — portal doküman sayfası 360px'te kırılmayan bir `code` yüzünden
   gövdeyi 27px kaydırıyordu ve kural yalnız bir yüzeyde geçerliydi.

   `overflow-x: hidden` BİLİNÇLİ OLARAK YOK. Kural onunla "sağlanmış" görünür
   ama iki bedeli vardır: `position: sticky` öğeleri sessizce bozulur ve —
   asıl önemlisi — taşma ölçülemez hale gelir. Gövdeyi kırpan bir sayfada
   `scrollWidth <= clientWidth` sondası HER ZAMAN yeşildir; yani kuralı
   koruyacak ölçüm, kuralı koruduğunu iddia eden satır tarafından öldürülür. */
img,
svg,
video,
canvas,
iframe {
  max-width: 100%;
}

body {
  overflow-wrap: break-word;
}

/* İçerik kolonu — tek tavan, tek iç boşluk kaynağı. */
.layout-container {
  width: 100%;
  max-width: var(--layout-content-max);
  margin-inline: auto;
  padding-inline: var(--space-lg);
}

/* Dar ekranda kenar boşluğu daralır; içerik kaybolmaz, nefes payı azalır. */
@media (width < 768px) {
  .layout-container {
    padding-inline: var(--space-md);
  }
}

/* Dikey ritim — 8px taban ızgarasının tek uygulayıcısı.

   `minmax(0, 1fr)` SÜS DEĞİL, KURALIN KENDİSİ. Tek kolonlu bir ızgarada
   varsayılan track boyutu `auto`dur ve `auto` bir track KAPSAYICIDAN GENİŞ
   olabilir: içerik max-content genişliği isterse track büyür, çocuklar o
   track'e yaslanır ve kapsayıcının kutusunu taşarlar.

   BU ÖLÇÜLDÜ ve iki kez yanlış teşhis edildi (TASK-194):
     1. Sayfaların `overflow-x: auto` taşıyan sarmalayıcıları ZATEN VARDI ve
        yine de 48 ziyaretin 19'unda gövde kayıyordu.
     2. Çocuklara `min-width: 0` eklendi — HİÇBİR ŞEY DEĞİŞMEDİ (7 kayma aynen
        kaldı), çünkü `min-width` ÇOCUĞU sınırlar, TRACK'İ değil.
   Taşan öğeler DOM'da tek tek ölçüldüğünde görüldü ki sarmayan satırlar da
   `auto-fit` ızgaralar da zaten doğruydu: hepsi 583px'lik bir track'e
   yaslanıyordu, 360px'lik kapsayıcının içinde. `minmax(0, …)` track'in alt
   sınırını sıfırlar ve taşmayı YAPISAL OLARAK imkânsız kılar. */
.layout-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-lg);
  align-content: start;
}

.layout-stack-sik {
  gap: var(--space-sm-md);
}

/* Yatay grup — DAR EKRANDA SARAR. Araç çubukları, rozet dizileri ve düğme
   ikilileri bunu kullanır; sarmayan bir yatay grup, gövde kaymasının en sık
   nedenidir. */
.layout-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm-md);
}

.layout-cluster-aralik {
  justify-content: space-between;
}

/* `.layout-grid` KALDIRILDI (TASK-280; DEC-231): hiçbir işaretleme onu
   tüketmiyordu ve bu dosya ilkeller.css'in TÜRETME KAYNAĞI olduğu için kural
   SPA'nın yanı sıra admin ve portal Blade yüzeylerine de iniyordu. Kart/panel
   dizilerinin ızgarası bugün sayfaların kendi kurallarındadır; ilkel bir ızgara
   yeniden gerekirse KENDİ TÜKETİCİSİYLE BİRLİKTE geri gelir (olu-kural kapısı
   tüketicisiz kuralı reddeder, kuralın kendisini değil). */

/* Izgara/flex çocuklarının varsayılan `min-width: auto` değeri, içeriği
   kutusundan TAŞIRIR (mono takip numaraları ve uzun e-postalar bunu tetikler).
   Taşıma hakkı yalnız `.layout-scroll-x` kutusundadır. */
.layout-min-0 {
  min-width: 0;
}

/* YATAY KAYMA HAKKI OLAN TEK KUTU. Geniş tablo, geniş kod bloğu ve geniş
   çizelge buraya sarılır: kayan şey GÖVDE değil, bu kutudur. Klavye
   kullanıcısı için odaklanabilir olmalıdır, aksi halde içeriğe yalnız fareyle
   ulaşılır. */
.layout-scroll-x {
  overflow-x: auto;
  max-width: 100%;
  /* Dokunmatik ivme mobilde varsayılan; kaydırma çubuğu tema-farkındadır
     çünkü `color-scheme` kök öğeden miras gelir. */
  overscroll-behavior-x: contain;
}

/* KUTUDAKI TABLO SIKISMAZ, KUTU KAYAR.
   `width: 100%` taşıyan bir tablo dar ekranda kolonlarını içeriğin min-content
   genişliğinin ALTINA ezer: ölçüldü, koli ölçü alanları 44px taban yazılı
   olduğu halde 37px'e sıkıştı. Kural kutunun KENDİSİNDE durur — sayfa tablosu
   `.layout-scroll-x` içine girdiği anda doğru davranışı devralır ve her tablo
   için ayrıca hatırlanması gerekmez. */
.layout-scroll-x > table {
  min-width: max-content;
}

.layout-scroll-x:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* WCAG 2.5.8 (AA) TABANI — HER YERLESIMDE, masaustu dahil.
   Yukaridaki 44px tabani DOKUNMATIK yerlesime aittir; bu 24px'lik taban her
   yerde gecerlidir ve olculdu: masaustunde tablo baglantilari 18px, yerel
   onay kutulari 13px cikiyordu. Yogunlugu bozmayacak kadar kucuk, standardi
   karsilayacak kadar buyuk. */
.btn,
.field-control,
.status-chip,
.layout-geri,
.account-nav a,
.layout-scroll-x a {
  min-height: 24px;
}

/* `min-height` SATIR-ICI bir ogeye ETKI ETMEZ — yerlesim kutusu gerekir.
   Olculdu: tablo baglantilari kural yazili oldugu halde 18px kalmisti. */
.layout-geri,
.account-nav a,
.layout-scroll-x a {
  display: inline-flex;
  align-items: center;
}

/* Yerel onay kutusu/radyo 13px cizilir; 16px'e cikarilir ve gorunmez ortuyle
   24px'lik hedefe tamamlanir (mekanik dokunmatik yerlesimdekinin aynisidir,
   yalniz pay kucuktur).

   GORSEL OLARAK GIZLENMIS RADYO DISLAMASI KALKTI (TASK-202): tema secimi uc
   durumlu bir radyo grubuyken gizli girdiler bu kuraldan haric tutulurdu;
   DEC-156 ile secim iki durumlu bir dugmeye dondu ve o sinif hicbir ogede
   kalmadi. Disi bosa dusen bir `:not()` birakmak, sonraki okuyucuya var
   olmayan bir istisna anlatirdi. */
input[type='checkbox'],
input[type='radio'] {
  position: relative;
  width: 16px;
  height: 16px;
}

input[type='checkbox']::after,
input[type='radio']::after {
  content: '';
  position: absolute;
  inset: -4px;
}

/* DOKUNMA HEDEFİ TABANI — KOŞUL GENİŞLİK **VEYA** İŞARETÇİ TÜRÜDÜR.
   Eşik {breakpoints.lg}, {breakpoints.md} DEĞİL: çekmece kabuğu 1024px'in
   altında devreye giriyor, yani 768–1023px arası TAM OLARAK dokunmatik
   yerleşimdir ama ilk sürümde tabansız kalmıştı — hamburger düğmesi orada
   32x22 ölçüldü. Eşiği kabuğun kendi eşiğine bağlamak, iki sayının sessizce
   ayrışmasını önler.

   `(pointer: coarse)` İKİNCİ VE DAHA DOĞRU KOŞULDUR: 44px kuralı bir GENİŞLİK
   kuralı değil bir GİRDİ kuralıdır (WCAG 2.5.5). Geniş ekranlı dokunmatik bir
   dizüstü ya da yatay tablet, genişlik testinden geçer ama parmakla kullanılır.
   Genişliği tek ölçüt yapmak o kullanıcıyı sessizce dışarıda bırakırdı.
   Ters yönde de doğru: fare kullanan 1280px'lik masaüstünde 44px taban,
   evrak dilinin yoğunluğunu bozardı ve orada geçerli olan WCAG 2.5.8'in
   24px tabanıdır. */
@media (width < 1024px), (pointer: coarse) {
  .layout-tap {
    min-height: var(--layout-tap-target);
    min-width: var(--layout-tap-target);
  }

  /* PAYLAŞILAN DENETİMLERİN TABANI. Tek tek sayfalara `.layout-tap` serpmek
     yerine, ilkel setin kendi sınıfları taban alır: bir sayfa düğme
     kullandığında dokunma hedefini HATIRLAMAK zorunda kalmaz. */
  /* `.drawer-kapat` TASK-446 ile girdi: çekmecenin Kapat düğmesi `.btn`
     değildir ve gerçek tarayıcı ölçümü onu dokunmatik yerleşimde 26px buldu
     (.specforge/evidence/TASK-446/05-gorsel-kontrol.txt); klavye
     kullanıcısının tek çıkış yolu ESC'tir ama dokunan kullanıcının tek yolu
     bu düğmedir. */
  .btn,
  .field-control,
  .tema-anahtari,
  .status-chip,
  .drawer-kapat {
    min-height: var(--layout-tap-target);
  }

  /* Dar sayısal alanlar (koli ölçüleri) yükseklikte tabanı tutuyordu ama
     GENİŞLİKTE 37px ölçüldü — hedef iki boyutludur. `width: 100%` gerekli:
     alan, hücresinin min-width'ini DOLDURMADIĞI için dar kalıyordu. */
  .field-control {
    min-width: var(--layout-tap-target);
    width: 100%;
  }

  /* TEK BAŞINA DURAN BAĞLANTI bir düğmedir, cümle değil: geri dönüş
     bağlantıları, hesap alt-gezinmesi ve tablo hücresindeki satır eylemleri
     dokunma hedefini tutmak zorundadır. Bir CÜMLENİN İÇİNDEKİ bağlantı bu
     kuralın dışındadır (WCAG 2.5.8 Inline) ve sonda onu ayrıca sayar. */
  .account-nav a,
  .layout-geri,
  /* Tablodaki her bağlantı: seçici ilkelin KENDİSİNE bağlıdır (her tablo
     `.layout-scroll-x` kutusundadır), tablo tablo sayılan sınıf listesine
     değil — yeni bir tablo eklendiğinde kural KENDİLİĞİNDEN kapsar. */
  .layout-scroll-x a {
    display: inline-flex;
    align-items: center;
    min-height: var(--layout-tap-target);
  }

  /* Onay kutusu ve radyo: yerel denetim 13–16px'tir ve dokunulacak kadar
     büyütülemez (tarayıcı çizimi bozulur). Hedef, denetimi SARAN kutudur —
     bu yüzden isabet alanı görünmez bir dolguyla genişletilir. */
  /* `.layout-onay` seçicisi bu gruptan KALDIRILDI (TASK-280; DEC-231):
     hiçbir işaretleme onu taşımıyordu. Kural `.checkbox-field` için aynen
     yürürlüktedir. */
  .checkbox-field {
    min-height: var(--layout-tap-target);
    display: flex;
    align-items: center;
  }

  /* ONAY KUTUSU / RADYO — GÖRÜNMEZ İSABET ALANI.
     Yerel denetim 13–16px çizilir ve 44px'e BÜYÜTÜLEMEZ: tarayıcı kutuyu
     ölçekleyince tik işareti bozulur ve denetim yabancılaşır. Ölçüldü:
     `padding` + negatif `margin` denemesi de işe yaramadı — Chromium yerel
     denetimin sınır kutusunu dolguyla genişletmiyor.
     Doğru mekanizma, denetimin GÖRÜNMEZ bir örtüyle kaplanmasıdır: kutu 24px
     çizilir, tıklanabilir alan 44px olur, görsel dil değişmez. */
  /* `flex-shrink: 0` BİR CİLA DEĞİL, ÖLÇÜLMÜŞ BİR ONARIMDIR. Denetim bir
     flex kabının içindeyken (taşıyıcı seçenekleri: `label` + uzun metin)
     varsayılan `flex-shrink: 1` onu 24px'ten 17px ve 13px'e kadar eziyordu;
     örtü kutuya GÖRE büyüdüğü için isabet alanı da 44px değil 37×44 ve 33×44
     ölçüldü. Yani kural yazılıydı ama yerleşim onu sessizce geri alıyordu —
     kalıntı bir ölçüm artefaktı değil, gerçek bir dokunma hedefi ihlaliydi. */
  input[type='checkbox'],
  input[type='radio'] {
    position: relative;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
  }

  input[type='checkbox']::after,
  input[type='radio']::after {
    content: '';
    position: absolute;
    inset: -10px;
  }
}

/* ===== src/styles/typography.css ===== */

/* Tipografi yardımcıları — token varyantlarının sınıf karşılıkları.
   DEC-142: Archivo ölçeği 2 boyuttan 4'e çıktı (display-xl … heading-sm),
   böylece sayfa başlığı ile panel içi ara başlık aynı sesi paylaşmıyor.

   NEDEN AYRI DOSYA (TASK-195; DEC-146 dalga 3). Bu sınıflar `base.css`
   içindeydi; oradan çıkarıldılar çünkü ilkel setin İŞARETLEMESİ onlara
   dayanır (`class="field-label type-label-xs"`) ve aynı işaretleme Laravel
   kabuklarında da yazılıyor. `base.css` ise ilkel değil TABAN taşır: gövde
   sıfırlaması, `#root` yüksekliği, seçim rengi — bunların Blade tarafında
   karşılığı yoktur ve admin/portal kendi taban kurallarını taşır.
   Ayırmasaydık, Laravel tarafı ya sınıfları KENDİ dosyasına ikinci kez
   yazacaktı (ED-079: aynı bildirim iki yerde) ya da SPA'nın tüm taban
   sıfırlamasını devralacaktı. */

/* BUYUK KADEMELERDE HARF ARALIGI NEGATIFTIR (DEC-197). Bir baslik buyudukce
   optik olarak GEVSER; geri sikistirilmadiginda "buyutulmus govde metni" gibi
   okunur. Olcegin karakterini tasiyan tek ayar budur ve bedeli sifirdir. */

/* `.type-display-2xl` ve `.type-display-xl` KALKTI (TASK-435, FAZ E): son
   tuketicileri tanitim sayfasinin 11, 12 ve 13. bolum baslikllariydi ve port
   onlari referansin KENDI olceklerine cevirdi (`tanitim-bolum__baslik`
   clamp 2rem..3rem, `tanitim-kapanis__baslik` clamp 2.25rem..3.75rem).
   Tuketicisi kalmayan kural govdesi bu depoda BIRAKILMAZ (RISK-074, DEC-231;
   olu-kural kapisi). Tokenlar (`--type-display-xl-*`) uretilmis blokta KALIR:
   uretici tam kumeyi yazar ve token esligi onu boyle olcer. */

.type-heading-sm {
  font-family: var(--type-heading-sm-family);
  font-size: var(--type-heading-sm-size);
  font-weight: var(--type-heading-sm-weight);
  line-height: var(--type-heading-sm-line-height);
}

.type-display-lg {
  font-family: var(--type-display-lg-family);
  font-size: var(--type-display-lg-size);
  font-weight: var(--type-display-lg-weight);
  line-height: var(--type-display-lg-line-height);
  letter-spacing: var(--type-display-lg-letter-spacing);
}

.type-heading-md {
  font-family: var(--type-heading-md-family);
  font-size: var(--type-heading-md-size);
  font-weight: var(--type-heading-md-weight);
  line-height: var(--type-heading-md-line-height);
}

.type-body-sm {
  font-family: var(--type-body-sm-family);
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line-height);
}

.type-label-xs {
  font-family: var(--type-label-xs-family);
  font-size: var(--type-label-xs-size);
  font-weight: var(--type-label-xs-weight);
  letter-spacing: var(--type-label-xs-letter-spacing);
  text-transform: var(--type-label-xs-transform);
}

.type-mono {
  font-family: var(--type-mono-md-family);
  font-size: var(--type-mono-md-size);
  font-variant-numeric: tabular-nums;
}

/* MONO IKI KADEMEDIR (DEC-197). `type-mono` olagan tanimlayicidir;
   `type-mono-lg` evrak artefaktinin masthead'indeki takip numarasidir —
   belgenin ADI odur ve bir tablo hucresi gibi dizilmez. */
.type-mono-lg {
  font-family: var(--type-mono-lg-family);
  font-size: var(--type-mono-lg-size);
  letter-spacing: var(--type-mono-lg-letter-spacing);
  font-variant-numeric: tabular-nums;
}

/* ===== src/components/Button.css ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid transparent;
  border-radius: var(--rounded-md);
  background-color: transparent;
  font-family: var(--type-body-md-family);
  font-size: var(--type-body-md-size);
  font-weight: 600;
  line-height: var(--type-body-md-line-height);
  cursor: pointer;
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn-primary {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-fill);
}

.btn-primary:hover:not(:disabled),
.btn-primary:active:not(:disabled) {
  background-color: var(--color-primary-deep);
  border-color: var(--color-primary-deep);
}

/* IKINCIL DUGME KENDI KAGIDINI TASIR (DEC-243). Eski hal seffaf zemin +
   {colors.ink} kenardi; yeni dilde ikincil aksiyon bir YUZEYDIR ve kenari
   {colors.line-strong} ile cizilir — cunku o kenar dugmenin SINIRINI
   TANIMLAYAN cizgidir ve WCAG 1.4.11 geregi >=3:1 olculur. {colors.line}
   dekoratif kil cizgidir ve bir kontrol sinirini tasiyamaz. */
.btn-secondary {
  background-color: var(--color-surface);
  border-color: var(--color-line-strong);
  color: var(--color-ink);
}

.btn-secondary:hover:not(:disabled),
.btn-secondary:active:not(:disabled) {
  background-color: var(--color-fill-soft);
  border-color: var(--color-ink-soft);
}

/* METIN TOKENI `--color-on-fill`DIR, `--color-surface` DEGIL (DEC-243).
   Ikisi acik temada ayni degeri tasiyordu ve fark gorunmuyordu; ama kontrast
   matrisinin OLCTUGU cift `on-fill / primary`dir. Olculmeyen bir tokeni
   kullanmak, yesil bir kapinin ekranda karsiligi olmayan bir cifti
   dogrulamasi demekti — koyu temada surface (#1A1A23) ile on-fill (#16182B)
   ZATEN ayrisiyor. */

/* Yıkıcı işlem: yalnız onay modalındaki nihai düğme dolgulanır (DESIGN). */
.btn-danger {
  background-color: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-on-fill);
}

.btn-ghost {
  color: var(--color-primary);
}

.btn-ghost:hover:not(:disabled),
.btn-ghost:active:not(:disabled) {
  color: var(--color-primary-deep);
}

/* ===== src/components/Panel.css ===== */

/* Panel/kart — surface zemin + 1px line kenar + ölçülü yükseltme gölgesi.
   DEC-243: gölge çizginin YERİNE geçmez, onunla BİRLİKTE çalışır — kenar formu
   çizer, gölge kâğıdın kalktığını söyler. Köşe merdiveninde panel {rounded.xl}
   basamağıdır: kabuk (2xl) > panel (xl) > kart (lg) > düğme (md) > çip (sm).
   İç eleman dış kabından bir kademe DAHA KESKİN olur; ters yön gözü yanıltır. */

.panel {
  /* DOLGU BIR DEGISKENDEN OKUNUR, DOGRUDAN YAZILMAZ (TASK-264).
     Sebebi başlık rayıdır: ray panelin kenarlarına TAŞAR ve taşmanın ölçüsü
     panelin kendi dolgusudur. Dolgu doğrudan yazılsaydı, onu ezen her sınıf
     (`padding: 0` ile kenardan kenara kurulan tablo panelleri) rayı sessizce
     panelin DIŞINA taşırdı — çünkü ray eski değeri okumaya devam ederdi.
     Değişken bunu yapısal olarak imkânsız kılar: dolguyu ezen sınıf
     `--panel-dolgu` değerini değiştirir ve ray onu KENDILIGINDEN izler. */
  --panel-dolgu: var(--space-lg);

  background-color: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--rounded-xl);
  box-shadow: var(--shadow-raised);
  padding: var(--panel-dolgu);
}

/* KONTROL YUZEYI SUSAR (TASK-264; kullanıcı kararı DEC-212).

   Ölçülen kusur, görevin teşhisinin ikinci yarısıydı: gönderi listesinde filtre
   paneli ile TABLO paneli birebir aynı ağırlıktaydı (ikisi de {colors.surface}
   + 1px kenar + {shadow.raised}). Yani sayfanın var oluş sebebi olan veri ile
   onu süzen denetim kümesi, göze aynı şeyi söylüyordu; bir sayfada her şey
   öne çıkıyorsa hiçbir şey öne çıkmaz.

   Ayrım DESIGN.md §Elevation & Depth'in KENDI merdiveninden kurulur — önce
   boşluk, sonra çizgi, sonra fill-soft, en son gölge. Kontrol yüzeyi üçüncü
   basamakta durur ve DÖRDÜNCÜYE ÇIKMAZ: gölge yalnız verinin kâğıdında kalır.
   Yeni bir gölge seviyesi AÇILMAZ, mevcut olan DAHA AZ yerde kullanılır
   (DEC-142 iki katman kuralı bu yönde de aynen geçerlidir).

   Kenar {colors.line} olarak KALIR: form hâlâ cetvelle çizilir, kaldırılan tek
   şey yükselmedir. */
.panel-kontrol {
  background-color: var(--color-fill-soft);
  box-shadow: none;
}

/* BAŞLIK RAYI (TASK-264) — panelin ilk çocuğu bir Toolbar olduğunda.

   NEDEN KURAL BURADA, Toolbar.css'te DEĞİL. Ray panelin kenarlarına taşar ve
   taşmanın ölçüsü panelin KENDİ dolgusudur; o ölçüyü bilen tek dosya burasıdır.
   Kuralı Toolbar'a yazmak, kabuğu içinde durduğu kabın dolgusu hakkında
   varsayım yapmaya zorlardı — ve panel dışında kullanılan bir araç çubuğu
   sessizce yanlış yere taşardı (POLA).

   NEDEN SEÇİCİ `:first-child`. Ray, panelin BAŞLIĞI olduğunda bir banttır;
   ortasında duran bir araç çubuğu ise bölüm ayracıdır ve taşmamalıdır. Seçici
   bu ayrımı yapının kendisinden okur, sayfanın hatırlamasına bırakmaz. JSX
   yorumları DOM düğümü üretmediği için araya yazılmış bir açıklama seçiciyi
   bozmaz.

   ZEMİN {colors.fill-soft}, GÖLGE DEĞİL. DESIGN.md §Elevation & Depth'in
   sıralaması şudur: önce boşluk, sonra çizgi, sonra fill-soft, en son gölge.
   Ölçüm bu sıralamanın kod tarafında TERS işlediğini gösterdi — 3.400 satırlık
   CSS'te fill-soft yalnız dört yerde tüketiliyor, buna karşılık en pahalı araç
   olan gölge her panelin varsayılanı. Ray üçüncü basamağı kullanır ve DEC-142'nin
   iki katman kuralı aynen durur: YENİ BİR GÖLGE SEVİYESİ AÇILMAZ.

   ALT KURAL Toolbar'ın KENDİSİNDEN gelir (1px {colors.line}); burada ikinci bir
   kenarlık bildirmek aynı çizgiyi iki kez çizerdi.

   ARDINDAKİ BOŞLUK PANELİN İŞİDİR ve bu bilinçli bir sözleşmedir: ray kendi
   bandını çizer, bandın ardındaki aralığı panelin kendi yerleşimi (bugün her
   iki tüketicide de `.form-section` ızgarasının `gap` değeri) verir. Raya alt
   marj yazmak, ızgara aralığıyla toplanıp aralığı iki kez ödetirdi. */
.panel > .toolbar:first-child {
  margin-block: calc(-1 * var(--panel-dolgu)) 0;
  margin-inline: calc(-1 * var(--panel-dolgu));
  /* Rayın KENDI iç dolgusu panelinkinden bağımsızdır ve olmalıdır: kenardan
     kenara kurulan bir veri panelinde (`--panel-dolgu: 0`) taşma sıfırdır ama
     ray metni yine de kenara yapışmamalıdır. */
  padding: var(--space-md) var(--space-lg);
  background-color: var(--color-fill-soft);
  /* Panelin 1px kenarı köşe yarıçapının DIŞINDA kaldığı için rayın yarıçapı
     bir piksel küçüktür; token'dan türetilir, elle yazılmaz. */
  border-start-start-radius: calc(var(--rounded-xl) - 1px);
  border-start-end-radius: calc(var(--rounded-xl) - 1px);
}

/* ===== src/components/Field.css ===== */

/* Form alanı — PAYLAŞILAN kabuk ve denetim derisi (TASK-193).
   Kaynak: DESIGN.md §Components → Yerleşim → Form. Bu dosya TextField.css'in
   yerini aldı: aynı kurallar iki bileşende ayrı ayrı yaşıyordu. */

.field {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xs);
  /* Izgara/flex çocuğu olarak dar kalıba girdiğinde taşmaz. */
  min-width: 0;
}

.field-label {
  color: var(--color-ink-soft);
}

/* Metin girişi, açılır liste ve çok satırlı alanın ORTAK derisi. */
.field-control {
  background-color: var(--color-surface);
  /* KENAR {colors.line-strong}TIR, {colors.ink-soft} DEGIL (DEC-243).
     Eski hal metin murekkebini kenarlik olarak kullaniyordu; yeni palette
     ink-soft KONTRAST MATRISINDE bir METIN murekkebi olarak olculuyor ve bir
     KONTROL SINIRI olarak degil. Sinir cizgisi WCAG 1.4.11 geregi >=3:1
     olculur ve o olcumu tasiyan token line-strong'dur. {colors.line}
     dekoratif kil cizgidir ve bir girdi alaninin sinirini TASIYAMAZ. */
  border: 1px solid var(--color-line-strong);
  /* Merdiven: girdi bir KONTROLdur -> {rounded.md} */
  border-radius: var(--rounded-md);
  padding: var(--space-sm) var(--space-md);
  color: var(--color-ink);
  font-family: var(--type-body-md-family);
  font-size: var(--type-body-md-size);
  line-height: var(--type-body-md-line-height);
  /* Denetim kendi kutusunu AŞMAZ: uzun `value` gövdeyi kaydırmaz.
     `min-width: 0` BİLEREK YOK: bu dosya bileşenle birlikte layout.css'ten
     SONRA yüklenir ve oradaki dokunma hedefi tabanını kaskadda ezerdi
     (ölçüldü — koli ölçü alanları 44px yerine 37px kaldı). Daralma zaten
     `max-width` ve sarmalayıcı `.field`in kendi `min-width: 0`ı ile sağlanır. */
  max-width: 100%;
}

.field-control:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 0;
  border-color: var(--color-primary);
}

.field-control-invalid {
  border-color: var(--color-danger);
}

.field-error {
  color: var(--color-danger);
  font-family: var(--type-body-sm-family);
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line-height);
}

/* KALICI BİÇİM KURALI — görsel olarak gizli, erişilebilirlik ağacında VAR
   (TASK-453; DEC-420 KK-7). Süzgeç bir karakteri reddettiğinde gören
   kullanıcı karakterin görünmediğini OKUR; ekran okuyucu kullanıcısı hiçbir
   şey duymaz. Bu satır o sessizliği kapatır ve `aria-describedby` ile alana
   bağlıdır.

   `display: none` DEĞİL: gizlenen düğüm erişilebilirlik ağacından da düşer ve
   metin hiç okunmaz — yani tam olarak kapatmak istediğimiz sessizliği
   üretirdi. Kırpma kalıbı düğümü ağaçta tutar.

   MUTLAK KONUMLUDUR ve bu bilinçlidir: `.field` bir ızgaradır, akışta kalan
   1px'lik bir düğüm kendi satırını açar ve alanın altında `gap` kadar boşluk
   bırakırdı (koli tablosunda her satırda). */
.field-yardim,
.field-label-gizli {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ALANIN NE OLDUĞUNU SÖYLEYEN GÖRÜNÜR AÇIKLAMA (TASK-488; DEC-474).
   `.field-yardim`in TERSİ ve bu bilinçlidir: orada okunması gereken kişi
   ekran okuyucu kullanıcısıydı, burada GÖREN kullanıcıdır. Kavram
   karışıklığını kapatan şey metnin GÖRÜNMESİDİR; kırpılmış bir satır
   görevin çözdüğü kusuru hiç çözmezdi.

   Akışta kalır (mutlak konumlu DEĞİL): satırını açması İSTENEN davranıştır,
   alanın altında okunur. `.field-yardim`in mutlak konumu koli tablosundaki
   satır başına tekrardan gelir; bu açıklama form alanında BİR KEZ durur.

   Ton {colors.ink-soft}: etiket ve değerden geri durur, hata satırıyla
   ({colors.danger}) karışmaz. */
.field-aciklama {
  color: var(--color-ink-soft);
}

/* ===== src/components/DataTable.css ===== */

/* Tablo — thead {typography.label-xs}, satırlar 1px cetvel, sayısal kolonlar
   mono ve sağa yaslı (DESIGN.md §Components → Yerleşim). */

.data-table {
  width: 100%;
  border-collapse: collapse;
  /* Kaydırma kutusu içinde daralmaz: kolonlar okunur kalır, kutu kayar. */
  min-width: max-content;
}

.data-table-caption {
  color: var(--color-ink-soft);
  text-align: left;
  padding-bottom: var(--space-sm);
}

/* Görsel düzenden çıkar ama erişilebilirlik ağacında KALIR. */
.data-table-caption-gizli {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* BAŞLIK BANDI (TASK-264) — kolon etiketleri artık YÜZEN bir satır değil,
   kendi zemini olan bir BANTTIR.

   Ölçülen kusur şuydu: `thead` beyaz yüzeyin üstünde duruyor ve altındaki
   çizgi, iki veri satırını ayıran çizginin AYNISIYDI. Yani tablonun başlığı
   ile bir kayıt ayracı ekranda aynı işareti çiziyordu; göz her tabloda
   "nerede başlıyor" sorusunu yeniden çözmek zorunda kalıyordu.

   Onarım DESIGN.md §Elevation & Depth'in KENDİ merdivenini kullanır — önce
   boşluk, sonra çizgi, sonra fill-soft, en son gölge. Üçüncü basamak
   ({colors.fill-soft} bölüm zemini) sözleşmede yazılıydı ama kod tabanının
   3.400 satırlık CSS'inde yalnız dört yerde tüketiliyordu; buna karşılık en
   pahalı araç olan gölge her panelin varsayılanıydı. Bant o tersliği düzeltir
   ve YENİ BİR GÖLGE SEVİYESİ AÇMAZ (DEC-142 iki katman kuralı aynen durur).

   Alt kural {colors.line-strong}'a çıkar ama 1px KALIR: başlık/veri sınırı
   satır/satır sınırından GÜÇLÜ olmalıdır, çünkü biri kaydı diğerinden ayırır,
   öteki tablonun nerede başladığını söyler. 2px'e çıkmak DEC-197'nin belge
   kuralıydı ve o kural sayfa başlığına aittir (bkz. Toolbar.css). */
.data-table th {
  text-align: left;
  color: var(--color-ink-soft);
  font-family: var(--type-label-xs-family);
  font-size: var(--type-label-xs-size);
  font-weight: var(--type-label-xs-weight);
  letter-spacing: var(--type-label-xs-letter-spacing);
  text-transform: var(--type-label-xs-transform);
  padding: var(--space-sm) var(--space-md);
  background-color: var(--color-fill-soft);
  border-bottom: 1px solid var(--color-line-strong);
  white-space: nowrap;
}

/* SATIR YOĞUNLUĞU İLKELE AİTTİR (TASK-196).
   Bu satır dört tüketicinin BAĞIMSIZ OLARAK aynı değeri seçtiği yerdi: admin,
   portal ve dokuz SPA sayfasının hepsi tablo satırlarını {typography.body-sm}
   diziyordu. Dört ayrı bildirim, tek bir ortak karardı — yani ilkelin işi.

   Ayrıca bu bir ONARIMDIR: TASK-195 admin ve portaldaki kopyaları kaldırırken
   kuralı ilkele TAŞIMAMIŞTI, dolayısıyla o iki yüzeyin tablo metni 13px'ten
   15px'e çıkmıştı — adı konmamış bir yoğunluk değişikliği. Kural buraya
   girince üç yüzey de tek bildirimden okur ve eski yoğunluk geri gelir.

   OKUMA RİTMİ (TASK-264): hizalama `top`tan `middle`a döndü. Üstten hizalama
   tek satırlık hücrelerin doğru olduğu bir varsayımdı; gerçekte gönderi
   satırının durum hücresi damga + mikro omurgadan oluşan İKİ katmanlı bir
   yığındır ve `top` ile o yığın satırı yukarı asıyor, geri kalan yedi hücrenin
   metni satırın optik ortasının ÜSTÜNDE kalıyordu. Sonuç, satırdan satıra
   kayan bir taban çizgisiydi: bir tabloda göz tam olarak o çizgiyi izler. */
.data-table td {
  padding: var(--space-sm-md) var(--space-md);
  border-bottom: 1px solid var(--color-line);
  vertical-align: middle;
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line-height);
}

.data-table tbody tr:last-child td {
  border-bottom: 0;
}

/* Sayısal ve tanımlayıcı hücreler: mono, tabular, sağa yaslı. */
.data-table-num {
  font-family: var(--type-mono-md-family);
  font-size: var(--type-mono-md-size);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* ===== src/components/Toolbar.css ===== */

/* Araç çubuğu — bölüm başlığı solda, eylemler sağda; dar ekranda SARAR.
   Ayrım cetvelle kurulur, dolguyla değil (DESIGN.md §Elevation & Depth:
   önce boşluk, sonra çizgi, sonra fill-soft, en son gölge). */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm-md);
  padding-bottom: var(--space-md);
  /* CETVEL AĞIRLIĞI 2px'TEN 1px'E İNDİ (TASK-264; DEC-211).

     Kural buraya TASK-263'ten önce, Toolbar sayfa başlığıyken girmişti ve o
     zaman doğruydu: DEC-197 "ince kural VERİYİ böler, kalın kural BELGEYİ
     tanımlar" der ve bir sayfa başlığı o sayfanın belge başlığıdır. TASK-263
     sayfa başlığını PageHeader'a taşıyınca Toolbar BÖLÜM başlığına daraldı —
     ama kalın kural onunla birlikte taşınmadı ve geride, kendi gerekçesini
     yitirmiş bir işaret kaldı.

     Bedeli ölçüldü: bir panelin içindeki `Koliler` bandı, sayfanın kendi
     başlığıyla AYNI ağırlıkta bir kural çiziyordu. Görevin teşhisi olan "her
     şey aynı görsel ağırlıkta" cümlesinin tam olarak bir örneği budur; iki
     farklı hiyerarşi seviyesi aynı işareti kullandığında hiyerarşi ekranda
     yoktur. 2px {colors.line-strong} artık YALNIZ belge başlıklarındadır:
     PageHeader'ın bandı ve DocumentSheet'in masthead'i. */
  border-bottom: 1px solid var(--color-line);
}

.toolbar-baslik {
  gap: var(--space-sm);
}

/* Yardımcı metin — bölümün ne olduğunu bir cümleyle söyler ve başlıkla AYNI
   hizada durur (kümenin kendisi sarar, dolayısıyla dar ekranda alta iner).
   Başlıktan sönüktür: sıralamayı göz her seferinde yeniden çözmek zorunda
   kalmasın diye ağırlık farkı ADIYLA kurulur. */
.toolbar-yardimci {
  margin: 0;
  color: var(--color-ink-soft);
}

/* Sarma gerçekleştiğinde eylemler sola kayar; sağa yaslı bırakmak dar
   ekranda başlıkla eylem arasında boş bir koridor bırakırdı. */
.toolbar-eylemler {
  gap: var(--space-sm);
}

/* ===== src/components/EmptyState.css ===== */

/* "Boş evrak" bloğu — kesikli cetvel çerçeve, ortalanmış tek cümle, tek
   aksiyon. Kesikli kenar bilinçlidir: dolu bir evrakla karışmasın, ama
   dolgu/gölge de eklemesin (DESIGN.md dokuz durum → empty). */

.empty-state {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  gap: var(--space-sm-md);
  padding: var(--space-xl) var(--space-lg);
  border: 1px dashed var(--color-line);
  border-radius: var(--rounded-md);
  text-align: center;
}

.empty-state-baslik {
  color: var(--color-ink-soft);
}

.empty-state-metin {
  max-width: 42ch;
  color: var(--color-ink);
}

.empty-state-eylem {
  margin-top: var(--space-xs);
}

/* ===== src/components/Drawer.css ===== */

/* Çekmece — kenardan açılan kâğıt. Modal ile aynı dil: {colors.surface}
   yüzey, 1px {colors.line} kenar, koyu %40 perde, {shadow.overlay}
   (DESIGN.md §Components → Yerleşim → Modal). */

.drawer-katman {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
}

.drawer-perde {
  position: absolute;
  inset: 0;
  /* Perde artık {colors.scrim} TOKEN'ıdır ve TEMAYA GÖRE değişir (DEC-216).
     Önceki hüküm perdeyi tema-bağımsız tek bir koyulukta tutuyordu ve
     gerekçesi doğruydu — perdenin işi rengi değil derinliği söylemektir — ama
     SEÇİLEN DEĞER o gerekçeyi koyu temada yerine getiremiyordu: sabit ton v1'in
     sıcak mürekkebiydi (#1C1B18) ve koyu tema kâğıdı (#0D1524) ondan KOYU
     olduğu için perde kırmızı ve yeşil kanalda zemini karartmak yerine AÇIYORDU
     (ölçüm: zemin deltası 1,004:1 — evidence/TASK-266). Karartmak orada bir
     tercih değil, fiziksel olarak imkânsızdı. Token iki temada da GERÇEKTEN
     karartır; tema-bağımsızlık ilkesinin yerini tema-bağımsız SONUÇ aldı. */
  background-color: var(--color-scrim);
}

/* Yüzey {colors.surface-overlay}'dir, {colors.surface} DEĞİL (DEC-216). Açık
   temada ikisi AYNI değerdir — orada derinliği gölge taşır. Koyu temada üst
   katman bir kademe AÇIK bir zemin alır, çünkü koyu zeminde koyu gölgenin
   fiziksel tavanı 1,150:1'dir: saf siyah %100 bile açık temanın 1,270:1'ini
   veremez. Ölçülen sonuç kâğıda karşı 1,069:1 -> 1,252:1. */
.drawer-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(100%, 320px);
  height: 100%;
  background-color: var(--color-surface-overlay);
  box-shadow: var(--shadow-overlay);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.drawer-panel-left {
  margin-right: auto;
  border-right: 1px solid var(--color-line);
}

.drawer-panel-right {
  margin-left: auto;
  border-left: 1px solid var(--color-line);
}

/* GENIS CEKMECE (TASK-446; DEC-408): bir KAGIT tasiyan cekmece. Etiket
   onizlemesi A4'u gercek olcusuyle (794px) yerlestirip kabina zoom ile
   sigdirir; 320px'lik kapta olcek 0,34'e duser ve kagit okunmaz. 720px
   okunur bir olcek (0,85) verir; dar ekranda `min()` yine tam genisliktir. */
.drawer-panel-genis {
  width: min(100%, 720px);
}

/* Panelin kendisi odaklanabilir (tabIndex=-1) ama halka yalnız klavye
   yolunda görünür — fare tıklamasında değil. */
.drawer-panel:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.drawer-baslik-bandi {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  border-bottom: 1px solid var(--color-line);
}

.drawer-kapat {
  background: none;
  border: 1px solid var(--color-ink);
  border-radius: var(--rounded-sm);
  color: var(--color-ink);
  padding: var(--space-xs) var(--space-sm-md);
  font-family: var(--type-body-sm-family);
  font-size: var(--type-body-sm-size);
  cursor: pointer;
}

.drawer-kapat:hover {
  background-color: var(--color-fill-soft);
}

.drawer-govde {
  padding: var(--space-lg);
}

/* ===== src/components/Popover.css ===== */

/* Popover — çapaya bağlanan katman (TASK-201; DEC-155). Modal ve çekmece ile
   aynı dil: {colors.surface} yüzey, 1px {colors.line} kenar, {shadow.overlay}
   (DESIGN.md §Elevation & Depth → içeriğin üstünde duran kâğıt).

   PERDE YOKTUR VE BU BİLİNÇLİDİR. Çekmece sayfayı kilitler; popover üst
   bardaki bir düğmenin yanına açılan küçük bir kâğıttır. Perde koymak onu
   modal'a çevirir, arkadaki içeriği tıklanamaz yapar ve "küçük bir menü için
   orantısız" diye reddedilen çekmece seçeneğine (DEC-155 (A)) geri götürürdü.

   ÇAPADAN TAŞMAZ — YAPISAL OLARAK. Katman çapanın SAĞ kenarına hizalanır ve
   sola doğru açılır. Üst bardaki düğmeler sağ uçta durduğu için sola açılmak
   sağ taşmayı imkânsız kılar; sol tarafa taşan içerik ise LTR yazımda
   `scrollWidth` büyütmez, yani gövdeyi kaydırmaz. Genişlik ayrıca görüntü
   alanına bağlanır: dar ekranda kâğıdın kendisi küçülür (DESIGN.md §Gövde
   asla yatay kaymaz — kural `overflow-x: hidden` ile KAPATILMAZ, taşma
   yapısal olarak imkânsız kılınır). */

.popover-capa {
  position: relative;
  display: inline-flex;
}

.popover {
  position: absolute;
  /* Çapanın ALTINA, bir tık boşlukla: katman düğmeyi örtmez, ona bağlı
     olduğunu boşlukla söyler. */
  top: calc(100% + var(--space-xs));
  right: 0;
  /* Çekmecenin (50) ALTINDA kalır: tam ekran katman açıldığında üste o
     çıkmalıdır. Çevrimdışı bandı (20) ise altta kalır. */
  z-index: 40;
  width: max-content;
  min-width: min(16rem, calc(100vw - var(--space-lg)));
  max-width: min(24rem, calc(100vw - var(--space-lg)));
  padding: var(--space-sm-md);
  /* {colors.surface-overlay} — çekmece ve modalla AYNI hüküm (DEC-216). Açık
     temada {colors.surface} ile aynı değerdir; koyu temada bir kademe açılır.
     Popover'ın perdesi olmadığı için bu katmanın tek yükselme kanalı buydu ve
     ölçüm onu 1,069:1'de buldu — kenarı olan düz bir dikdörtgen. */
  background-color: var(--color-surface-overlay);
  border: 1px solid var(--color-line);
  border-radius: var(--rounded-lg);
  box-shadow: var(--shadow-overlay);
}

/* Katmanın kendisi odaklanabilir (tabIndex=-1) — içeride odaklanacak bir öğe
   yoksa odak buraya girer. Halka yalnız klavye yolunda görünür. */
.popover:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

/* ===== src/components/ThemeToggle.css ===== */

/* Tema anahtarı — iki durum, ikonlu (TASK-202; DEC-156, TASK-301 madde 6).

   GÖRSEL FORM YENİLENDİ, ERİŞİLEBİLİRLİK BAĞI AYNEN DURUYOR. Değişen şey
   kontrolün NASIL göründüğüdür; `role="switch"` + `aria-checked` sözleşmesi
   (DEC-156) ve durumun o nitelikten TÜRETİLMESİ dokunulmadan kaldı.

   HAP KÖŞE ARTIK VAR — VE BU BİR SÜRÜKLENME ONARIMIDIR. Bu dosyanın önceki
   yorumu "hap köşe makine kuralıyla yasaktır, tavan {rounded.lg}'dir" diyordu;
   o hüküm DEC-243 ile DÜŞTÜ. Yasak biçim değiştirdi ama silinmedi: serbest
   olan {rounded.full} TOKENIDIR, elle yazılmış `9999` hâlâ reddedilir. Anahtar
   bu yüzden artık gerçek bir raydır.

   ETKİN YÜZ RENKLE DEĞİL YÜZEYLE İŞARETLENİR ve bu, tercihten daha güçlü bir
   sebeple böyle: önceki hâl etkin yüzü {colors.primary} ile DOLDURUYORDU, yani
   üst barda sayfanın TEK dolu birincil elemanıyla aynı ağırlıkta ikinci bir
   dolu eleman duruyordu ("Sayfada TEK dolu birincil düğme bırak" — DESIGN.md
   Do's). Yeni hâl sözleşmenin kendi kuralını izler: "Aktif/seçili durumu
   YÜZEYLE işaretle (kalkmış pill + gölge + kenar), rengi üçüncü kanal olarak
   kullan." Kalkan yüz {colors.surface} kâğıdına çıkar, {shadow.raised} taşır
   ve mürekkebi {colors.ink} olur.

   İKİ DURUM DA GÖSTERİLİR ve bu dürüst bir kazançtır: kullanıcı hem nerede
   olduğunu hem neye geçeceğini görür. */

.tema-anahtari {
  display: inline-flex;
  align-items: center;
  padding: 2px;
  gap: 2px;
  background-color: var(--color-fill-soft);
  border: 1px solid var(--color-line);
  border-radius: var(--rounded-full);
  cursor: pointer;
}

.tema-anahtari-yuz {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid transparent;
  border-radius: var(--rounded-full);
  color: var(--color-ink-soft);
  transition:
    background-color var(--motion-fast) var(--motion-ease),
    box-shadow var(--motion-fast) var(--motion-ease),
    color var(--motion-fast) var(--motion-ease);
}

/* ETKİN YÜZ KALKAR — ve hangisinin etkin olduğunu `aria-checked` söyler.
   Görsel hâl bağdan TÜRETİLİR; ikinci bir sınıf ya da data niteliği
   tutulmaz. Bağ koparsa görsel de bozulur, yani sessizce kaybolamaz. */
.tema-anahtari[aria-checked='false'] .tema-anahtari-acik,
.tema-anahtari[aria-checked='true'] .tema-anahtari-koyu {
  background-color: var(--color-surface);
  border-color: var(--color-line);
  box-shadow: var(--shadow-raised);
  color: var(--color-ink);
}

/* Etkin OLMAYAN yüz hover'da mürekkebe koyulur; kalkmış yüz kendi hâlini
   korur — bir hover geri bildirimi, durum işaretini bastırmamalıdır. */
.tema-anahtari:hover .tema-anahtari-yuz {
  color: var(--color-ink);
}

.tema-anahtari:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .tema-anahtari-yuz {
    transition: none;
  }
}

/* ===== src/components/UserMenu.css ===== */

/* Hesap menüsü — üst bardaki kullanıcı çapası ve içeriği (TASK-204; DEC-155,
   TASK-301 madde 5).

   BU DOSYA İKİ YÜZEYE ÜRETİLİR (DEC-150): SPA'daki UserMenu ile admin
   kabuğundaki Blade karşılığı AYNI sınıf adlarını taşır ve kuralları
   /ilkeller.css üzerinden AYNI kaynaktan alır. Admin'e elle kopyalansaydı bir
   bildirim iki yerde yaşar, biri tazelenir, öteki kalırdı.

   Katmanın kendisi (yüzey, kenar, gölge, konumlanma, taşma kelepçesi) Popover
   ilkelinindir ve burada YENİDEN KURULMAZ.

   ÇAPA ARTIK DAİRESELDİR ve bu bir tercih değil sözleşmenin kendi tarifidir:
   DESIGN.md "Yerleşim" bölümü üst bandı yazarken "sağda dairesel ikon
   düğmeleri" diyor. Önceki hâl zeminsiz, kenarsız düz bir ikondu — kullanıcı
   (2026-08-19) üst bar denetimleri için "eski duruyor" dedi ve eksik tam
   olarak buydu: tarif ekranda yoktu.

   KART VARYANTI KALDIRILDI (`.hesap-capa-kart`). Hesap menüsü rayın dibinden
   üst bara döndü ve orada TEK kaldı (DEC-246 dalgasının 5. maddesi); kartın
   yaşadığı yer kalmayınca kuralı da kalmadı. Rayın dibindeki kimlik kutusu
   yerine SADE bir çıkış eylemi durur (PanelLayout.css `.panel-cikis`). */

.hesap-capa {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* DOKUNMA HEDEFİ İKİ BOYUTLUDUR: ikon 18px çizilir, hedef {layout.tap-target}
     olmalıdır (TASK-203'te bildirim çapasında ölçülmüş kusur; aynı hata burada
     tekrarlanmasın diye taban baştan yazıldı). */
  min-height: var(--layout-tap-target);
  min-width: var(--layout-tap-target);
  padding: 0;
  background-color: var(--color-fill-soft);
  border: 1px solid var(--color-line);
  border-radius: var(--rounded-full);
  color: var(--color-ink);
  cursor: pointer;
  transition:
    background-color var(--motion-fast) var(--motion-ease),
    color var(--motion-fast) var(--motion-ease);
}

.hesap-capa:hover {
  background-color: var(--color-surface);
  color: var(--color-primary-deep);
}

.hesap-capa:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .hesap-capa {
    transition: none;
  }
}

/* E-POSTA DAR EKRANDA DA GÖRÜNÜR — bu görevin onardığı bilgi kaybı budur.
   Uzun bir e-posta kutuyu aşmasın diye kırılır; kırpılmaz, çünkü kırpılmış bir
   adres yanlış okunabilir. */
.hesap-menusu-eposta {
  margin: 0;
  color: var(--color-ink-soft);
  overflow-wrap: anywhere;
}

/* KİMLİK BAŞLIĞI — katmanın içindeki avatar + ad + e-posta (TASK-302 madde 3).
   Kartın rayda yaptığı işi (kim olarak gezdiğini söylemek) artık katmanın
   kendisi yapar, yani bilgi kaybolmadı, yeri değişti — ve zenginleşti:
   kullanıcının ADI bugüne kadar hiç gösterilmiyordu, oysa oturumla birlikte
   zaten çözülmüştü. */
.hesap-menusu-kimlik {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
  min-width: 0;
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-line);
}

.hesap-menusu-kimlik__metin {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Ad BİRİNCİ satırdır ve gövde mürekkebindedir; e-posta ikincildir. İkisi eşit
   ağırlıkta olsaydı göz hangisinin kimlik olduğunu her seferinde yeniden
   çözerdi (sayfa başlığı bandındaki bağlam/başlık ayrımıyla aynı gerekçe). */
.hesap-menusu-ad {
  color: var(--color-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* KISAYOLLAR — menü bir kimlik kutusu olduğu kadar bir gezinme noktasıdır.
   `<Link>`tirler (bkz. UserMenu.tsx gerekçesi) ve menü öğesi ölçeğinde
   {rounded.md} taşırlar. */
.hesap-menusu-kisayollar {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hesap-menusu-baglanti {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
  min-height: var(--layout-tap-target);
  padding: var(--space-sm) var(--space-sm-md);
  border-radius: var(--rounded-md);
  color: var(--color-ink);
  font-family: var(--type-body-sm-family);
  font-size: var(--type-body-sm-size);
  text-decoration: none;
  transition: background-color var(--motion-fast) var(--motion-ease);
}

.hesap-menusu-baglanti:hover {
  background-color: var(--color-fill-soft);
}

@media (prefers-reduced-motion: reduce) {
  .hesap-menusu-baglanti {
    transition: none;
  }
}

.hesap-capa__avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--rounded-full);
  background-color: color-mix(in srgb, var(--color-accent) var(--tint-surface), var(--color-surface));
  color: var(--color-accent);
  font-family: var(--type-body-sm-family);
  font-size: var(--type-body-sm-size);
  font-weight: 700;
  line-height: 1;
}

/* ===== src/components/PageHeader.css ===== */

/* Sayfa başlığı — KOMPAKT bant: bağlam üstte, başlık ve durum yan yana,
   eylemler sağda (TASK-263; DEC-208, DEC-209, DEC-210).

   DİKEY BÜTÇE ADIYLA YAZILMIŞTIR ve bandın "yaklaşık 56px" hedefi buradan
   çıkar, göz kararından değil:
     4px  (üst dolgu, --space-xs)
   + 13px (bağlam satırı: 11px x 1.15)
   + 2px  (bağlam ile başlık arası)
   + 27px (başlık: 21px x 1.3)
   + 8px  (alt dolgu, --space-sm)
   + 1px  (ayraç cetveli)
   = 55px
   Dolgu BİLEREK asimetriktir: üstte bant üst bara dayanır ve nefes payı
   gerekmez, altta cetvelin okunması için boşluk gerekir. Eylem düğmesi
   41px'dir, yani solun 42px'lik kolonundan alçaktır ve bandı BÜYÜTMEZ. */

.sayfa-basligi {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm-md);
  padding-block: var(--space-xs) var(--space-sm);
  /* CETVEL YUMUŞADI (DEC-247): 2px {colors.line-strong} → 1px {colors.line}.
     Önceki hükmün gerekçesi bir MATBAA ayrımıydı ("ince kural VERİYİ böler,
     kalın kural BELGEYİ tanımlar", DEC-197/DEC-211) ve o metafor DEC-243 ile
     emekli olan dünyanın kalıntısıydı: yeni dil yumuşak pastel bir panodur,
     bir konşimento değil. Kullanıcı (2026-08-19) çizgiyi "çok siyah keskin"
     diye adlandırdı ve tarif ölçümle uyuştu — {colors.line-strong} #73738A'dır
     ve 2px'te gerçekten bir cetvel gibi okunur.

     DOCUMENTSHEET MASTHEAD'İ DEĞİŞMEDİ ve bu bir tutarsızlık değil ayrımın
     KENDİSİDİR: orası gerçekten bir BELGE artefaktıdır (sevk evrakı) ve matbaa
     ayrımı orada hâlâ doğrudur. Burası uygulamanın kendi başlığıdır.

     ÇİZGİ KALDIRILMADI, YUMUŞATILDI: bandın nerede bittiğini söyleyen tek
     işaret budur ve yapışkan bant kaydırmada içeriğin üstünden geçerken o
     sınır okunur kalmalıdır. */
  border-bottom: 1px solid var(--color-line);
}

.sayfa-basligi__sol {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
}

/* Bağlam satırı — bulunulan yer. Başlıktan SÖNÜK olması bilinçlidir: sayfanın
   adı birincil, yeri ikincildir; ikisi eşit ağırlıkta olsaydı göz hangisinin
   sayfa olduğunu her seferinde yeniden çözmek zorunda kalırdı. */
.sayfa-basligi__baglam {
  color: var(--color-ink-soft);
  line-height: 1.15;
}

/* Başlık ve durum AYNI satırda; dar ekranda durum alta sarar. */
.sayfa-basligi__satir {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-sm-md);
}

.sayfa-basligi__ad {
  margin: 0;
}

/* Durum kümesi — sayım ve tazelik. Ayrım CETVELLE kurulur, işaretle değil:
   orta nokta, madde imi ve tire ekrana çıkan yasak işaretlerdir
   (DEC-200/201/203) ve bir ayracın işi zaten çizginin işidir. */
.sayfa-basligi__durum {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm-md);
  min-width: 0;
  color: var(--color-ink-soft);
}

.sayfa-basligi__sayim + .sayfa-basligi__tazelik {
  border-inline-start: 1px solid var(--color-line);
  padding-inline-start: var(--space-sm-md);
}

.sayfa-basligi__tazelik {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  min-width: 0;
}

/* Sinyal noktası — bağlantı kopukken amber ve İÇİ BOŞ, canlıyken {colors.data} ve
   DOLU. Dolu/boş ayrımı rengin YANINDA ikinci bir kanaldır; rengi ayırt
   edemeyen kullanıcı da iki hâli ayırt eder. Durumu taşıyan asıl şey yine de
   yanındaki cümledir (bkz. PageHeader.tsx). */
.sayfa-basligi__sinyal {
  flex: none;
  color: var(--color-warning);
}

.sayfa-basligi__sinyal-canli {
  color: var(--color-data);
}

.sayfa-basligi__eylemler {
  gap: var(--space-sm);
}

/* GENİŞ EKRANDA YAPIŞKAN (DEC-210).

   Bant artık yer harcayan bir başlık değil, sayfanın durumunu ve birincil
   eylemini taşıyan bir KONTROL YÜZEYİDİR; uzun listelerde kaydırıldığında
   ekrandan çıkması, taşıdığı iki bilgiyi birden erişilemez yapardı.

   Eşik {breakpoints.lg}'dir ve YENİ DEĞİLDİR: kabuk aynı eşikte kalıcı menü
   ile çekmeceyi, layout.css aynı eşikte dokunmatik ile masaüstü hedefini
   ayırır. Dar ve orta genişlikte bant AKAR, çünkü orada eylem kümesi SARAR ve
   sarmış bir bandı yapıştırmak zaten kıt olan dikey alandan kalıcı pay alırdı.

   Zemin ŞART: yapışkan bir bandın altından geçen içerik, zemini olmayan bir
   bantta okunur hâlde görünür ve iki metin üst üste biner. `z-index: 10`
   katman sırasını korur — çekmece (50) ve popover (40) bandın ÜSTÜNDE kalır,
   çünkü onlar sayfanın üzerine açılan katmanlardır.

   OTURUM VARYANTI DIŞARIDA BIRAKILIR ve bu `:not()` bir üslup tercihi değil ÖLÇÜLMÜŞ
   bir kusurun onarımıdır: kural başta yalın `.sayfa-basligi` idi ve oturum
   başlığı da onu alıyordu. Sonuç, giriş kartının İÇİNDE {colors.paper}
   zeminli açık bir dikdörtgendi — kart {colors.surface} olduğu için başlığın
   arkasında kutu gibi duruyordu. Ekran görüntüsüne BAKILMASAYDI görülmezdi;
   birim testi de e2e ölçümü de yeşil dönüyordu, çünkü ikisi de yüksekliğe ve
   yapıya bakar, ZEMİNE değil. */
@media (width >= 1024px) {
  .sayfa-basligi:not(.sayfa-basligi-oturum) {
    position: sticky;
    top: 0;
    z-index: 10;
    background-color: var(--color-paper);
  }
}

/* OTURUM VARYANTI (DEC-209) — Giriş, Kayıt, Şifre Sıfırlama, Yeni Şifre.

   Bağlam, durum ve eylem YOKTUR: kullanıcı henüz uygulamanın içinde değildir,
   sayfanın bir tazelik durumu ve bir eylem kümesi yoktur. Kabukta kalan şey
   h1 tekliği ve aralık disiplinidir; ortak OLMAYAN üç alan varyantla birlikte
   yok olur. Yapışkanlık da yoktur — kart zaten ekrana sığar.

   CETVEL YOKTUR ve bu DEC-197'yi delmez. "Kalın kural BELGEYİ tanımlar"
   hükmünün işi belgenin sınırını çizmektir; oturum kartının 1px kenarı o
   sınırı ZATEN çiziyor. İkinci ve daha kalın bir kuralı otuz piksel içeriye
   koymak, aynı sınırı iki kez çizmek olurdu. Panel bandında kural şarttır,
   çünkü orada kartın kenarı yoktur: bant doğrudan kâğıdın üstünde durur. */
.sayfa-basligi-oturum {
  display: block;
  padding-block: 0 var(--space-sm);
  border-bottom: none;
}
