/* ============================
   Veraius Shared Component Styles
   Reusable patterns for all pages
   ============================ */

/* ============================
   Section Card — DESIGN.md: "No-Line" kuralı
   Ayrımı kenarlık değil DÜZLEM KAYMASI taşır.
   ============================
   ÖLÇÜLDÜ 2026-09-15, /agents (117 kart). Kural yorumunda "No-Line" yazıyordu
   ama gövdesi kuralın tam tersini yapıyordu:

     1) `background: var(--surface-container)` = #EEEEEE — bu SAYFA ZEMİNİNİN
        tonu. İki yüzey eşitse kart görünmez olur. Doğrusu `container-lowest`.
     2) `box-shadow: var(--shadow-md)` DURAĞAN halde gölge veriyordu; DESIGN.md
        gölgeyi yalnız `:hover` ("Raised Interactive State") için kabul eder.
     3) `transition: all` — `all` zaten CSS varsayılanı; adlandırılmış özellik
        yazmak neyin animasyonlandığını belirgin kılar.

   Belirti tarayıcıda görünüyordu: taban kart kuralı (`[class*="card "]`)
   kartların çoğunu beyaza çekiyordu, ama `class="… section-card … p-6"` gibi
   sınıf listesi "card" ile BİTMEYEN kartlar kaçıyor ve #EEEEEE + gölge
   kalıyordu — aynı bileşen sayfada iki farklı görünümdeydi. */
.section-card {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    padding: var(--space-5);
    margin-bottom: var(--space-5);
    transition: background var(--transition-card), box-shadow var(--transition-card);
    content-visibility: auto;
    contain-intrinsic-size: auto 200px;
    position: relative;
    overflow: hidden;
}

/* AKSAN ŞERİDİ KPI'YA ÖZGÜDÜR — bölüm kartında YOK (ürün kararı 2026-09-16).
   Burada `::after` ile soldan 3px teal şerit çiziliyordu ve `.section-card`
   392 yerde kullanıldığı için şerit neredeyse HER kartta görünüyordu:
   liste tablosu, form bölümü, metin paneli. Şeridin işi bir SAYIYA dikkat
   çekmek; her kartta olduğunda o anlamı kaybediyor ve yalnız gürültü
   bırakıyor.

   Şerit `.kpi-card` / `.va-kpi` üzerinde durur (bkz. aynı dosyada
   `BothKpiAnatomies_ShareTheAccentBarRule` guard'ı). Bölüm kartının ayrımını
   düzlem kayması taşır — DESIGN.md "No-Line". Kart bölüm türüne göre
   vurgulanacaksa `.card-accent-left` sınıfı BİLİNÇLİ olarak eklenir. */

/* Yükselme HİSSİNİ gölge taşır, renk değil. Taban beyaz (`container-lowest`)
   olduğu için hover'da `container-high`'a (#E8E8E8) geçmek kartı KOYULAŞTIRIR —
   yükselmenin tersi. Zemin sabit kalır, gölge bir kademe artar. */
.section-card:hover {
    box-shadow: var(--shadow-lg);
}

.section-title {
    font-family: var(--font-headline);
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--on-surface);
    margin-bottom: 1rem;
}

.section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
}

/* Başlık + eylem satırında başlığın KENDİ marjı olmaz: 27 sayfa scoped CSS'te
   `.section-title { margin-bottom: … }` yazıyor ve dikeyde ortalı satırda bu marj
   başlığı düğmelerden yukarı itiyordu (ölçüldü 2026-10-19, /simulation/scenarios:
   başlık merkezi 10px, düğmeler 26px). Aradaki boşluğu satırın kendi alt marjı verir.
   Sınıf iki kez yazıldı: scoped kural (0,2,0) sonra yüklenir ve eşit özgüllüğü yener. */
.section-header > .section-title.section-title,
.section-header > :is(h1, h2, h3, h4).section-title,
.section-header-row > .section-title.section-title,
.toolbar-row > :is(h1, h2, h3, h4),
/* Kabuk altındaki flex başlık satırları — scoped `.section-title { margin-bottom }`
   kardeş düğmelerle dikey kayma üretiyordu (ModelEng / simülasyon). */
.ws-shell :is(.section-header, .section-header-row, .toolbar-row, .vsection--split) :is(.section-title, h2, h3) {
    margin-block: 0;
}

.section-header h2 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--on-surface);
}

/* ============================
   Ops Screen — Full page layout for operations pages
   ============================ */
.ops-screen {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--surface);
    padding: 2rem;
    overflow-y: auto;
    gap: 1.5rem;
}

/* ══ KABUK ALTINDA ÇİFT GUTTER ══════════════════════════════════════════════
   ÖLÇÜLDÜ 2026-10-22: 46 sayfa `.page-padding` (1.5rem) + 18 sayfa `.ops-screen`
   (2rem) WorkspaceShell / .app-content-surface GUTTER'ının ÜSTÜNE biniyordu.
   Yüzey zaten `--content-pad-*` taşır; .ws-main ek 0.25rem inline pad taşır.
   İç kaplar yalnız ritim (gap / kardeş margin) için kalır, kenar eklemez. */
.ws-shell .page-padding,
.ws-main .page-padding,
.ws-shell .ops-screen,
.ws-main .ops-screen {
    padding: 0;
    min-height: 0;
    overflow: visible;
    background: transparent;
}

/* Kabuğu saran dış ops-screen (shell kardeş değil, ebeveyn). */
.ops-screen:has(.ws-shell) {
    padding: 0;
    min-height: 0;
    overflow: visible;
    background: transparent;
}

/* Dış page-padding kabuğu SARAR (6 ajan sayfası) — soyundan değil atadan gelir. */
.page-padding:has(.ws-shell) {
    padding: 0;
    min-height: 0;
    overflow: visible;
}

/* Config gövdesi kabuk altında 32×48px ikinci gutter taşıyordu (8 sayfa). */
.ws-shell .config-content,
.ws-main .config-content {
    padding: 0;
}

/* ops-container okuma genişliği kabuk altında 1200px tavanı ile daralıyordu. */
.ws-shell .ops-container,
.ws-main .ops-container {
    max-width: none;
}

/* ÖLÇÜLDÜ 2026-10-22: 69 sayfa `*-screen` kökü (team/analytics space-8, edi/kg 1rem)
   WorkspaceShell gutter'ının üstüne biniyordu. Yatay/üst padding bastırılır;
   alt boşluk (settings-screen vb.) korunur. */
.ws-shell [class$="-screen"],
.ws-main [class$="-screen"] {
    padding-inline: 0;
    padding-block-start: 0;
    background: transparent;
}


/* Araç çubuğu kabukta başlıkla aynı sol kenarı paylaşır — ekstra 1rem inset yok. */
.ws-shell :where(.toolbar-row) {
    padding-inline: 0;
    padding-block: 0.5rem;
}

.ops-container {
    width: 100%;
    max-width: 1200px;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding-bottom: 4rem;
}

.ops-back {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    align-self: flex-start;
}

@media (max-width: 767px) {
    .ops-screen { padding: 1rem; }
}

/* ============================
   Page Patterns
   ============================ */
.page-container,
.page-surface,
.dashboard-page,
.admin-page,
.settings-page {
    width: 100%;
    min-width: 0;
    padding: clamp(1rem, 2vw, 1.5rem);
}

.page-stack {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

/* ARALIK TERS ORANTILIYDI. ÖLÇÜLDÜ 2026-09-04 /admin/rules/create: kartlar arası
   boşluk 16px, kart İÇİ dolgu 24px. Yani kartların içi dışından genişti; göz
   kartları ayrı nesneler olarak değil tek bir gevşek yığın olarak okuyordu.
   Kurumsal ritim bunun tersini ister: nesneler arası mesafe, nesne içi
   mesafeden BÜYÜK olmalı ki gruplama görünsün (yakınlık ilkesi).

   Sabit bir sayı yerine kabın rolüne göre ayrıldı: kart taşıyan bir yığın
   24px'ten geniş açılır, kart İÇİNDEKİ alan yığını 12px'e kapanır. Böylece tek
   sınıf iki bağlamda doğru davranır ve çağrı yerlerinin sınıf seçmesi gerekmez. */
/* `:has(> .vcard)` DENENDİ VE GERİ ALINDI. ÖLÇÜLDÜ 2026-09-04: kural dosyanın
   3122. baytındaydı ve ondan SONRAKİ HER KURAL ÖLDÜ — tarayıcıda .vcard bile
   dolgusuz/zeminsiz kaldı, yalnız başka dosyadan gelen border-radius vardı.
   cssRules 704 yerine 0 okundu. CLAUDE.md'nin uyardığı kusurun aynısı: tek
   geçersiz seçici koca bir stil sayfasını sessizce çöpe atar ve hiçbir test
   görmez. Ayrım artık açık sınıfla yapılıyor — çağrı yeri birini seçer. */
.page-stack--cards {
    gap: var(--space-6, 1.5rem);
}

.vcard .page-stack {
    gap: var(--space-3, 0.75rem);
}

.page-section,
.section-surface {
    min-width: 0;
    padding: 1rem;
    background: var(--surface-container-low);
    border-radius: var(--card-radius);
}

.page-toolbar,
.section-toolbar,
.table-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    min-width: 0;
}

.dashboard-grid,
.metrics-grid,
.card-grid,
.grid-auto-1fr {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
    gap: 1rem;
    min-width: 0;
}

.content-auto {
    min-width: 0;
    max-width: 100%;
}

@media (max-width: 767px) {
    .page-container,
    .page-surface,
    .dashboard-page,
    .admin-page,
    .settings-page {
        padding: 1rem;
    }

    .page-section,
    .section-surface {
        padding: 0.875rem;
    }
}

/* ============================
   Page Header
   ============================ */
/* BAŞLIK BLOĞU GÖVDEDEN AYRIŞIR. ÖLÇÜLDÜ 2026-09-16: `.page-header` yalnız
   yerleşim veriyordu (flex + boşluk), hiçbir görsel ayrım YOKTU — başlık,
   altındaki içerikle aynı düzlemde akıyor ve "sayfa başlığı" olduğu
   okunmuyordu. Ayrımı kenarlık değil ALT BOŞLUK + ince bir hayalet çizgi
   taşır (DESIGN.md "No-Line": 1px opak kenarlık yok, `--ghost-border`
   zaten bu iş için var ve rgba(...,0.08)). */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    margin-bottom: 1.5rem;
    padding-bottom: var(--space-4);
    box-shadow: inset 0 -1px 0 0 var(--ghost-border);
    flex-wrap: wrap;
    width: 100%;
}

/* `.toolbar` PAKETTE YOKTU. ÖLÇÜLDÜ 2026-09-16: markup'ta 128 kullanım var
   ama kanonik tanımı hiç yazılmamış — her sayfa kendi gövdesini yazıyordu
   (19 tanım / 12 farklı gövde). Araç çubuğu, başlık ile içerik arasındaki
   KOMUT şerididir: filtre, arama, toplu eylem. Kendi zeminini taşır ki
   içerikten ayrışsın. */
.toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    background: var(--surface-container);
    border-radius: var(--btn-radius);
    min-width: 0;
}

/* Sağa yaslanan grup — "ara" solda, "eylemler" sağda. */
.toolbar-end {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* Kayıt sayacı ARAÇ ÇUBUĞUNDA durur, başlıkta değil (ürün kararı 2026-09-16).
   Gerekçe ölçüm değil mantık: dönem ve durum birer FİLTREDİR; sayaç onların
   sonucudur. Başlığa koymak filtreyi sonucundan ayırır — kullanıcı 128'in
   34'e düştüğünü ekranın öbür ucunda görür. `tabular-nums` sayının filtre
   değişirken yerinden oynamasını engeller. */
.toolbar-count {
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--on-surface);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Araç çubuğu içi ayraç — gruplar arası nefes. */
.toolbar-divider {
    width: 1px;
    align-self: stretch;
    margin-block: var(--space-1);
    background: var(--ghost-border);
    flex-shrink: 0;
}

/* ══ SAYFA BAŞLIK BLOĞU ══════════════════════════════════════════════════
   ÖLÇÜLDÜ 2026-09-16: bu üçlünün (üst bağlam · başlık · altyazı) kanonik
   dili PAKETTE YOKTU — `.page-title` yalnız punto veriyordu,
   `.page-subtitle` hiç tanımlı değildi, `.breadcrumb` ise yalnız
   `.breadcrumb-nav` kapsayıcısı altında yaşıyordu. Sonuç: her sayfa kendi
   inline stilini yazıyordu ve başlık ile üst bağlam aynı ağırlıkta akıyor,
   aralarında hiyerarşi görünmüyordu.

   Dört varyant çizilip karşılaştırıldı; ÜRÜN KARARI (2026-09-16) "aksan
   çubuğu + büyük başlık": üst bağlam uppercase + geniş harf aralığıyla
   başlıktan net ayrışır, teal çubuk sayfayı sidebar'ın aktif işaretiyle
   AYNI dile bağlar (kullanıcı öğrendiği sinyali korur).

   Kayıt sayacı ve dönem seçici bilinçli olarak BURADA DEĞİL: ikisi de
   filtredir ve araç çubuğunda dururlar (bkz. `.toolbar`). */
/* ══ FORM YARDIM METNİ ═══════════════════════════════════════════════════
   ÖLÇÜLDÜ 2026-09-16: `.form-hint` ve `.form-error` pakette HİÇ tanımlı
   değildi — her form kendi inline stilini yazıyordu ya da hiç yazmıyordu.
   Sınıfsız hâlde ipucu metni 16px/koyu çıkıyor ve GÖVDE metni gibi
   okunuyordu; oysa işi alanı açıklamak, ondan daha sessiz olmalı. */
.form-hint {
    display: block;
    margin-top: var(--space-1);
    font-family: var(--font-body);
    font-size: var(--font-size-sm);
    line-height: 1.45;
    color: var(--on-surface-variant);
}

/* Hata metni ipucunun yerini ALIR, altına eklenmez: ikisi aynı anda
   gösterilince kullanıcı hangisinin geçerli olduğunu bilemez. */
.form-error {
    display: flex;
    align-items: flex-start;
    gap: var(--space-1);
    margin-top: var(--space-1);
    font-family: var(--font-body);
    font-size: var(--font-size-sm);
    line-height: 1.45;
    font-weight: 600;
    color: var(--state-error-text);
}

/* ══ İKON KABI — optik ortalama ═══════════════════════════════════════════
   ÖLÇÜLDÜ 2026-09-16: glif kutusu kabın tam ortasında (sapma 0.0px) ama
   Material Symbols fontunda glifin GÖRSEL ağırlık merkezi kutusunun biraz
   üstünde kalıyor; sonuç gözle "yukarı kaçmış" görünüyor. Matematiksel
   ortalama yetmez, optik düzeltme gerekir. `translateY` glif kutusunu
   değil ÇİZİMİ kaydırır, yani hizalama hesabını bozmaz. */
.icon-tile {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--btn-radius);
    background: color-mix(in srgb, var(--primary) 12%, transparent);
    flex-shrink: 0;
}

.icon-tile > .material-symbols-outlined {
    display: block;
    font-size: var(--icon-md);
    line-height: 1;
    color: var(--primary);
    transform: translateY(0.5px);
}

/* Durum varyantları — ikon kabı da `--state-*` ailesini konuşur. */
.icon-tile--success { background: var(--state-success-bg); }
.icon-tile--success > .material-symbols-outlined { color: var(--state-success-text); }
.icon-tile--warning { background: var(--state-warning-bg); }
.icon-tile--warning > .material-symbols-outlined { color: var(--state-warning-text); }
.icon-tile--error { background: var(--state-error-bg); }
.icon-tile--error > .material-symbols-outlined { color: var(--state-error-text); }

.page-eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
}

/* Marka omurgası — sidebar'ın aktif öğesindeki işaretin aynısı. */
.page-eyebrow::before {
    content: '';
    width: 3px;
    height: 0.75em;
    border-radius: 2px;
    background: var(--primary);
    flex-shrink: 0;
}

.page-eyebrow a {
    color: inherit;
    text-decoration: none;
}

.page-eyebrow a:hover {
    color: var(--primary);
}

/* Ayraç metne DEĞİL kurala ait: markup yalnız parçaları yazar. */
.page-eyebrow > * + *::before {
    content: '/';
    margin-inline-end: var(--space-2);
    opacity: 0.45;
}

.page-title {
    margin: 0 0 var(--space-1);
    font-family: var(--font-headline);
    font-size: var(--font-size-4xl);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
    color: var(--on-surface);
}

.page-subtitle {
    margin: 0;
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    line-height: 1.5;
    color: var(--on-surface-variant);
}

.page-header-left {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-width: 0;
    flex: 1;
}

.page-header-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
}

.page-header-title .material-symbols-outlined {
    font-size: var(--icon-lg);
    color: var(--primary);
    flex: 0 0 auto;
}

/* Sayfa gövdesindeki bölüm başlıkları h1'den h2'ye alınıyor (WorkspaceShell zaten bir
   h1 basıyor — ÖLÇÜLDÜ 2026-08-26: 82 sayfada çift h1). Seçici yalnız h1'i hedeflediği
   için h2 de kapsama alındı; ayrıca sınıf doğrudan başlık ELEMANININ üzerinde de
   kullanılıyor (7 yerde), o durumda bu inen seçici hiç eşleşmiyordu — kendi kuralı
   eklendi ki ince ayar her iki kullanımda da uygulansın. */
.page-header-title h1,
.page-header-title h2,
h1.page-header-title,
h2.page-header-title {
    margin: 0;
    /* ÖLÇÜ AÇIKÇA YAZILIR. ÖLÇÜLDÜ 2026-09-05: bu kural font-size TAŞIMIYORDU,
       yani başlığın boyu tarayıcının etiket varsayılanına kalıyordu — h2 iken
       tesadüfen kanonik ölçüye yakındı, erişilebilirlik için h1'e çevrilince
       36px'e fırladı. Aynı rolün ölçüsü etikete göre değişmemeli;
       WorkspaceShell'in .ws-title'ı ile aynı değer.
       ÖLÇÜLDÜ 2026-09-06: değer 1.3rem SABİT yazılmıştı ve o gün .ws-title da
       öyleydi; sonradan .ws-title --font-size-xl'e (20px) indi, bu kural
       20.8px'te kaldı ve 14 ekranın 2'si sapma oldu. "Aynı değer" niyeti
       ancak AYNI TOKEN'la korunur — kopyalanan sayı sessizce ayrışır.
       TOKEN ADI DA ÖLÇÜLDÜ: önce --font-size-xl yazıldı, ölçüm 18px verdi ve
       sapma büyüdü. xl=1.125rem (18px), referans 20px = --font-size-2xl.
       (WorkspaceShell:176'daki --font-size-xl DENSE varyantına aittir.) */
    font-size: var(--font-size-2xl);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.025em;
    overflow-wrap: anywhere;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.page-header-subtitle {
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
    line-height: 1.55;
    max-width: 72ch;
}

.page-header-precontent,
.page-header-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    color: var(--on-surface-variant);
    font-size: var(--font-size-md);
}

.page-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    justify-content: flex-end;
    flex-wrap: wrap;
    flex-shrink: 0;
    max-width: 100%;
}

.page-header-breadcrumb {
    margin-block-end: 0.25rem;
    font-size: var(--font-size-2xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--on-surface-variant);
}

.page-header-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.625rem;
    margin-inline-start: 0.5rem;
    background: var(--surface-container-high);
    color: var(--primary);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-radius: var(--btn-radius);
    border: 1px solid var(--ghost-border);
}

@media (max-width: 767px) {
    .page-header {
        flex-direction: column;
        align-items: stretch;
    }

    .page-header-actions {
        justify-content: flex-start;
    }

    .page-header-actions > * {
        min-height: 44px;
    }
}

/* ============================
   Stat Card — DESIGN.md: Tonal depth, no borders
   ============================ */
.stat-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-height: 132px;
    padding: var(--space-5) var(--space-5) var(--space-5) 1.375rem;
    /* Kart düzlemi: sayfa zemininden AYRI ton (No-Line kuralı). */
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    transition:
        background var(--transition-default),
        box-shadow var(--transition-default),
        transform var(--transition-default);
    container-type: inline-size;
    content-visibility: auto;
    contain-intrinsic-size: auto 120px;
    position: relative;
    overflow: hidden;
    /* ÖLÇÜLDÜ 2026-09-15: burada DURAĞAN bir gölge bildirimi vardı (orta kademe).
       DESIGN.md gölgeyi yalnız :hover ("Raised Interactive State") için kabul
       eder; durağan kartta ayrımı düzlem kayması taşır. */
}

/* Top-edge sheen — a faint light fall-off gives the tile dimension. */
.stat-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 40%;
    background: linear-gradient(
        to bottom,
        color-mix(in srgb, var(--on-surface) 4%, transparent),
        transparent
    );
    pointer-events: none;
}

/* Left accent rail — a brand gradient that fades top→bottom, not a blunt bar. */
.stat-card::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: linear-gradient(
        to bottom,
        var(--primary),
        color-mix(in srgb, var(--primary) 35%, transparent)
    );
    transition: width var(--transition-default);
}

.stat-card:hover {
    background: var(--surface-container);
    box-shadow:
        var(--shadow-lg),
        0 0 24px -10px var(--primary-glow),
        inset 0 0 0 1px color-mix(in srgb, var(--primary) 16%, transparent);
    transform: translateY(-2px);
}

.stat-card:hover::after {
    width: 4px;
    box-shadow: 0 0 12px -2px var(--primary-glow);
}

.stat-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

/* DESIGN.md: Use on-surface-variant for secondary metadata */
.stat-card-label {
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--on-surface-variant);
}

.stat-card-icon {
    font-size: 20px;
    color: var(--primary);
    flex: 0 0 auto;
}

/* DESIGN.md: Be Bold with Scale — use display-sm for numbers */
.stat-card-value {
    font-family: var(--font-headline);
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--on-surface);
    line-height: 1.05;
    overflow-wrap: anywhere;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.stat-card-trend {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    align-self: flex-start;
    min-height: 24px;
    padding: 0.125rem var(--space-2);
    border-radius: var(--radius-md);
    background: var(--surface-container-high);
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.stat-card-trend.positive { color: var(--state-success-text-on-fill); }
.stat-card-trend.negative { color: var(--state-error-text-on-fill); }
.stat-card-trend.neutral { color: var(--on-surface-variant); }

@container (max-width: 200px) {
    .stat-card-value { font-size: var(--font-size-2xl); }
}

/* ============================
   KPI Grid & Cards — DESIGN.md: Tonal depth, no borders
   ============================ */
/* ÖLÇÜLDÜ 2026-09-15: sabit `repeat(4, 1fr)` iki ayrı kusur üretiyordu.
     • `class="kpi-grid bento-grid"` — 37 DOSYADA iki ızgara sistemi aynı
       elemanda. `bento-grid` 12 sütun kurar ve sonra yüklendiği için kazanır:
       4 KPI kartı 102px'e sıkışıyordu (ölçüldü, /ai-security ailesi 4 sayfa).
     • Çocuk sayısı 4 değilse satır düzensiz kırılıyordu (5 çocuk → 3 satır).
   `auto-fit` sütun sayısını İÇERİĞE göre belirler: 12 sütunluk bir bento
   tanımını da ezer, 5 çocuğu da düzgün yerleştirir. `minmax` tabanı KPI
   kartının okunabilir asgarisidir — 102px'lik kart okunmuyordu.
   Sayfa CSS'i sütun sayısını artık TEKRAR TANIMLAMAZ; `.kpi-strip` de
   aynı davranışı paylaşır (27 tanım / 6 gövde hâlindeydi).
   `stretch` (karar 2026-10-12): bir satırdaki kartlar içerikten bağımsız AYNI
   boyda olmalı. `start` ile /dashboards/retail şeridi 215/199/170/215px
   çiziliyordu ve satır kaymış görünüyordu. Satır zaten en uzun karta göre yer
   kapladığı için `stretch` ekran maliyeti getirmez (bkz. CLAUDE.md, kart
   ızgarasında stretch). */
.kpi-grid,
.kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
    align-items: stretch;
}

/* ÖLÇÜLDÜ 2026-09-15: `.bento-grid` bu dosyada SONRA geliyor (1531 vs 458) ve
   ayni ozgullukte (0,1,0) oldugu icin kaynak sirasi onu kazandiriyordu —
   `class="kpi-grid bento-grid"` yazan 37 dosyada 12 sutun uygulaniyor, 4 KPI
   karti 85-102px'e sikisiyordu. Ikisi BIRLIKTE yazildiginda niyet KPI
   seridi'dir; bu yuzden ozgullugu (0,2,0)'a cikariyoruz. */
.kpi-grid.bento-grid,
.kpi-strip.bento-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
}

/* `bento-col-*` KPI ŞERİDİNDE DE NÖTRLENİR — `.nav-grid` emsalinin aynısı.
   ÖLÇÜLDÜ 2026-09-18 /ecosystem @375px: şeritteki TEK bir `bento-col-2` kart
   `grid-column: span 12` alıyor; `auto-fit` 12 ize düşüyor ve kalan kartlar
   48px'e SIKIŞIYOR (ölçülen sütun dizisi: `220px 48px 48px 0px ×9`). Span
   taşıyan kart 492px ile 327px'lik kaptan da taşıyordu.
   Bir KPI şeridinde her kart EŞİT ağırlıklıdır — bento'nun editoryal
   hiyerarşisi burada geçerli değil. Kapsam dar: yalnız ikisi BİRLİKTE
   yazıldığında, yani niyet KPI şeridi olduğunda. */
.kpi-grid.bento-grid > [class*="bento-col-"],
.kpi-strip.bento-grid > [class*="bento-col-"] {
    grid-column: auto;
}

/* CIPLAK `bento-grid` de KPI SERIDI olabilir. ÖLÇÜLDÜ 2026-09-16: yukaridaki
   kural yalniz `class="kpi-grid bento-grid"` yazani koruyor, ama 64 yerde
   markup yalnizca `class="bento-grid"` yazip icine `kpi-card` koyuyor —
   span sinifi da yok. 12 sutunluk izgarada her kart 1 SUTUN aliyordu:
   /ai-control 1600px'te 5 kart **77px**, deger 83px ile karttan TASIYOR ve
   etiket BES SATIRA kiriliyordu ("TOP LAM MOD ELLE R"). Olculen 36 kartin
   28'i 200px altindaydi.

   `:has()` ile niyet dogrudan okunur: bir bento izgarasi DOGRUDAN kpi-card
   tasiyorsa o bir KPI seridi'dir. Ozgulluk (0,2,0) — taban `.bento-grid`
   (0,1,0) ile ayni yerde yazildigi icin kaynak sirasi degil ozgulluk karar
   verir. Span tasiyan kartlar KAPSAM DISI: onlar bento hiyerarsisini
   bilincli kullaniyor. */
.bento-grid:has(> .kpi-card):not(:has(> [class*="bento-col-"])) {
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
}
/* Zemin KART DUZLEMI (kit 27, 2026-09-14): KPI kutucugu da bir karttir,
   `container-low` degil `container-lowest` basmali — yoksa ayni ekranda
   VCard beyaz, KPI kutucugu gri kaliyor ve serit ayrisiyor. */
.kpi-card {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    content-visibility: auto;
    contain-intrinsic-size: auto 120px;
    position: relative;
    overflow: hidden;
    /* GÖLGE YOK (kit 27, "Elevation & Depth"): "Ground State (Cards,
       Modules): No shadow. Edges are pure value shifts." Kart zaten
       #FFFFFF ile #F9F9F9 zemin arasinda bir DUZLEM KAYMASI tasiyor;
       ustune golge koymak brutalist dili "floating card"a cevirir. */
    box-shadow: none;
    transition:
        background var(--transition-default),
        box-shadow var(--transition-default),
        transform var(--transition-default);
}
.kpi-card::before,
.va-kpi::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 40%;
    background: linear-gradient(
        to bottom,
        color-mix(in srgb, var(--on-surface) 4%, transparent),
        transparent
    );
    pointer-events: none;
}
.kpi-card::after,
.va-kpi::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: linear-gradient(
        to bottom,
        var(--primary),
        color-mix(in srgb, var(--primary) 35%, transparent)
    );
    transition: width var(--transition-default);
}
/* Hover KOYULASTIRMAZ: kart zaten rampanin en ust basamagi. Onceki kural
   `--surface-container`e (sayfa zemini tonu) gidiyordu, yani hover'da kart
   zemine GOMULUYORDU. */
.kpi-card:hover {
    background: var(--surface-container-lowest);
    /* Yalniz ETKILESIM aninda yukselir — kit'in "Raised Interactive State"
       degeri birebir. */
    box-shadow:
        0 12px 32px -4px rgba(var(--overlay-scrim-rgb), 0.06),
        0 4px 12px -2px rgba(var(--overlay-scrim-rgb), 0.04);
    transform: translateY(-1px);
}
.kpi-card:hover::after,
.va-kpi:hover::after { width: 4px; }
.kpi-value {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--on-surface);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
/* ÖLÇÜLDÜ 2026-09-14 (/finance, 8 KPI): etiketler teknik tanimlayici
   ("cashflow_acc_min_pct", 131px) ve kart `overflow: hidden` tasiyor —
   metin kutunun disina tasip GORSEL OLARAK kirpiliyordu ("nflow_acc_min_").
   DOM'da tam metin duruyor, yani bir "kirpma" testi bunu goremez; kusur
   yalniz ekranda.

   Cozum kirpmak DEGIL sarmak: alt_cizgi ve tire noktalarindan kir, tasma
   kalmasin. `anywhere` cok uzun tek parcali adlar icin son care. */
/* Kit 27, "Typography": "All label-sm and label-md variants should default to
   uppercase with tracking expanded to +0.06em or +0.08em to evoke technical
   drafting schemas, serial stamping, and architectural blueprints."
   ÖLÇÜLDÜ 2026-09-14: textTransform `none`, letterSpacing `normal` idi. */
.kpi-label {
    font-size: var(--font-size-2xs, 0.75rem);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--on-surface-variant);
    max-inline-size: 100%;
    text-align: center;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.kpi-icon { font-size: 32px; color: var(--primary); }

/* ── KPI anatomisinin ikinci adi: .stat-label / .stat-value ────────────
   ÖLÇÜLDÜ 2026-09-15. Ayni anatomi iki adla yasiyordu ve `.stat-*` tarafi
   sayfa sayfa yeniden yaziliyordu: `.stat-value` 22 tanim / 16 FARKLI govde,
   `.stat-label` 19 tanim / 11 govde. Sayfalarin birbirinden farkli gorunmesinin
   dogrudan sebebi buydu.

   Kit 27 ihlalleri olculdu:
     • Label "uppercase + 0.06em" olmali — 19 tanimin HICBIRINDE yoktu.
     • Value `tabular-nums` tasimali (canli sayac satiri titretmesin) —
       22 tanimin yalniz 1'inde vardi.
   `.kpi-label` bu kurallara zaten uyuyordu; kanonik taban odur, `.stat-*`
   ona hizalanir. Sayfalar yalniz RENK varyantini kendi CSS'inde tutar. */
.stat-label {
    font-size: var(--font-size-2xs, 0.75rem);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--on-surface-variant);
    overflow-wrap: anywhere;
}

.stat-value {
    font-size: 1.75rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--on-surface);
    font-variant-numeric: tabular-nums;
}

/* ============================
   Tab Panel
   ============================ */
/* DESIGN.md: No-Line Rule — tonal tabs */
.tab-bar {
    display: flex;
    gap: 0;
    background: var(--surface-container-low);
    border-radius: var(--card-radius);
    padding: 0.25rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    box-shadow: var(--shadow-inset);
}

.tab-bar::-webkit-scrollbar { display: none; }

.tab-btn {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.75rem 1.25rem;
    background: transparent;
    border: none;
    border-radius: var(--btn-radius);
    color: var(--on-surface-variant);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
    min-height: 44px;
    -webkit-tap-highlight-color: transparent;
}

.tab-btn:hover {
    color: var(--on-surface);
    background: var(--surface-container);
}

/* DESIGN.md: Active tab with tonal background */
.tab-btn.active {
    background: var(--surface-container-highest);
    color: var(--primary);
}

.tab-content {
    padding-top: 1rem;
}

/* ============================
   Search Bar
   ============================ */
/* DESIGN.md: Modern Input style — tonal focus */
.search-bar-component {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0 1rem;
    background: var(--surface-container-low);
    border: 1px solid transparent;
    border-radius: var(--panel-radius);
    transition: all var(--transition-fast);
    min-height: 44px;
}

.search-bar-component:focus-within {
    background: var(--surface-container-highest);
    border-color: color-mix(in srgb, var(--primary) 45%, transparent);
    box-shadow: var(--focus-ring);
}

.search-bar-component .material-symbols-outlined {
    font-size: 20px;
    color: var(--on-surface-variant);
}

.search-bar-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    min-width: 0;
}

.search-bar-input::placeholder {
    color: var(--outline-text);
}

/* DESIGN.md: Radius-full for circular buttons */
.search-bar-clear {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    background: transparent;
    border: none;
    color: var(--on-surface-variant);
    cursor: pointer;
    border-radius: var(--radius-full);
    transition: all var(--transition-fast);
}

.search-bar-clear:hover {
    background: var(--surface-container-highest);
    color: var(--on-surface);
}

/* ============================
   Data Table
   ============================ */
/* DESIGN.md: No-Line Rule — tonal background */
.data-table-wrapper {
    /* ref-33 (2026-09-25): tablo, beyaz bir kart icinde hayalet cerceveyle durur. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    border-radius: var(--card-radius);
    max-width: 100%;
}

.data-table-wrapper:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 42rem;
}

.data-table thead {
    position: sticky;
    top: 0;
    z-index: 5;
}

/* DESIGN.md: label typography (Manrope via --font-label), tonal background.
   A brand-tinted hairline on the header's bottom edge cleanly separates the
   sticky head from the scrolling body without a flat divider border. */
.data-table th {
    text-align: left;
    padding: 12px 16px;
    /* ref-33: baslik cumle duzeninde, buyuk harf/harf araligi YOK. */
    font-family: var(--font-label);
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--on-surface-variant);
    background: var(--surface-container-lowest);
    box-shadow: inset 0 -1px 0 0 var(--ghost-border);
    white-space: nowrap;
    cursor: default;
    user-select: none;
}

/* Active sort column header reads in the brand accent. */
.data-table th[aria-sort="ascending"],
.data-table th[aria-sort="descending"] {
    color: var(--primary);
}

.data-table th.sortable {
    cursor: default;
}

.data-table th.sortable:hover {
    color: var(--primary);
}

.data-table-sort-btn {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.25rem;
    width: 100%;
    min-height: 32px;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
    text-align: left;
}

.data-table-sort-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

.data-table-sort-icon {
    font-size: 16px;
    line-height: 1;
    flex: 0 0 auto;
}

/* DESIGN.md: No divider borders — use tonal shift */
.data-table td {
    padding: var(--space-3) 16px;
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    color: var(--on-surface);
    vertical-align: middle;
    box-shadow: inset 0 -1px 0 0 var(--ghost-border);
}

/* Alternating tonal rows.

   `:nth-child(even)` HER <tr>'yi sayar — detay satiri (DataTable.DetailTemplate)
   araya girince veri satirlari 1,3,5… olur ve serit ters doner. `of` seciciyle
   sayim yalniz VERI satirlari uzerinden yapilir; detay satiri kendi zeminini
   tasir (asagida). ÖLÇÜLDÜ 2026-09-21. */
.data-table tbody tr:nth-child(even of :not(.data-table-detail-row)) {
    /* ref-33: satirlar beyaz, ayrimi ince cizgi tasir; zebra seridi cok hafif. */
    background: color-mix(in srgb, var(--surface-container-low) 45%, var(--surface-container-lowest));
}

.data-table tbody tr {
    transition: background var(--transition-fast);
}

/* DESIGN.md: Tonal hover */
.data-table tbody tr:hover {
    background: var(--surface-container-low);
}

.data-table-clickable-row {
    cursor: pointer;
}

.data-table-empty-cell {
    text-align: center;
    padding: 2rem;
}

/* Detay satiri — satirin ALTINA, tablo genisliginde ek icerik.
   ÖLÇÜLDÜ 2026-09-21: iki sayfa bunu elle yaziyordu (ConnectorHealthPage
   devre aciklamasi, SwarmAuctions teklif tablosu) ve DataTable'a gocemiyordu.

   ZEBRA RITMI: `.data-table tbody tr:nth-child(even)` her IKINCI <tr>'yi
   boyar; detay satiri eklenince veri satirlari 1,3,5… olur ve serit ters
   doner. Detay satiri seridin DISINDA tutulur — kendi zeminini tasir ve
   zebra kurali onu atlar. */
/* ÖZGÜLLÜK (olculdu 2026-09-21): `:nth-child(of S)` ozgullugu S'nin EN OZGUL
   dalini da ekler — `:not(.data-table-detail-row)` bir SINIF getirir ve zebra
   kurali (0,3,2) olur. Duz `.data-table tbody tr.data-table-detail-row` (0,2,2)
   onu yenemez; detay satiri zebra rengini alirdi. `:where()` ozgullugu 0
   oldugu icin sayim davranisini korur ama kurali yenilebilir birakir — burada
   ters yonde, ZEBRAYA esit ozgulluk gerekiyor: sinif IKI kez yazilir. */
.data-table tbody tr.data-table-detail-row.data-table-detail-row,
.data-table tbody tr.data-table-detail-row.data-table-detail-row:hover {
    background: var(--surface-container);
}

.data-table-detail-cell {
    padding: var(--space-3) var(--space-4);
    /* Detay, ustundeki satira AIT oldugunu gostermeli: kenarlik degil
       duzlem kaymasi ("No-Line"), solda ince bir aksan. */
    box-shadow: inset 3px 0 0 0 var(--primary);
}

/* DESIGN.md: No-Line Rule — tonal separation */
.data-table-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 1rem;
    background: var(--surface-container-lowest);
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
}

.data-table-pagination-btns {
    display: flex;
    gap: 0.25rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.data-table-page-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border: none;
    border-radius: var(--radius-md);
    color: var(--on-surface-variant);
    background: transparent;
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-sm);
}

.data-table-page-btn:hover:not(:disabled) {
    background: var(--surface-container-high);
    color: var(--primary);
}

.data-table-page-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.data-table-page-btn.active {
    /* ref-33: aktif sayfa dolu degil, cerceveli ve belirgin. */
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    font-weight: 700;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--on-surface) 28%, transparent);
}

@media (max-width: 767px) {
    .data-table {
        min-width: 38rem;
    }

    .data-table th,
    .data-table td {
        padding: var(--space-2) 12px;
    }

    .data-table-pagination {
        align-items: flex-start;
        flex-direction: column;
    }

    .data-table-pagination-btns {
        justify-content: flex-start;
    }
}

/* ============================
   Status Badge
   ============================ */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--btn-radius);
    font-family: var(--font-label);
    font-size: var(--font-size-sm);
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    line-height: 1;
    white-space: nowrap;
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border: 1px solid var(--ghost-border, transparent);
}

/* DESIGN.md: Radius-full. A faint glow makes the live-status dot read as a
   real indicator, not flat decoration — colour inherits from the variant. */
.status-badge-dot {
    width: 6px;
    height: 6px;
    border-radius: var(--radius-full);
    flex-shrink: 0;
    box-shadow: 0 0 6px -1px currentColor;
}

/* ÖLÇÜLDÜ 2026-09-15: `.status-dot` YİRMİ ALTI ayrı sayfa CSS'inde tanımlıydı
   ve 17'si birebir aynı tabanı yazıyordu (10px daire, token yarıçapı). Kanonik
   taban burada; sayfalar yalnız RENK varyantını (`background:`) ya da bilinçli
   bir boyut farkını kendi CSS'inde tutar — o ikisi meşru sapmalardır. */
/* ============================================================
   SAYFA İSKELETİ — tema paketinin taşıyıcı katmanı
   ============================================================
   ÖLÇÜLDÜ 2026-09-15. Üç desen, sayfa CSS'lerinde 450 kez tanımlıydı
   ve 207 FARKLI ad taşıyordu — hepsi birebir aynı gövdeyle:

     .va-page        223 tanım / 115 ad  (abr-container, edi-container, …)
     .va-page-back   151 tanım /  80 ad  (abr-back, eco-back, …)
     .va-screen       76 tanım /  12 ad  (edi-screen, kg-screen, …)

   Yani her bölüm kendi prefix'iyle AYNI kabı yeniden icat etmişti;
   paylaşılan katmanda karşılığı olmadığı için başka çaresi de yoktu.

   Adlar `va-` önekiyle NÖTR tutuldu: sayfa iskeleti bir bölüme ait
   değildir. Mevcut prefix'li sınıflar (`.edi-container` gibi) bu
   kurallara TAKMA AD olarak bağlanmaz — sayfa CSS'inden kaldırılıp
   markup bu sınıfa geçirilir; böylece 207 ad tek ada iner. */

.va-page {
    /* Max-width okuma genişliğini sınırlar; ortalamak (margin:auto) WorkspaceShell
       başlığından bağımsız bir sol kenar üretir — 227+ sayfada ölçüldü.
       Kabuk zaten .app-content-surface içinde; kap sola yaslanır. */
    max-width: var(--content-max-width, 2040px);
    margin-inline: 0;
}

/* Bir üst seviyeye dönüş bağlantısı (ikon + etiket). */
.va-page-back {
    margin-bottom: var(--space-5);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* Kendi zeminini taşıyan tam ekran kabuk. `min-height: 0` bilinçli:
   flex/grid çocuğu olarak taşmayı engeller. */
.va-screen {
    min-height: 0;
    background: var(--surface);
}

.status-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: var(--btn-radius);
}

/* RENK VARYANTLARI — tema paketinin parçası, sayfanın değil.
   ÖLÇÜLDÜ 2026-09-15: bu dört varyant SEKSEN İKİ ayrı sayfa CSS'inde
   tanımlıydı ve 79'u birebir aynı gövdeyi yazıyordu; markup kullanımı ise
   yalnız 12. Yani 70 tanım ölü kopyaydı. Varyant paylaşılan katmanda
   olmadığı için her sayfa kendi rengini yazmak zorunda kalmıştı.

   İKİ KUSUR birden düzeltildi:

   1) ADLANDIRMA: `.dot-green` gerçekte YEŞİL değil `--primary-container`
      (teal, #76abae) basıyordu; `.dot-yellow` `--secondary` (gold),
      `.dot-red` `--tertiary` (salmon). Yani DURUM göstergeleri MARKA
      renklerini kullanıyordu — kullanıcı "aktif mi?" sorusuna teal bir
      nokta görüyordu, yeşil değil.

   2) TUTARSIZLIK: aynı `.dot-green` 18 dosyada teal, 3 dosyada gerçek
      yeşil (`--state-success`) basıyordu. Aynı sınıf, iki farklı anlam.

   Markup ölçümü kararı verdi: kullanım ANLAMSAL
   (`IsActive ? "dot-green" : "dot-red"`, `Error => red`, `Working =>
   yellow`). Dolayısıyla doğru kaynak `--state-*` ailesidir; marka tonu
   değil. Renk adları geriye uyumluluk için korundu ve anlamsal adla AYNI
   kurala bağlandı, böylece ikisi asla ayrışamaz. Yeni kod anlamsal adı
   kullanmalı. */
.status-dot--info,
.dot-blue { background: var(--state-info); }

.status-dot--success,
.dot-green { background: var(--state-success); }

.status-dot--danger,
.dot-red { background: var(--state-error); }

.status-dot--warning,
.dot-yellow { background: var(--state-warning); }

.status-dot--muted { background: var(--state-inactive); }

/* Marka tonlu nokta — DURUM değil, KATEGORİ/aksan işareti içindir.
   (Örn. bir ajanı markaya bağlayan rozet.) Durum göstermek için
   yukarıdaki state varyantlarını kullan. */
.status-dot--accent { background: var(--primary); }

.status-badge.success { background: var(--state-success-bg); color: var(--state-success-text-on-fill); border-color: var(--state-success-border); }
.status-badge.success .status-badge-dot { background: var(--state-success); }

/* TERS YUZEYDEKI ROZET. ÖLÇÜLDÜ 2026-09-14 (/agent-dev, crawler WCAG taramasi):
   "STABLE" rozeti 2.0:1 kontrastla okunmuyordu — #136c34 metin, #2f3131 zemin.

   Sebep KAPSAM: rozeti duzelten kural `.add-threat-card .status-badge` olarak
   SCOPED CSS'te yaziliydi, ama StatusBadge AYRI bir bilesen ve kok <span>'i
   `b-xxxxx` ozniteligi tasimiyor — scoped kural ona HIC ulasmiyor.
   (Ayni tuzak SystemStatusIndicator'da da olculdu; CLAUDE.md'de kayitli.)

   Cozum paylasilan CSS: ters zemin tasiyan her kap icin rozet kendi tonunu
   birakir ve zeminin kontrast ciftine doner. */
/* `.success`/`.active` DE hedeflenir. ÖLÇÜLDÜ 2026-09-14: yalniz
   `.status-badge` yazan kural (0,2,0) yetmiyordu — rozet ayni zamanda
   `.status-badge.success` tasiyor ve o kural (0,2,0) DAHA SONRA yuklendigi
   icin kazaniyordu; "STABLE" 2.01:1'de kaliyordu. Sinif zincirini esitleyip
   kaynak sirasina birakmiyoruz. */
:is(.add-threat-card, .inverse-surface, [class*="inverse"]) :is(.status-badge, .status-badge.success, .status-badge.active) {
    color: var(--inverse-on-surface);
    background: color-mix(in srgb, var(--inverse-on-surface) 12%, transparent);
    border-color: color-mix(in srgb, var(--inverse-on-surface) 22%, transparent);
}

:is(.add-threat-card, .inverse-surface, [class*="inverse"]) .status-badge .status-badge-dot {
    background: var(--inverse-on-surface);
}

.status-badge.warning { background: var(--state-warning-bg); color: var(--state-warning-text-on-fill); border-color: var(--state-warning-border); }
.status-badge.warning .status-badge-dot { background: var(--state-warning); }

.status-badge.error { background: var(--state-error-bg); color: var(--state-error-text-on-fill); border-color: var(--state-error-border); }
/* danger === error: bileşen StatusBadgeTone.Danger için "danger" üretiyor ama CSS'te karşılığı yoktu; ÖLÇÜLDÜ 2026-09-03: 15 kullanım nötr griye düşüyordu. */
.status-badge.danger { background: var(--state-error-bg); color: var(--state-error-text-on-fill); border-color: var(--state-error-border); }
.status-badge.error .status-badge-dot { background: var(--state-error); }
.status-badge.danger .status-badge-dot { background: var(--state-error); }

.status-badge.critical { background: var(--state-critical-bg); color: var(--state-critical); border-color: var(--state-critical-border); }
.status-badge.critical .status-badge-dot { background: var(--state-critical); }

.status-badge.info { background: var(--state-info-bg); color: var(--state-info-text-on-fill); border-color: var(--state-info-border); }
.status-badge.info .status-badge-dot { background: var(--state-info); }

.status-badge.active { background: var(--state-active-bg); color: var(--state-active); border-color: var(--state-active-border); }
.status-badge.active .status-badge-dot { background: var(--state-active); }

.status-badge.pending { background: var(--state-pending-bg); color: var(--state-pending); border-color: var(--state-pending-border); }
.status-badge.pending .status-badge-dot { background: var(--state-pending); }

.status-badge.inactive { background: var(--state-inactive-bg); color: var(--state-inactive); border-color: var(--state-inactive-border); }
.status-badge.inactive .status-badge-dot { background: var(--state-inactive); }

.status-badge.neutral { background: var(--surface-container-high); color: var(--on-surface-variant); }
.status-badge.neutral .status-badge-dot { background: var(--outline); }

/* ── Page Badge Aliases (shorthand state badges used across pages) ── */
.badge-ok, .badge-pass { background: var(--state-success-bg); color: var(--state-success-text-on-fill); }
.badge-error, .badge-fail { background: var(--state-error-bg); color: var(--state-error-text-on-fill); }
.badge-warn, .badge-warning { background: var(--state-warning-bg); color: var(--state-warning-text-on-fill); }
.badge-info { background: var(--state-info-bg); color: var(--state-info-text-on-fill); }
.badge-default { background: var(--surface-container-high); color: var(--on-surface-variant); }

.badge,
.badge-ok,
.badge-pass,
.badge-error,
.badge-fail,
.badge-warn,
.badge-warning,
.badge-info,
.badge-default {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    max-width: 100%;
    min-height: 24px;
    padding: 0.25rem 0.625rem;
    border-radius: var(--radius-md);
    font-family: var(--font-label);
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    line-height: 1.2;
    overflow-wrap: anywhere;
}

/* İKİ SINIF BİRDEN: `class="status-badge badge-info"`. ÖLÇÜLDÜ 2026-09-03,
   /ai-ops/logs ve /ai-security/scans, 269 rozetin 27'si:
       kanonik  ağırlık 500 · dolgu 4px/12px · yarıçap 12px
       sapan    ağırlık 700 · dolgu 4px/10px · yarıçap  8px
   .badge-* ailesi kendi iskeletini kuruyor ve .status-badge ile AYNI
   özgüllükte (0-1-0) olduğu için, dosyada SONRA geldiğinden kazanıyordu.
   Eleman .status-badge'i de taşıyorsa kanonik iskelet geçerli olmalı —
   .badge-* yalnız rengini versin. */
.status-badge.badge,
.status-badge.badge-ok,
.status-badge.badge-pass,
.status-badge.badge-error,
.status-badge.badge-fail,
.status-badge.badge-warn,
.status-badge.badge-warning,
.status-badge.badge-info,
.status-badge.badge-default {
    gap: var(--space-2);
    min-height: 0;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--btn-radius);
    font-size: var(--font-size-sm);
    font-weight: 500;
    letter-spacing: normal;
}

/* ROZET AİLESİ — SAYFAYA ÖZEL ADLAR KANONİK İSKELETE BAĞLANIR.
   ÖLÇÜLDÜ 2026-09-03, altı gerçek sayfada gerçek öğelerle:
       13 rozet sınıfı → 13 FARKLI görünüm
       yükseklik 14 · 19 · 21 · 22 · 26 · 29 · 32
       yarıçap   12px · 16px · 9999px
   Hiçbiri diğerine benzemiyordu. Oysa .status-badge / .badge ailesi zaten
   tutarlı tanımlı — sorun o aileye girmeyen sayfa adlarıydı.

   ROLLER AYRIŞTIRILDI (markup'taki içerikten okundu, körlemesine değil):
       infra-chip     @b.Status          → DURUM
       ev-badge       @r.Status          → DURUM
       severity-badge @rule.Severity     → DURUM
       badge-count    @workspaces.Count  → SAYI    (ayrı rol, dar ve yuvarlak)
       type-badge     @evt.EventType     → KATEGORİ (ayrı rol, nötr renk)
   Üç rol üç ayrı görünüm ister; hepsini tek biçime zorlamak anlamı silerdi.

   Kaynak: "consistent visual language — maintain consistent iconography,
   spacing and color usage per design system standards". */

/* 1) DURUM rozetleri — kanonik iskelet. Renk .status-badge.success gibi
      durum sınıflarından ya da sayfanın kendi kuralından gelir. */
.infra-chip,
.ev-badge,
.severity-badge,
.card-status-badge,
.quality-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    max-width: 100%;
    min-height: 24px;
    padding: 0.25rem 0.625rem;
    border-radius: var(--radius-md);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    line-height: 1.2;
    white-space: nowrap;
}

/* 2) SAYI rozeti — dar, tam yuvarlak, tek satır. Bir sayı okunmak için
      vardır; durum rozeti kadar yer kaplamamalı. */
.badge-count,
.topbar-badge--count,
.notification-unread-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    min-height: 1.25rem;
    padding: 0 var(--space-1);
    border-radius: var(--chip-radius);
    background: var(--surface-container-highest);
    color: var(--on-surface);
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    line-height: 1;
}

/* 3) KATEGORİ rozeti — nötr. Renk taşımaz ki DURUM renkleri anlam koruyabilsin
      (tasarım sistemi kuralı: renk yalnız durum taşır, süs değil). */
.type-badge,
.category-badge,
.meta-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    min-height: 24px;
    padding: 0.25rem 0.625rem;
    border-radius: var(--radius-md);
    background: var(--surface-container-high);
    color: var(--on-surface-variant);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: var(--tracking-wider);
    line-height: 1.2;
    white-space: nowrap;
}

/* ============================
   State Cards — Status-aware card variants
   ============================ */
.state-card {
    border: 1px solid var(--glass-border, transparent);
    border-radius: var(--card-radius);
    padding: var(--space-5);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    transition: all var(--transition-default);
    position: relative;
    overflow: hidden;
}

.state-card::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: var(--accent-color, var(--primary));
}

.state-card.state-success { --accent-color: var(--state-success-text, var(--state-success)); background: var(--state-success-bg); border-color: var(--state-success-border); }
.state-card.state-success:hover { border-color: var(--state-success-text, var(--state-success)); box-shadow: 0 0 16px var(--state-success-bg); }

.state-card.state-warning { --accent-color: var(--state-warning-text, var(--state-warning)); background: var(--state-warning-bg); border-color: var(--state-warning-border); }
.state-card.state-warning:hover { border-color: var(--state-warning-text, var(--state-warning)); box-shadow: 0 0 16px var(--state-warning-bg); }

.state-card.state-error { --accent-color: var(--state-error-text, var(--state-error)); background: var(--state-error-bg); border-color: var(--state-error-border); }
.state-card.state-error:hover { border-color: var(--state-error-text, var(--state-error)); box-shadow: 0 0 16px var(--state-error-bg); }

.state-card.state-critical { --accent-color: var(--state-critical); background: var(--state-critical-bg); border-color: var(--state-critical-border); }
.state-card.state-critical:hover { border-color: var(--state-critical); box-shadow: 0 0 16px var(--state-critical-bg); }

.state-card.state-info { --accent-color: var(--state-info-text, var(--state-info)); background: var(--state-info-bg); border-color: var(--state-info-border); }
.state-card.state-info:hover { border-color: var(--state-info-text, var(--state-info)); box-shadow: 0 0 16px var(--state-info-bg); }

.state-card.state-active { --accent-color: var(--state-active); background: var(--state-active-bg); border-color: var(--state-active-border); }
.state-card.state-active:hover { border-color: var(--state-active); box-shadow: 0 0 16px var(--state-active-bg); }

.state-card.state-pending { --accent-color: var(--state-pending); background: var(--state-pending-bg); border-color: var(--state-pending-border); }
.state-card.state-pending:hover { border-color: var(--state-pending); box-shadow: 0 0 16px var(--state-pending-bg); }

.state-card.state-inactive { --accent-color: var(--state-inactive); background: var(--state-inactive-bg); border-color: var(--state-inactive-border); }
.state-card.state-inactive:hover { border-color: var(--state-inactive); }

/* State card accent icons inherit color */
.state-card.state-success .state-icon { color: var(--state-success-text-on-fill); }
.state-card.state-warning .state-icon { color: var(--state-warning-text-on-fill); }
.state-card.state-error .state-icon { color: var(--state-error-text-on-fill); }
.state-card.state-critical .state-icon { color: var(--state-critical); }
.state-card.state-info .state-icon { color: var(--state-info-text-on-fill); }
.state-card.state-active .state-icon { color: var(--state-active); }
.state-card.state-pending .state-icon { color: var(--state-pending); }
.state-card.state-inactive .state-icon { color: var(--state-inactive); }

/* ============================
   Bar Fill States — Progress/capacity indicators
   ============================ */
.bar-container {
    height: 6px;
    background: var(--surface-container-high);
    border-radius: var(--radius-full);
    overflow: hidden;
}

.bar-fill {
    width: var(--bar-w, 0%);
    height: 100%;
    border-radius: var(--radius-full);
    transition: width 600ms ease-out;
}

.bar-ok { background: var(--state-success); }
.bar-warn { background: var(--state-warning); }
.bar-danger { background: var(--state-error); }
.bar-critical { background: var(--state-critical); }
.bar-info { background: var(--state-info); }

/* ============================
   Metric Score Utility Classes
   Replaces inline style="color:@GetHealthColor()" / GetQColor() / GetUtilColor() patterns.
   Use .score-high / .score-medium / .score-low on the wrapping <span>.
   ============================ */
/* High/medium/low traffic-light, anchored so the WHOLE scale stays legible in every theme:
   high = brand-teal (--primary-container is pale #b6ecef in Light → unreadable on white),
   medium = brand-gold (--secondary is charcoal in Light),
   low = tertiary salmon. */
.score-high   { color: var(--brand-teal-text); }
.score-medium { color: var(--brand-gold-text); }
/* Low/danger tier = error red. --tertiary is salmon only in Dark (near-white in Mixed,
   charcoal in Light), so the "bad" end of the scale was invisible/wrong off-Dark. */
.score-low    { color: var(--error); }

/* Bar fill variants — for progress/bar elements using score classes as background */
.score-high.bar-fill-score,
[class*="bar-fill"].score-high,
[class*="-fill"].score-high,
[class*="progress-fill"].score-high,
.gauge-fill.score-high,
.bar.score-high  { background: var(--primary-container); }
.score-medium.bar-fill-score,
[class*="bar-fill"].score-medium,
[class*="-fill"].score-medium,
[class*="progress-fill"].score-medium,
.gauge-fill.score-medium,
.bar.score-medium { background: var(--brand-gold); }
.score-low.bar-fill-score,
[class*="bar-fill"].score-low,
[class*="-fill"].score-low,
[class*="progress-fill"].score-low,
.gauge-fill.score-low,
.bar.score-low   { background: var(--error); }

/* Bar fill with icon-accent (primary color) — multi-series neutral bars */
[class*="-fill"].icon-accent { background: var(--primary); }

/* Risk level aliases (DataPrivacyAnalyzerPage etc.) */
.risk-low    { color: var(--brand-teal-text); }
.risk-medium { color: var(--brand-gold-text); }
.risk-high   { color: var(--error); }

/* Binary pass/fail color shortcuts */
.value-ok   { color: var(--brand-teal-text); font-weight: 600; }
.value-fail { color: var(--error); font-weight: 600; }
.value-warn { color: var(--brand-gold-text); font-weight: 600; }

/* Icon state colors — use on material-symbols icons */
.icon-active { color: var(--brand-teal-text); }
.icon-muted  { color: var(--on-surface-variant); }


/* ============================
   Empty State
   ============================ */

/* ÖLÇÜLDÜ 2026-09-15: boş durum sayfalarda TEK DÜZ yüzey olarak çiziliyordu —
   tonal derinlik 2 (DESIGN.md en az 3 ister). İki ayrı kusur ölçüldü:

   1) `.empty-state` hiç zemin yazmıyordu; kart düzlemi yoktu.
   2) İkonun tonal çerçevesi `EmptyState.razor.css` içinde yazılıydı ama ikon
      bir `VIcon` BİLEŞENİ — onun kök elemanı EmptyState'in `b-xxxxx` kapsam
      özniteliğini TAŞIMAZ. Tarayıcıda ölçüldü: ikon kapsam özniteliği []
      (boş), zemin `rgba(0,0,0,0)`, genişlik 40px (hedef 56px). Scoped CSS
      başka bileşenin kök elemanına ulaşmaz; `::deep` de çözmez.

   Çözüm ikisini de paylaşılana taşımak: boş durum kendi kart düzlemine oturur
   (container-lowest), ikon onun İÇİNDE bir basamak daha (container-high) —
   zemin → kart → ikon çerçevesi = üç tonal derinlik. */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    min-height: 12rem;
    padding: 2.5rem 1.5rem;
    text-align: center;
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
}

.empty-state-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    margin-bottom: var(--space-1, 0.25rem);
    font-size: var(--icon-2xl);
    color: var(--on-surface-variant);
    background: var(--surface-container-high);
    border-radius: var(--btn-radius);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    opacity: 0.85;
    flex-shrink: 0;
}

/* Yardim/kisayol kartlarinin ikon cercevesi — `empty-state-icon` ile ayni
   anatomi (3rem kap / 24px glif = %50 oran, tonal zemin + hayalet kenarlik).
   PAYLASILAN katmanda durur cunku `VIcon` bir bilesendir: sayfa scoped CSS'i
   onun kok elemanina ULASAMAZ (kapsam oznitelnigi tasimaz).

   OLCULDU 2026-09-16: bu kartlar once ciplak 2rem glif tasiyordu ve bes kart
   DORT ayri marka tonu kullaniyordu — `--tertiary` light temada KIRMIZI
   (#ad3e38), yani "Destek Talepleri" ikonu tehlike rengindeydi. Renk ayrimi
   kaldirildi; ayrimi ikonun KENDISI tasir. */
.help-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--icon-shell-lg);
    height: var(--icon-shell-lg);
    font-size: var(--icon-lg);
    color: var(--primary);
    background: var(--surface-container-high);
    border-radius: var(--btn-radius);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    flex-shrink: 0;
    transition: background var(--transition-btn);
}

.help-card:hover .help-card-icon {
    background: var(--surface-container-highest);
}

/* Satir ici (inline/hint) varyant kart duzlemi ISTEMEZ — o zaten bir kabin
   icinde yasiyor; kendi zemini ikinci bir kart gibi gorunurdu. */
.empty-state.empty-state-compact,
.empty-state-hint {
    background: transparent;
    border-radius: 0;
}

/* ÖLÇÜLDÜ 2026-09-15: `.empty-msg` 13 sayfa CSS'inde tanımlıydı ve 13'ü de
   BİREBİR aynı gövdeyi yazıyordu — saf kopya. Kanonik tanım burada. */
.empty-msg {
    padding: 3rem;
    text-align: center;
    color: var(--on-surface-variant);
    font-size: 0.95rem;
}

/* Material symbol used as the primary empty-state icon.
   ÖLÇÜLDÜ 2026-09-15: bu blok `.empty-state-icon`'u da listeliyordu ve
   yukaridaki kanonik tonal cerceveyle AYNI ozgullukte (0,1,0) oldugu icin
   kaynak sirasi bunu kazandiriyordu — font-size 56px yerine 40px'e,
   opacity 0.85 yerine 0.5'e donuyordu. Takma ad korunur, kanonik sinif
   listeden cikarildi. */
.empty-state .icon-empty {
    font-size: var(--icon-2xl);
    color: var(--outline-text);
    opacity: 0.5;
    flex-shrink: 0;
}

.empty-state-title {
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 600;
    color: var(--on-surface);
    margin: 0;
}

.empty-state-message,
/* pages that place a <p> directly inside .empty-state */
.empty-state > p {
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
    max-width: 360px;
    line-height: 1.5;
    margin: 0;
}

/* Compact variant for inline use (e.g. inside a table cell) */
.empty-state.empty-state-compact {
    min-height: 6rem;
    padding: 1.5rem 1rem;
    gap: 0.5rem;
}

.empty-state.empty-state-compact .icon-empty,
/* COMPACT varyant standart 48px'i KULLANMAZ: satir ici / tablo hucresi icin
   kucultulmus surumdur (min-height 6rem). Bos-durum standardi --icon-2xl (48px)
   ama bu varyant bilerek bir kademe asagida. */
.empty-state.empty-state-compact .empty-state-icon {
    font-size: var(--icon-xl);
}

/* ============================
   Error State
   ============================ */
.error-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 2rem 1.5rem;
    text-align: center;
}

.error-state-icon {
    font-size: var(--icon-2xl);
    color: var(--error);
}

.error-state-message {
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
    max-width: 320px;
}

/* ============================
   Toast Container
   ============================ */
.toast-container {
    position: fixed;
    /* Ust bar (--z-topbar 500) 200'luk sabit z-index'i ortuyordu. Toast barin
       UZERINDE durur: kanonik bildirim katmani (--z-notify 950). */
    top: 1rem;
    right: 1rem;
    z-index: var(--z-notify);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 400px;
    pointer-events: none;
}

@media (max-width: 767px) {
    .toast-container {
        top: auto;
        bottom: calc(64px + env(safe-area-inset-bottom, 0px));
        left: 0.75rem;
        right: 0.75rem;
        max-width: none;
    }
}

.toast {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    background: var(--glass-bg, var(--surface-container-highest));
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border-radius: var(--panel-radius);
    box-shadow: var(--shadow-xl);
    pointer-events: auto;
    border: 1px solid var(--glass-border, transparent);
    border-left: 3px solid var(--primary);
}

.toast.toast-success { border-left-color: var(--state-success-text, var(--state-success)); background: var(--state-success-bg); }
.toast.toast-error { border-left-color: var(--state-error-text, var(--state-error)); background: var(--state-error-bg); }
.toast.toast-warning { border-left-color: var(--state-warning-text, var(--state-warning)); background: var(--state-warning-bg); }
.toast.toast-critical { border-left-color: var(--state-critical); background: var(--state-critical-bg); }
.toast.toast-info { border-left-color: var(--state-info-text, var(--state-info)); background: var(--state-info-bg); }

.toast-icon {
    font-size: 20px;
    flex-shrink: 0;
}

.toast-body {
    flex: 1;
    min-width: 0;
}

.toast-title {
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--on-surface);
}

.toast-message {
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
    margin-top: 0.125rem;
}

/* DESIGN.md: Radius-full */
.toast-close {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: var(--touch-target-min, 44px);
    min-height: var(--touch-target-min, 44px);
    padding: 0;
    background: transparent;
    border: none;
    border-radius: var(--radius-full);
    color: var(--on-surface-variant);
    cursor: pointer;
    flex-shrink: 0;
}

.toast-close:hover {
    background: var(--surface-container);
}

/* Inline action button (undo-everywhere). Teal text button, flush right before the
   close button — reads as the primary affordance on the toast without a filled bg. */
.toast-action {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch-target-min, 44px);
    padding: 0 0.75rem;
    background: transparent;
    border: none;
    color: var(--primary);
    font: inherit;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--label-sm-size, 0.6875rem);
    cursor: pointer;
    flex-shrink: 0;
    border-radius: var(--btn-radius, 0);
}

.toast-action:hover {
    background: var(--surface-container-high);
}

.toast-action:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* ============================
   Confirm Dialog
   ============================ */
.dialog-overlay {
    position: fixed;
    inset: 0;
    background: rgba(var(--overlay-scrim-rgb), 0.5);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    z-index: 150;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    animation: fadeIn 150ms ease-out;
}

.dialog-panel {
    background: var(--surface-container-high);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border: 1px solid var(--ghost-border, transparent);
    border-radius: var(--radius-xl);
    padding: var(--space-5);
    width: 100%;
    max-width: 420px;
    animation: scale-in 200ms ease-out;
}

.dialog-title {
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--on-surface);
    margin-bottom: 0.5rem;
}

.dialog-message {
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
    line-height: 1.5;
    margin-bottom: 1.5rem;
}

.dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes scale-in {
    from { opacity: 0; transform: scale(0.95); }
    to { opacity: 1; transform: scale(1); }
}

/* ============================
   Bento Grid — Asymmetric card layout
   ============================ */
.bento-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 1rem;
}

.bento-grid > .bento-8  { grid-column: span 8; }
.bento-grid > .bento-7  { grid-column: span 7; }
.bento-grid > .bento-6  { grid-column: span 6; }
.bento-grid > .bento-5  { grid-column: span 5; }
.bento-grid > .bento-4  { grid-column: span 4; }
.bento-grid > .bento-3  { grid-column: span 3; }
.bento-grid > .bento-12 { grid-column: span 12; }

@media (max-width: 767px) {
    .bento-grid > [class*="bento-"] { grid-column: span 12; }
}

/* ============================
   Metric Hero — Large hero metric with trend
   ============================ */
.metric-hero {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.5rem;
    background: var(--glass-bg, var(--surface-container));
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border: 1px solid var(--glass-border, transparent);
    border-radius: var(--card-radius);
    box-shadow: var(--shadow-xl);
    content-visibility: auto;
    position: relative;
    overflow: hidden;
}

.metric-hero::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: var(--primary);
    box-shadow: 2px 0 15px var(--primary-glow-hover);
}

.metric-hero-value {
    font-family: var(--font-headline);
    font-size: 3.5rem;
    font-weight: 800;
    line-height: 1;
    color: var(--on-surface);
    letter-spacing: -0.02em;
}

.metric-hero-label {
    font-size: var(--font-size-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--on-surface-variant);
}

.metric-hero-trend {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: var(--font-size-md);
    font-weight: 600;
}

.metric-hero-trend.up   { color: var(--secondary); }
.metric-hero-trend.down { color: var(--tertiary); }

/* ============================
   Live Feed — Scrollable event log
   ============================ */
.live-feed {
    display: flex;
    flex-direction: column;
    max-height: 400px;
    overflow-y: auto;
    padding: 1rem;
    background: var(--glass-bg, var(--surface-container));
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border: 1px solid var(--glass-border, transparent);
    border-radius: var(--card-radius);
    box-shadow: var(--shadow-xl);
    scrollbar-width: thin;
    scrollbar-color: var(--outline-variant) transparent;
}

.live-feed-item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--ghost-border);
}

.live-feed-item:last-child { border-bottom: none; }

.live-feed-timestamp {
    font-size: var(--font-size-2xs);
    font-family: var(--font-label);
    color: var(--on-surface-variant);
    white-space: nowrap;
    min-width: 56px;
}

.live-feed-content {
    font-size: var(--font-size-md);
    line-height: 1.5;
    color: var(--on-surface);
    flex: 1;
    min-width: 0;
}

/* ============================
   Code Block — Dark bg code display with language tabs
   ============================ */
.code-block {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    border: 1px solid var(--glass-border, transparent);
    overflow: hidden;
    font-family: 'JetBrains Mono', 'Fira Code', monospace;
    font-size: var(--font-size-md);
    line-height: 1.6;
}

.code-block-content {
    padding: 1rem 1.25rem;
    overflow-x: auto;
    color: var(--on-surface);
    white-space: pre;
}

/* ============================
   Curator Tray — Glassmorphic floating filter panel
   ============================ */
.curator-tray {
    position: fixed;
    bottom: 5rem;
    right: 1.5rem;
    z-index: 50;
    padding: 1.25rem;
    min-width: 280px;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    border-radius: var(--panel-radius, var(--card-radius));
    box-shadow: var(--shadow-xl);
    border: 1px solid var(--ghost-border);
}

@media (max-width: 767px) {
    .curator-tray {
        position: fixed;
        bottom: 4.5rem;
        left: 1rem;
        right: 1rem;
        min-width: unset;
    }
}

/* ============================
   Monolith Hero — Full-width surface-dim + nested offset card
   ============================ */
.monolith-hero {
    position: relative;
    background: var(--surface-dim);
    padding: 3rem 2rem;
    margin: -1.5rem -1.5rem 1.5rem;
}

.monolith-hero-card {
    background: var(--surface-bright, var(--surface-container));
    padding: var(--space-6);
    border-radius: var(--card-radius);
    box-shadow: var(--shadow-xl);
    max-width: 720px;
}

/* ============================
   Technical Rail — Vertical dark strip with icon buttons
   ============================ */
.technical-rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 0.5rem;
    background: var(--surface-container-lowest);
    min-width: 48px;
}

.technical-rail-btn {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    background: transparent;
    border: none;
    color: var(--on-surface-variant);
    cursor: pointer;
    border-radius: var(--btn-radius);
    transition: background var(--transition-btn), color var(--transition-btn);
}

.technical-rail-btn:hover,
.technical-rail-btn.active {
    background: var(--surface-container);
    color: var(--primary);
}

/* ============================
   Infrastructure Chip — Sharp corners, label-sm type
   ============================ */
.infrastructure-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    background: var(--surface-container-highest);
    border-radius: var(--btn-radius);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--on-surface-variant);
}

/* ============================
   Pulse Tint — AI processing breathing animation
   ============================ */
@keyframes pulse-tint {
    0%, 100% { opacity: 0.1; }
    50%      { opacity: 0.3; }
}

.pulse-tint {
    position: relative;
}

.pulse-tint::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--surface-tint, var(--primary));
    border-radius: inherit;
    animation: pulse-tint 2s ease-in-out infinite;
    pointer-events: none;
}

/* ============================
   Radar Chart — Concentric circle container
   ============================ */
.radar-chart {
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    max-width: 320px;
    margin: 0 auto;
}

/* DESIGN.md: Radius-full */
.radar-chart-ring {
    position: absolute;
    inset: 0;
    border: 1px solid var(--ghost-border);
    border-radius: var(--radius-full);
}

.radar-chart-ring:nth-child(2) { inset: 15%; }
.radar-chart-ring:nth-child(3) { inset: 30%; }
.radar-chart-ring:nth-child(4) { inset: 45%; }

/* ============================
   Heatmap Grid — Color-coded cells
   ============================ */
.heatmap-grid {
    display: grid;
    gap: 2px;
}

.heatmap-cell {
    aspect-ratio: 1;
    border-radius: var(--btn-radius);
    min-width: 16px;
    min-height: 16px;
    transition: transform var(--transition-card);
}

.heatmap-cell:hover { transform: scale(1.2); }

.heatmap-cell.level-0 { background: var(--surface-container); }
.heatmap-cell.level-1 { background: color-mix(in srgb, var(--primary) 20%, transparent); }
.heatmap-cell.level-2 { background: color-mix(in srgb, var(--primary) 40%, transparent); }
.heatmap-cell.level-3 { background: color-mix(in srgb, var(--primary) 60%, transparent); }
.heatmap-cell.level-4 { background: var(--primary); }

/* ============================
   Ghost Button — No background, primary text
   ============================ */
.ghost-button {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    background: transparent;
    border: 1px solid var(--ghost-border);
    border-radius: var(--btn-radius);
    color: var(--primary);
    font-size: var(--font-size-md);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--transition-btn), color var(--transition-btn);
}

.ghost-button:hover {
    background: var(--surface-container-high);
}

/* ============================
   Skeleton Pulse Animation
   ============================ */
@keyframes skeleton-pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 0.8; }
}

.skeleton {
    background: var(--surface-container-high);
    border-radius: var(--btn-radius);
    animation: skeleton-pulse 1.5s ease-in-out infinite;
}

.skeleton-text { height: 0.875rem; width: 100%; }
/* DESIGN.md: Radius-full */
.skeleton-circle { width: 40px; height: 40px; border-radius: var(--radius-full); }
.skeleton-card { height: 120px; width: 100%; border-radius: var(--card-radius); }
.skeleton-table-row { height: 2.5rem; width: 100%; margin-bottom: 0.5rem; }
.skeleton-chart { height: 200px; width: 100%; border-radius: var(--card-radius); }

/* ============================
   Kbd Shortcut
   ============================ */
kbd {
    display: inline-block;
    /* ref-nav #8: beyaz tus kapagi, hayalet cerceve, koyu metin. */
    min-width: 1.75rem;
    text-align: center;
    padding: 0.25rem 0.5rem;
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    box-shadow: 0 1px 0 var(--ghost-border);
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 600;
    border: 1px solid var(--ghost-border);
    border-radius: var(--btn-radius);
    line-height: 1.4;
    vertical-align: middle;
}

/* ============================
   Mini Chart (pure CSS)
   ============================ */
.mini-chart {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 48px;
    min-width: 60px;
}

.mini-chart-bar {
    flex: 1;
    background: var(--primary);
    opacity: 0.6;
    border-radius: var(--btn-radius) var(--btn-radius) 0 0;
    min-width: 4px;
    transition: opacity var(--transition-card);
}

.mini-chart-bar:hover { opacity: 1; }

.mini-chart-sparkline {
    display: flex;
    align-items: flex-end;
    gap: 1px;
    height: 32px;
}

.mini-chart-sparkline .mini-chart-bar {
    width: 2px;
    border-radius: var(--btn-radius);
}

/* ══ EĞİLİM ÇUBUĞU — satır içi mikro grafik ══════════════════════════════
   ÖLÇÜLDÜ 2026-09-16. Paket `.mini-chart-sparkline` sunuyordu ama iki eksiği
   vardı: (a) rengi sabit `--primary` idi, yani bir DURUM eğilimini (düşen
   başarı oranı) marka tonuyla çiziyordu; (b) son değer vurgusu yoktu, yedi
   çubuk eşit ağırlıkta duruyor ve göz "bugün"ü bulamıyordu.

   `.trend-spark` bu iki eksiği kapatır ve KPI kartında da tablo satırında da
   aynı görünür. Durum rengi `--spark-tint` üzerinden gelir; markup
   `style="--spark-tint: var(--state-error)"` yazar, ham hex DEĞİL.

   Yükseklik yüzdeyle verilir (`--spark-h`), böylece kap yüksekliği değişse de
   oran korunur — sabit px, kartta ve satırda farklı görünürdü.

   ÖLÇÜLDÜ 2026-09-16 — **`--spark-h` SERİYE GÖRE normalize edilir, mutlak
   değerle DEĞİL.** İlk sürüm ham metriği (0-100 yüzde) doğrudan yüksekliğe
   çeviriyordu ve dar aralıklı seriler DÜMDÜZ görünüyordu:

       seri [95,92,88,80,84,86,87]  ->  yükseklikler 21,20,19,18,18,19,19
                                        aralık yalnız 3px, desen görünmez

   Kap yüksekliğini artırmak çözmedi (22→32px, aralık 3→4px). Doğru okuma:
   eğilim çubuğu mutlak düzeyi değil DEĞİŞİMİ anlatır. Seri kendi min-max
   aralığında normalize edilince aynı veri 19px'lik bir desen üretir.

   Markup şunu hesaplar (sunucu tarafı, tek satır):
       h = 15 + (v - min) / (max - min) * 85     [min==max ise 50]

   Mutlak düzey ZATEN yanındaki sayıda yazılıdır (%87,1); çubuğun işi onu
   tekrar etmek değil, nereden gelindiğini göstermek. */
.trend-spark {
    display: inline-flex;
    align-items: flex-end;
    gap: 2px;
    height: 24px;
    flex-shrink: 0;
}

.trend-spark > * {
    width: 4px;
    min-height: 3px;
    height: var(--spark-h, 50%);
    border-radius: 2px;
    /* Geçmiş çubuklar soluk: göz son değere gider. */
    background: color-mix(in srgb, var(--spark-tint, var(--primary)) 28%, transparent);
}

/* SON değer tam renkte — "şu an" buradadır. */
.trend-spark > :last-child {
    background: var(--spark-tint, var(--primary));
}

/* Delta rozeti — eğilimin YÖNÜ sözcükle de okunur (renk tek sinyal değil). */
.trend-delta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-family: var(--font-body);
    font-size: var(--font-size-sm);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--on-surface-variant);
    white-space: nowrap;
}

.trend-delta--up { color: var(--state-success-text); }
.trend-delta--down { color: var(--state-error-text); }

/* ============================
   Timeline
   ============================ */
.timeline {
    position: relative;
    padding-left: 2rem;
}

.timeline::before {
    content: '';
    position: absolute;
    left: 7px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--ghost-border);
}

.timeline-item {
    position: relative;
    padding-bottom: 1.25rem;
}

/* DESIGN.md: Radius-full */
.timeline-dot {
    position: absolute;
    left: -2rem;
    top: 0.25rem;
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    background: var(--primary);
    border: 2px solid var(--surface);
    z-index: 1;
}

.timeline-time {
    font-size: var(--font-size-2xs);
    color: var(--on-surface-variant);
    margin-bottom: 0.125rem;
}

.timeline-title {
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--on-surface);
}

.timeline-desc {
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
    line-height: 1.5;
}

/* ============================
   Step Indicator
   ============================ */
.step-indicator {
    display: flex;
    align-items: center;
    gap: 0;
    width: 100%;
}

.step-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 1;
    position: relative;
}

/* DESIGN.md: Radius-full */
.step-circle {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-full);
    display: grid;
    place-items: center;
    font-size: var(--font-size-2xs);
    font-weight: 700;
    z-index: 1;
}

.step-circle.completed {
    background: var(--primary);
    color: var(--on-primary);
}

.step-circle.active {
    background: var(--primary);
    color: var(--on-primary);
    box-shadow: 0 0 0 3px var(--primary-glow);
}

.step-circle.pending {
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
}

.step-label {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--on-surface-variant);
    margin-top: 0.375rem;
    text-align: center;
    max-width: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.step-connector {
    position: absolute;
    top: 14px;
    left: 50%;
    width: 100%;
    height: 2px;
    background: var(--ghost-border);
    z-index: 0;
}

.step-connector.completed { background: var(--primary); }

/* ============================
   Avatar
   ============================ */
/* DESIGN.md: Radius-full */
.avatar {
    /* --avatar-size is provided via inline style by the Avatar primitive (per-instance). */
    --avatar-size: 32px;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--avatar-size);
    height: var(--avatar-size);
    font-size: calc(var(--avatar-size) * 0.4);
    border-radius: var(--radius-full);
    overflow: hidden;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    font-family: var(--font-headline);
    font-weight: 700;
    flex-shrink: 0;
}

.avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* DESIGN.md: Radius-full */
.avatar-status {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    border: 2px solid var(--surface);
}

/* Durum renkleri Avatar.razor.css'te (status-*); buradaki .avatar-status.online ailesi hiç
   eşleşmiyordu — bileşen "online" değil "status-online" basar. ÖLÇÜLDÜ 2026-10-01. */

/* ============================
   Filter Bar
   ============================ */
.filter-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.75rem 0;
    min-width: 0;
}

/* KANONİK GİRDİ AİLESİNE HİZALI. ÖLÇÜLDÜ 2026-09-03: bu kural min-height 40px
   ve 0.5rem/0.75rem dolgu dayatıyordu; özgüllüğü (0-1-1) kanonik .filter-select
   ailesinden (0-1-0) yüksek olduğu için onu EZİYORDU. Sonuç: aynı filtre
   seçicisi bazı sayfalarda 40px, bazılarında 44px. 40px ayrıca WCAG 2.5.5
   dokunma hedefi minimumunun (44px) ALTINDA.

   Kural SİLİNMEDİ, kanoniğe hizalandı: 22 sınıfsız <select> ölçüldü ve onlar
   stillerini yalnız buradan alıyor — silmek onları çıplak bırakırdı. */
.filter-bar select {
    min-height: 44px;
    padding: 0.625rem 0.875rem;
    /* Girdi ailesiyle AYNI dil (2026-09-16): kart düzleminde şeffaf + hayalet
       çerçeve. Ayrı yazılırsa biri düzeltilip diğeri unutulur. */
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    color: var(--on-surface);
    border: none;
    border-radius: var(--input-radius);
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    cursor: pointer;
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    min-height: 32px;
    padding: 0.25rem 0.75rem;
    /* ref-37: acik, cerceveli cip; etkin olan acik teal dolgu. Onceki koyu teal dolgu her cipi
       "secili" gibi gosteriyordu ve etkin/pasif ayrimi kayboluyordu. */
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    border: 0;
    border-radius: var(--btn-radius);
    font-size: 14px;
    font-weight: 500;
}

.filter-chip.filter-chip-active,
.filter-chip.active,
.filter-chip[aria-pressed="true"] {
    /* ref-nav #5: etkin cip ACIK teal tonu + teal cerceve; metin okunur koyu teal. */
    background: color-mix(in srgb, var(--primary-container) 38%, var(--surface-container-lowest));
    color: var(--on-surface);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);
}

.filter-chip-remove {
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    min-width: 24px;
    min-height: 24px;
    padding: 0;
    font-size: var(--font-size-base);
    line-height: 1;
    opacity: 0.7;
}

.filter-chip-remove:hover { opacity: 1; }

/* ── Segmentli aç/kapa düğmesi ─────────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-15: `.toggle-btn` 19 sayfa CSS'inde tanımlıydı — 38 tanım
   ama yalnız İKİ gövde: taban ve `:hover`. On dokuzu da birebir aynıydı,
   yani saf kopya. Kanonik tanım burada. */
.toggle-btn {
    padding: 0.35rem 0.75rem;
    border: none;
    border-radius: var(--btn-radius);
    background: transparent;
    box-shadow: 0 0 0 1px var(--primary);
    color: var(--primary);
    font-size: 0.8rem;
    cursor: pointer;
    transition:
        background var(--transition-btn),
        color var(--transition-btn);
}

.toggle-btn:hover,
.toggle-btn.active,
.toggle-btn[aria-pressed="true"] {
    background: var(--primary);
    color: var(--on-primary);
}

/* ============================
   Tag Input
   ============================ */
.tag-input-wrapper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem;
    background: var(--surface-container-highest);
    border-radius: var(--btn-radius);
    min-height: 40px;
}

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1875rem 0.5rem;
    background: var(--surface-container);
    color: var(--on-surface-variant);
    border-radius: var(--btn-radius);
    font-size: var(--font-size-2xs);
    font-weight: 600;
}

.tag-chip button {
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    padding: 0;
    font-size: var(--font-size-sm);
    opacity: 0.6;
}

.tag-chip button:hover { opacity: 1; }

.tag-input-field {
    border: none;
    background: transparent;
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    outline: none;
    flex: 1;
    min-width: 80px;
}

/* ============================
   Date Range Picker
   ============================ */
.date-range-picker {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
}

.date-preset {
    padding: 0.3125rem 0.625rem;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--btn-radius);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-btn);
}

.date-preset:hover { background: var(--surface-container-high); }
.date-preset.active {
    background: var(--primary);
    color: var(--on-primary);
}

.date-range-picker input[type="date"] {
    padding: 0.3125rem 0.5rem;
    background: var(--surface-container-highest);
    color: var(--on-surface);
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-body);
    font-size: var(--font-size-2xs);
}

/* ============================
   Progress Bar
   ============================ */
.progress-bar-wrapper {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 100%;
}

.progress-bar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.progress-bar-label {
    font-size: var(--font-size-2xs);
    font-weight: 600;
    color: var(--on-surface-variant);
}

.progress-bar-value {
    font-size: var(--font-size-2xs);
    font-weight: 700;
    color: var(--on-surface);
}

.progress-bar-track {
    height: 6px;
    background: var(--surface-container-highest);
    border-radius: var(--chip-radius, var(--btn-radius));
    overflow: hidden;
}

/* ÖLÇÜLDÜ 2026-09-15: aynı çubuk iki adla yaşıyordu. `.progress-fill` 13 sayfa
   CSS'inde ayrı tanımlıydı — 29 tanım / 26 gövde; bunların 12'si yalnız RENK
   varyantıydı (meşru), 17'si TABAN ve 16 farklı gövde taşıyordu. Geçiş süresi
   dört ayrı token kullanıyordu (`--transition-toast`, `--transition-btn`, `0.5s`).
   Kanonik taban budur; sayfalar yalnız renk varyantını tutar. */
.progress-bar-fill,
.progress-fill {
    height: 100%;
    background: var(--primary);
    border-radius: var(--chip-radius, var(--btn-radius));
    transition: width var(--transition-toast);
}

/* ============================
   Inline Alert
   ============================ */
.inline-alert {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.75rem 1rem;
    /* Kendi dikey boşluğu YOKTU: 1161 kullanımda uyarı kutusu bir sonraki bloğa
       YAPIŞIYORDU. ÖLÇÜLDÜ 2026-08-26 /notification-center: kardeş aralıkları
       24px - 0px - 24px, yani ritim tam ortada kırılıyordu. Kap zaten gap
       veriyorsa margin çakışması (margin collapse) devreye girmez diye
       margin-block kullanıldı; flex/grid kaplarda gap kazanır. */
    margin-block: var(--space-4, 1rem);
    border-radius: var(--card-radius);
    font-size: var(--font-size-base);
    line-height: 1.5;
}

.inline-alert-info    { background: color-mix(in srgb, var(--primary) 10%, transparent); color: var(--primary); }
.inline-alert-warning { background: color-mix(in srgb, var(--brand-gold) 10%, transparent); color: var(--brand-gold-text); }
.inline-alert-success { background: color-mix(in srgb, var(--brand-teal) 10%, transparent); color: var(--brand-teal-text); }
.inline-alert-error   { background: color-mix(in srgb, var(--error) 10%, transparent); color: var(--error); }

.inline-alert-icon { font-size: var(--icon-md); flex-shrink: 0; margin-top: 1px; }

/* OLCULDU 2026-09-12: govde ve baslik sinifi YOKTU. Baslikli bir uyari
   yazmak isteyen her sayfa kendi <strong>'unu stillendiriyordu — VOIT
   Inline Message'in basligi bilesenin parcasi, sayfanin degil. */
.inline-alert-body { display: flex; flex-direction: column; gap: var(--space-1); min-inline-size: 0; }
.inline-alert-title { font-weight: 600; }

.inline-alert-dismiss {
    margin-left: auto;
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    opacity: 0.5;
    padding: 0;
}

.inline-alert-dismiss:hover { opacity: 1; }

/* ============================
   Copy Button
   ============================ */
.copy-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    background: transparent;
    border: none;
    color: var(--on-surface-variant);
    cursor: pointer;
    border-radius: var(--btn-radius);
    transition: color var(--transition-btn), background var(--transition-btn);
    vertical-align: middle;
}

.copy-btn:hover {
    background: var(--surface-container-high);
    color: var(--primary);
}

.copy-btn .material-symbols-outlined { font-size: 16px; }

/* ============================
   Dropdown Menu
   ============================ */
.dropdown-menu-wrapper { position: relative; display: inline-block; }

.dropdown-menu-panel {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 50;
    min-width: 180px;
    background: var(--surface-container-high);
    border-radius: var(--card-radius);
    box-shadow: var(--shadow-xl);
    padding: 0.375rem 0;
    animation: scale-in 100ms ease;
}

.dropdown-menu-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    cursor: pointer;
    transition: background var(--transition-btn);
}

.dropdown-menu-item:hover { background: var(--surface-container-highest); }
.dropdown-menu-item.danger { color: var(--error); }
.dropdown-menu-item .material-symbols-outlined { font-size: var(--icon-sm); }

/* ============================
   Export Menu trigger
   ============================ */
.export-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 0.75rem;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.03em;
    cursor: pointer;
    transition: all var(--transition-btn);
}

.export-trigger:hover {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.export-trigger .material-symbols-outlined { font-size: 16px; }

/* ============================
   VModal
   ============================ */
.vmodal-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(var(--overlay-scrim-rgb), 0.5);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    display: grid;
    place-items: center;
    animation: fadeIn 150ms ease;
}

.vmodal-panel {
    background: var(--surface-container);
    border-radius: var(--panel-radius, var(--card-radius));
    max-width: 640px;
    width: 90%;
    max-height: 85vh;
    overflow-y: auto;
    padding: var(--space-5);
    animation: scale-in 150ms ease;
}

.vmodal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
}

.vmodal-title {
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--on-surface);
}

.vmodal-close {
    background: none;
    border: none;
    color: var(--on-surface-variant);
    cursor: pointer;
    padding: 0.25rem;
    border-radius: var(--btn-radius);
}

.vmodal-close:hover { color: var(--on-surface); }

.vmodal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ghost-border);
}

/* ============================
   Nav Grid & Cards
   ============================ */
.nav-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 1rem; }

/* ÖLÇÜLDÜ 2026-09-16: `class="nav-grid bento-grid"` — 12 markup kullanımının
   11'i ikisini BİRLİKTE yazıyor ve `.bento-grid` 12 sütun kurar. Kaynak
   sırası `.nav-grid`'i öne alsa da `auto-fill minmax(160px)` dar kapta
   ARTIK SÜTUN üretiyordu: /ai-ops 700px'te `160px 160px 160px 50px x9` —
   `bento-col-2` kartlar 50px'e düşüyor, 2 kart kaptan TAŞIYORDU (1106px >
   604px kap). `.kpi-grid.bento-grid` emsalinin aynısı: ikisi birlikte
   yazıldığında niyet NAV ŞERİDİDİR, özgüllük (0,2,0)'a çıkarılır.
   `auto-fit` + `min()` artık sütun bırakmaz ve tek çocuğu da esnetir. */
.nav-grid.bento-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
}

/* `bento-col-*` 12 SÜTUNLUK bir sisteme göre yazılmıştır; `auto-fit` şeridinde
   anlamı kalmaz ve kartları eşitsiz yapar. ÖLÇÜLDÜ 2026-09-16 /admin-tools
   1920px: `bento-col-2` taşıyan iki kart 375px, taşımayan ikisi 179px —
   AYNI şeritte iki farklı kart boyu. Nav şeridinde her hedef eşit ağırlıklıdır
   (bento'nun editoryal hiyerarşisi burada geçerli değil), bu yüzden span
   nötrlenir. Kapsam dar: yalnız `.nav-grid` içinde. */
.nav-grid.bento-grid > [class*="bento-col-"] {
    grid-column: auto;
}
.nav-card { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-5); background: var(--glass-bg, var(--surface-container-high)); backdrop-filter: blur(var(--blur-sm)); -webkit-backdrop-filter: blur(var(--blur-sm)); border: 1px solid var(--glass-border, transparent); border-radius: var(--card-radius); cursor: pointer; color: var(--on-surface); transition: all var(--transition-default, 200ms ease); }
.nav-card:hover { background: var(--surface-container-highest); border-color: var(--glass-border-hover, transparent); transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.nav-card .material-symbols-outlined { font-size: var(--icon-lg); color: var(--primary); }

/* ============================
   Button Variants
   ============================ */
/* .btn-sm YALNIZ BOYUTTUR — renk dayatmaz. ÖLÇÜLDÜ 2026-09-03, /business-rules:
   kural `background: var(--primary); color: var(--on-primary); border: none`
   da veriyordu ve `.btn-outline-secondary`'nin `transparent`'ını EZİYORDU
   (aynı özgüllük 0-1-0, sonra geldiği için kazanıyor). Sonuç: outline butonlar
   dolu turkuaz görünüyordu — "Düzenle" ile "Sil" ayırt edilemiyordu.
   Bir boyut varyantı renk vermez; renk varyant sınıfının işidir. */
/* .btn-sm PUNTOSU TOKEN'DAN GELİR — SABİT 0.8rem İKİ FARKLI DÜĞME ÜRETİYORDU.
   ÖLÇÜLDÜ 2026-09-06 /admin/rules: aynı .btn-sm sınıfını taşıyan 20 düğme
   İKİ gruba ayrılıyordu — .btn-outline-secondary 12.8px (bu sabit değerden),
   .btn-danger 12px (--font-size-sm). Fark uzun süredir vardı ama yükseklik
   dolgudan geldiği için gizliydi; satır aralığı 1.35'e çıkınca içerik
   min-height'i (36px) aştı ve 37px/36px olarak GÖRÜNÜR oldu.
   0.8rem hiçbir ölçekte yok: --font-size-sm 0.75rem (12px), 2xs 0.6875rem,
   xs 0.625rem. Ölçülen çoğunluk 12px olduğu için --font-size-sm seçildi. */
.btn-sm { min-height: var(--touch-target-min, 44px); padding: 0 0.75rem; font-size: var(--font-size-sm); font-weight: 500; display: inline-flex; align-items: center; gap: 0.35rem; border-radius: var(--btn-radius); cursor: pointer; transition: background var(--transition-btn, 150ms ease), opacity var(--transition-btn, 150ms ease); box-sizing: border-box; }
.btn-sm:hover { opacity: 0.9; }
/* Icon-only button. min-height/min-width pinned to --touch-target-min (44px) so it
   meets WCAG 2.5.5 AAA / Apple HIG / Material touch-target sizing on every device,
   regardless of the visual icon glyph size. justify-content centers the glyph in
   the enlarged hit area. */
.btn-icon {
    background: none;
    border: 1px solid var(--glass-border, var(--ghost-border));
    border-radius: var(--btn-radius);
    padding: 0.4rem;
    min-width: var(--touch-target-min);
    min-height: var(--touch-target-min);
    cursor: pointer;
    color: var(--on-surface-variant);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all var(--transition-default, 200ms ease);
}
.btn-icon:hover { background: var(--surface-container-high); border-color: var(--glass-border-hover, transparent); color: var(--on-surface); }

/* ============================
   Section Navigation
   ============================ */
.sec-back { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--primary); font-size: 0.85rem; font-weight: 500; cursor: pointer; background: none; border: none; margin-bottom: 1rem; }
.sec-section { margin-bottom: 2rem; }

/* ============================
   Empty Text
   ============================ */
.empty-text { text-align: center; padding: 2rem 1rem; color: var(--on-surface-variant); font-size: 0.9rem; }

/* ============================
   Form System — Glass-treated inputs & layout
   ============================ */

/* ── ANAHTAR (toggle) — TEK GÖRÜNÜM ───────────────────────────────────
   ÖLÇÜLDÜ 2026-09-15: aynı anahtar 12 sayfa CSS'inde baştan yazılmıştı ve
   DÖRT farklı boyutta çıkıyordu — 44x24 (6 sayfa), 48x26 (3), 48x28 (1),
   3rem x 1.5rem (1); topuz da 4 ayrı mesafede kayıyordu (18/20/22px, 1.5rem).
   Kullanıcı sayfadan sayfaya farklı bir anahtar görüyordu.

   Kanonik ölçü en yaygın olanıdır: 44x24, topuz 18px, kayma 20px.
   Ray her zaman tam yuvarlaktır (`--chip-radius`) — bir anahtar rayı pill'dir.

   İKİ API de desteklenir, çünkü ikisi de kullanımda:
     • gizli input:  <label class="toggle-switch"><input type="checkbox"><span class="toggle-slider">
     • sınıf:        <div class="toggle-switch active"><span class="toggle-thumb">
   Sayfalar yalnız RENK varyantını kendi CSS'inde tutar. */
.toggle-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    cursor: pointer;
}

.toggle-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

/* Ray: iki API'de de aynı — .toggle-slider (input) veya kapsayıcının kendisi. */
.toggle-slider,
.toggle-switch:not(:has(.toggle-slider)) {
    position: absolute;
    inset: 0;
    background: var(--surface-container-highest);
    border-radius: var(--chip-radius);
    transition: background var(--transition-card);
}

.toggle-switch:not(:has(.toggle-slider)) {
    position: relative;
}

/* Topuz */
.toggle-slider::before,
.toggle-thumb {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    background: var(--surface-container-lowest);
    border-radius: var(--chip-radius);
    transition: transform var(--transition-card);
}

/* Açık durum — her iki API */
/* Odak halkasi — KLAVYE erisilebilirligi.
   OLCULDU 2026-09-18 (/settings/notifications, 8 anahtar): gizli <input>
   odagi ALIYOR (document.activeElement dogruluyor) ama 0px genislikte ve
   opacity 0, yani odak hicbir yerde GORUNMUYORDU: ray outline "none",
   box-shadow "none". Klavyeyle gezen kullanici hangi anahtarda oldugunu
   goremiyordu.

   Halka RAYA basilir, input'a degil: input gorsel olarak yok. Kanonik
   `--focus-ring` token'i kullanilir — paketin butun odak halkalari ondan
   gelir, sabit piksel yazmak o tek kaynagi bolerdi.

   `:focus-visible` secilir (`:focus` degil): fare tiklamasinda halka
   cikmamali, yalnizca klavye gezintisinde.

   HALKA OFFSET'LI, ve bu OLCULMUS bir zorunluluk: ilk surum duz
   `var(--focus-ring)` yaziyordu ve halka raya YAPISIKTI. Anahtar ACIK
   konumdayken ray zemini `--primary` ile doluyor; halka rengi de
   `--focus-ring-color` = `--primary`. Olculdu (/settings/notifications,
   uc tema): kontrast **1.00:1** — yani acik anahtarlarda odak halkasi
   UC TEMADA DA tamamen gorunmezdi. Kapali anahtarlarda sorun yoktu
   (5.01 / 6.76 / 11.27:1), bu yuzden yuzeysel bir bakis "calisiyor" derdi.

   Once yuzey rengiyle bir ayirici halka, sonra asil halka: iki katman
   `--focus-ring-offset` kadar araliyor. */
.toggle-switch input:focus-visible + .toggle-slider,
.toggle-switch:focus-visible:not(:has(.toggle-slider)) {
    box-shadow:
        0 0 0 var(--focus-ring-offset) var(--surface),
        0 0 0 calc(var(--focus-ring-offset) + var(--focus-ring-width)) var(--focus-ring-color);
}

.toggle-switch input:checked + .toggle-slider,
.toggle-switch.active {
    background: var(--primary);
}

.toggle-switch input:checked + .toggle-slider::before,
.toggle-switch.active .toggle-thumb {
    transform: translateX(20px);
    background: var(--on-primary);
}
/* METİN GİRDİSİ — TEK GÖRÜNÜM.
   ÖLÇÜLDÜ 2026-09-03, /home içinde AYNI kapsamda, yalnız sınıf değiştirerek:
       form-input    p=10/14  bg=#2f3a4a
       input-field   p=16/16  bg=#151d28   ← farklı dolgu VE farklı zemin
       field-input   p=8/12   bg=#252f3f   ← üçüncü zemin
       va-input      p=0/0    bg=beyaz     ← HİÇ stil almıyor
       form-control  p=0/0    bg=beyaz     ← HİÇ stil almıyor
       search-input  p=0/0    bg=beyaz     ← HİÇ stil almıyor
       input-sm      p=0/0    bg=beyaz     ← HİÇ stil almıyor
       input-inline  p=4/8    bg=#252f3f
   Sekiz sınıf, BEŞ farklı görünüm; dördü tarayıcı varsayılanına düşüyordu
   (beyaz zemin, sıfır dolgu) — koyu temada göze batan bir kusur.

   Kurumsal UX kaynaklarının "predictable interactions" ilkesi: aynı görevi
   yapan girdi her ekranda aynı görünmeli. Sınıf adları KORUNUR (251 + 117 + …
   kullanım var, hepsini yeniden adlandırmak riskli); hepsi aynı görünüme
   BAĞLANIR. Sayfaya özel boyut varyantları (input-sm, input-inline) kendi
   kurallarıyla bu tabanı ezmeye devam eder — taban yalnız zemin, kenar,
   yazı ve odak davranışını verir. */
/* SINIF LİSTESİ YETMEZ — YENİ SINIF HER ZAMAN ÇIKAR.
   ÖLÇÜLDÜ 2026-09-03: on bir sınıf tek görünüme bağlandıktan SONRA bile
   gerçek sayfalarda beyaz zeminli girdiler kaldı:
       input.notification-search.neu-inset   ×5
       input.registry-search-input           ×1
       select.sort-select                    ×1
   Sınıf listesine eklemek bunu bir tur çözer; bir sonraki yeni sınıfta yine
   kırılır. Bu yüzden ETİKET TABANLI bir zemin kural konur: her metin girdisi
   varsayılan olarak tasarım sisteminin görünümünü alır, sınıflar yalnız
   VARYANT tanımlar.

   ÖZGÜLLÜK: :where() BURADA ÇALIŞMAZ. ÖLÇÜLDÜ 2026-09-03 — Tailwind preflight
   şu kuralı taşıyor:
       button, input, select, optgroup, textarea { background-color: transparent;
                                                   border-radius: 0; ... }
   Özgüllüğü 0-0-1; :where(...) ise 0-0-0. Yani sıfır-özgüllüklü taban preflight
   tarafından EZİLİYOR ve hiç uygulanmıyordu (canlı ölçüm: sınıfsız input
   p=0/0 bg=şeffaf, eşleşen kural 0).
   Bu yüzden ETİKET seçicisi kullanılır: özgüllük preflight ile eşit, sonra
   yüklendiği için kazanır. Sınıf kuralları (0-1-0) yine bunu ezer — varyantlar
   bozulmaz.

   Kapsam dışı: [type=checkbox], [type=radio], [type=range], [type=color],
   [type=file] — bunların kendi kutu modeli var, dolgu/zemin vermek bozar. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="submit"]):not([type="button"]),
textarea,
select {
    min-height: 44px;
    padding: 0.625rem 0.875rem;
    border-radius: var(--input-radius);
    border: none;
    /* KART DÜZLEMİNDE ŞEFFAF — sınıflı ailenin (.form-input …) aynısı.
       ÖLÇÜLDÜ 2026-09-16: bu kural `--surface-container-highest` (#e2e2e2)
       basıyordu ve ETİKET seçicisi olduğu için sınıflı kuralı SONRA yüklenip
       eziyordu. Sonuç: aynı formda `.form-input` yazan girdi de sınıfsız
       girdi de gri kalıyordu — hayalet çerçeve değişikliği hiç görünmedi.
       İki yer AYNI dili konuşmalı; yoksa biri düzeltilip diğeri unutulur. */
    background: var(--surface-container-lowest); /* ref-34 */
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    line-height: 1.4;
    box-shadow: inset 0 0 0 1px var(--outline-variant);
}

/* .filter-select + .form-select AİLEYE EKLENDİ. ÖLÇÜLDÜ 2026-09-03:
   .filter-select 35 dosyada yeniden tanımlıydı — 29 tanım, 9 FARKLI görünüm
   (dolgu 0.45/0.5/0.6/0.75rem, zemin container/-high/-highest/-low). Aileye
   dahil olmadığı için her sayfa kendi değerini icat etmişti. */
.form-input,
.input-field,
.va-input,
.field-input,
.form-control,
.search-input,
.filter-select,
.form-select,
.input-sm,
.input-inline,
.ace-input,
.rsm-input,
.field-sm,
/* OLCULDU 2026-09-12: form-input-alt ve vtextfield AILEYE DAHIL DEGILDI.
   VTextField, VTextArea ve VNumberInput bu ikisini kullaniyor — yani uc
   kanonik bilesen de durum sozlesmesinin DISINDA kaliyordu. */
.form-textarea,
.form-input-alt,
.vtextfield {
    min-height: 44px;
    padding: 0.625rem 0.875rem;
    border-radius: var(--input-radius);
    border: none;
    /* GİRDİ KART DÜZLEMİNDE KALIR. ÖLÇÜLDÜ 2026-09-16: taban zemin
       `--surface-container-highest` (#e2e2e2) idi — rampanın EN KOYU
       basamağı, yani KUYU tonu. Beyaz kart üzerinde ayrım 1.30:1 ve form
       bir "gri kutu yığını" gibi okunuyordu (ürün geri bildirimi).

       Üç aday çizilip karşılaştırıldı; şeffaf + hayalet çerçeve seçildi:
       girdi kartın düzleminde kalır, yapıyı 1px'lik `--ghost-border`
       okutur. Paket bu dili ZATEN biliyordu — `[readonly]` varyantı tam
       böyle yazılmıştı; taban kural onu kullanmıyordu.

       Odak/hover hâlâ ZEMİN değiştirir: boş çerçeve ile dolu alan
       arasındaki fark etkileşimi görünür kılar. */
    background: var(--surface-container-lowest); /* ref-34 */
    box-shadow: inset 0 0 0 1px var(--outline-variant);
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    line-height: 1.4;
    outline: none;
    /* Resting ghost outline + bottom hairline so the field reads as an input
       without a hard 1px border (No-Line rule). */
    transition:
        box-shadow var(--transition-default, 200ms ease),
        background var(--transition-default, 200ms ease);
}

/* -- Cok satirli girdi ------------------------------------------------
   OLCULDU 2026-09-15: `.form-textarea` 21 sayfa CSS'inde ayri ayri
   tanimliydi -- 28 tanim / 17 govde. Uc noktada ayrisiyordu:
     * zemin: `container-high` (11) vs `container` (3) vs `container-highest` (1)
     * yaricap: `card-radius` vs `input-radius`
     * odak halkasi: BES farkli bicim (outline 2px, box-shadow 1px, inset, ...)
   Ustteki 13 girdi sinifi ayni sorun icin zaten birlestirilmisti; textarea
   listeye alinmamisti. Artik ayni tabani paylasiyor -- yalniz cok satirli
   girdiye OZGU olan yukseklik ve yeniden boyutlandirma burada. */
.form-textarea {
    min-height: 96px;
    padding: 0.75rem 0.875rem;
    line-height: 1.5;
    resize: vertical;
}

.form-textarea::placeholder,
.form-input::placeholder,
.input-field::placeholder,
.va-input::placeholder,
.field-input::placeholder,
.form-control::placeholder,
.search-input::placeholder,
.input-sm::placeholder,
.input-inline::placeholder {
    color: color-mix(in srgb, var(--on-surface-variant) 70%, transparent);
}

/* Focus — surface lifts + primary ghost ring + soft outer glow (DESIGN.md). */
.form-textarea:focus,
.form-input:focus,
.input-field:focus,
.va-input:focus,
.field-input:focus,
.form-control:focus,
.search-input:focus,
.filter-select:focus,
.form-select:focus,
.input-sm:focus,
.input-inline:focus,
.ace-input:focus,
.rsm-input:focus,
.field-sm:focus,
.form-input:focus-visible,
.input-field:focus-visible,
.va-input:focus-visible,
.field-input:focus-visible,
.form-control:focus-visible,
.search-input:focus-visible,
.filter-select:focus-visible,
.form-select:focus-visible,
.input-sm:focus-visible,
.input-inline:focus-visible,
.ace-input:focus-visible,
.rsm-input:focus-visible,
.field-sm:focus-visible {
    background: var(--surface-container-high);
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--primary) 55%, transparent),
        0 0 0 3px var(--primary-glow, color-mix(in srgb, var(--primary) 18%, transparent));
}

.form-textarea:disabled,
.form-input:disabled,
.input-field:disabled,
.va-input:disabled,
.field-input:disabled,
.form-control:disabled,
.search-input:disabled,
.input-sm:disabled,
.input-inline:disabled,
.ace-input:disabled,
.rsm-input:disabled,
.field-sm:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* DEVRE DIŞI DÜĞME ETKİN DÜĞMEDEN AYIRT EDİLEBİLMELİ.
   ÖLÇÜLDÜ 2026-09-06 /custom-models: 13 devre dışı düğme opacity:1 ve
   cursor:pointer taşıyordu — etkin eşleriyle BİREBİR aynı görünüyorlardı
   ("Eğit", "Sohbette kullan", "Oluştur"). Kullanıcı tıklıyor, hiçbir şey
   olmuyor; düğmenin bozuk mu yoksa kapalı mı olduğunu anlamanın yolu yok.
   Kök neden: :disabled kuralı yalnız GİRDİ alanları için yazılmıştı
   (yukarıdaki .form-input ailesi, satır 2575) ve düğmeleri hiç kapsamıyordu.
   Tek istisna .data-table-page-btn idi — sayfalama düğmeleri doğru davranıyor,
   genel düğmeler davranmıyordu.
   Aynı görsel dil kullanılır: yarı saydamlık + not-allowed imleci. */
.btn:disabled,
.btn[aria-disabled="true"],
.btn-primary:disabled,
.btn-primary[aria-disabled="true"],
.btn-secondary:disabled,
.btn-secondary[aria-disabled="true"],
.btn-ghost:disabled,
.btn-ghost[aria-disabled="true"],
.btn-danger:disabled,
.btn-danger[aria-disabled="true"],
.btn-sm:disabled,
.btn-sm[aria-disabled="true"],
.btn-chip:disabled,
.btn-chip[aria-disabled="true"],
/* İKON DÜĞMESİ 2026-09-20'de EKLENDİ — yukarıdaki liste onu kapsamıyordu.
   Tarayıcıda ölçüldü (/admin/lexicon-suggestions, "yenile" düğmesi): devre dışı
   hâli etkin hâliyle BİREBİR aynıydı — opacity 1, cursor pointer — oysa kanonik
   .btn aynı anda 0.5 / not-allowed veriyordu. Yükleme sürerken kullanıcı
   tıklıyor, hiçbir şey olmuyor ve düğmenin bozuk mu kapalı mı olduğu
   anlaşılmıyordu. 2026-09-06'daki 13 düğmelik kusurun aynısı, yeni varyantta. */
.btn-icon:disabled,
.btn-icon[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Devre dışı düğme hover'da da tepki vermez — yarı saydamlık korunur.
   Bunu yazmazsak :hover kuralları opacity'yi geri alıp kullanıcıya
   "çalışıyorum" sinyali verir. */
.btn:disabled:hover,
.btn[aria-disabled="true"]:hover,
.btn-primary:disabled:hover,
.btn-secondary:disabled:hover,
.btn-ghost:disabled:hover,
.btn-danger:disabled:hover,
.btn-sm:disabled:hover,
.btn-chip:disabled:hover,
.btn-icon:disabled:hover,
.btn-icon[aria-disabled="true"]:hover {
    opacity: 0.5;
    transform: none;
}

.form-input[aria-invalid="true"] {
    box-shadow:
        inset 0 0 0 1px transparent,
        inset 0 -2px 0 0 var(--error);
}

/* SABİT İKİ SÜTUN RESPONSIVE DEĞİLDİ. ÖLÇÜLDÜ 2026-09-04 /admin/rules/create:
   414px genişlikte sütunlar hâlâ 178px + 166px idi — telefonda iki daracık alan,
   her etiket iki satıra kırılıyordu. `repeat(2, 1fr)` hiçbir kırılma noktası
   tanımıyor; medya sorgusu eklemek yerine auto-fit kullanıldı, böylece kural
   kabın gerçek genişliğine göre kendi karar verir ve her sayfada aynı davranır
   (medya sorgusu kap değil EKRAN ölçer — kenar sütununa konan bir form-grid'de
   yanlış cevap verirdi). 14rem taban: kanonik girdi 44px yüksekliğinde ve
   etiketler VERSİYON gibi uzun olabiliyor. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
    gap: 1rem;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

/* .as-label: hiçbir denetimi etiketlemeyen başlık/değer metni <label> değil <span> olur
   (ölçüldü 2026-10-01, 23 yer) — görünümü aynı kalsın diye aynı kuralı alır. */
.form-group :is(label, .as-label) {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--on-surface-variant);
}

.form-row {
    display: flex;
    /* DAR KAPTA SARMALI. ÖLÇÜLDÜ 2026-09-04, /ml-insights: 313px genişliğinde
       bir kartın içinde üç girdi normal akışta rastgele sarıyordu — "SKU" geniş,
       "14" yanında, "7" alta düşmüş, hizasız. flex-wrap düzenli sarma verir;
       min-width:0 girdilerin kaptan taşmasını engeller (grid/flex öğelerinin
       varsayılan min-width:auto değeri içerikten küçülmeyi engelliyor). */
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
}

/* Girdiler kabı PAYLAŞIR. ÖLÇÜLDÜ 2026-09-04, /ml-insights: üç girdi doğal
   genişlikleriyle 175+64+64+32 = 335px istiyordu, kart içi ise 265px — sığmıyor.
   Yalnız flex-wrap eklemek sarmayı düzenli yapıyor ama son girdi tek başına
   alt satırda kalıyor ve sağı boş duruyor. `flex: 1 1 <taban>` ile girdiler
   mevcut genişliği paylaşır: dar kapta küçülür, geniş kapta yayılır.
   min-width:0 taşmayı engeller (flex öğelerinin varsayılan min-width:auto
   değeri içerikten küçülmeyi engelliyor). */
.form-row > * {
    min-width: 0;
}

/* Metin alanı SATIRI DOLDURUR, sayı alanları altında yan yana paylaşır.
   ÖLÇÜLDÜ 2026-09-04, /ml-insights (kart içi 265px):
     metin 7rem taban → 177px  ·  iki sayı 4.5rem → 144px  ·  boşluk 32px
     toplam 353px > 265px — üç girdi tek satıra FİZİKSEL olarak sığmıyor.
   Sığdırmaya zorlamak yerine düzeni açıkça tanımlıyoruz: uzun değer (SKU,
   ad, kod) kendi satırını alır; kısa sayısal alanlar altta eşit paylaşır.
   Geniş kapta üçü de yan yana gelir, çünkü metin alanının tabanı esnektir. */
.form-row > input:not([type="number"]),
.form-row > select,
.form-row > textarea {
    flex: 1 1 12rem;
}

.form-row > input[type="number"] {
    flex: 1 1 4.5rem;
}

/* ── Error Banner ── */
.error-banner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--state-error-bg);
    color: var(--state-error-text-on-fill, var(--state-error-text, var(--state-error)));
    border-radius: var(--card-radius);
    border: 1px solid var(--state-error-border, transparent);
}

/* ============================
   Enhanced Reference Patterns
   ============================ */

/* Gradient Button — machined metallic finish.
   Uses --gradient-primary (theme-correct fill) so it stays vivid and legible in every theme
   instead of fading to cream in Mixed (where --primary is near-white). */
.btn-gradient {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 1.25rem;
    /* ÖLÇÜLDÜ 2026-09-15: burada `--gradient-accent` kullanılıyordu ve o
       gradyan `--primary-container` (#76abae) ile BİTİYOR. Light temada
       üzerine yazılan beyaz metin o uçta 2.56:1 — WCAG AA'nın (4.5:1)
       altında. `#76ABAE` bir DOLGU tonudur; üzerine beyaz değil
       `--primary-container-text` yazılır. Metin taşıyan bir düğme bu yüzden
       metin-güvenli `--gradient-primary`yi kullanır (iki uç da >= 4.87:1).
       `--gradient-accent` dekoratif yüzeylerde kalmaya devam ediyor. */
    background: var(--gradient-primary), var(--primary);
    color: var(--on-primary);
    font-family: var(--font-label);
    font-weight: 700;
    /* ÖLÇÜLDÜ 2026-09-05: .btn-gradient bir GÖRSEL varyant (degrade dolgu) ama
       tipografiyi de eziyordu. .btn-primary/.btn-secondary --font-size-2xs
       (11px) istiyor, bu kural --font-size-sm (12px) dayatıyordu; sonuçta
       birincil düğme /custom-models'te 12px, /settings/sector'de 14px,
       /agents/workflow-templates'te 12.8px görünüyordu — aynı rol, üç ölçü.
       Varyant dolguyu değiştirir, ölçüyü değil. */
    font-size: var(--font-size-2xs);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--btn-radius);
    cursor: pointer;
    transition: filter var(--transition-btn), box-shadow var(--transition-btn), transform var(--transition-btn);
    /* Premium depth: ambient drop + a soft teal brand glow. */
    box-shadow: 0 6px 18px -8px color-mix(in srgb, var(--overlay-scrim) 45%, transparent);
}
.btn-gradient:hover {
    filter: brightness(1.06);
    box-shadow:
        0 10px 26px -8px color-mix(in srgb, var(--overlay-scrim) 50%, transparent),
        0 0 22px -4px var(--primary-glow-hover, var(--primary-glow));
    transform: translateY(-1px);
}
.btn-gradient:active { transform: translateY(0) scale(0.98); }
.btn-gradient:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Danger Button */
/* DOLGULU YÜZEYDE METİN: aşağıdaki kurallar (.error-banner, .btn-danger,
   .cb-missing, .cb-enabled) rengi --state-*-bg dolgusu ÜSTÜNDE gösterir,
   sayfa zemininde değil. --state-*-text koyu/açık SAYFA zeminine göre
   ayarlıdır ve dolgu onu zemine yaklaştırır: ÖLÇÜLDÜ 2026-09-10,
   .btn-danger dark 3.58 / mixed 3.84 (12px, eşik 4.5). -on-fill
   varyantı üç temada da tanımlı; light'ta aynı değeri taşır çünkü
   orada zaten 5.56 ölçülüyor. */
/* KANONİK BUTON YARIÇAPI. ÖLÇÜLDÜ 2026-09-11: .btn-primary, .btn-secondary
   ve .btn-ghost'un HİÇBİR kuralı yoktu — üçü de yarıçap almıyordu ve ekranda
   köşeli görünüyorlardı. Tarayıcıda sayıldı: /decisions'ta 31, /today'de 23
   buton 0px yarıçapla çiziliyordu (kanonik değer 12px = --btn-radius).
   Kart yarıçapı (--card-radius, 16px) BUTONA UYGULANMAZ: bazı türevler
   (.btn-primary-action, .btn-primary-sm) onu kullanıyordu ve butonlar
   kartlarla aynı yuvarlaklıkta görünüp hiyerarşiyi bozuyordu.
   Bu kural yalnız YARIÇAP verir; renk/dolgu her varyantın kendi kuralında. */
.btn-primary,
.btn-secondary,
.btn-ghost,
.btn-primary-action,
.btn-primary-sm,
.btn-primary-ws {
    border-radius: var(--btn-radius);
}

/* YIKICI EYLEM DOLU KIRMIZIDIR. ÖLÇÜLDÜ 2026-09-16: `.btn-danger` pakette
   İKİ KEZ tanımlıydı ve ikisi çelişiyordu — `veraius-base.css` dolu `--error`
   diyordu, burası yumuşak `--state-error-bg`. Kaynak sırası burayı
   kazandırıyordu ve sonuç ölçüldü:

     yumuşak: zemin/kart ayrımı 1.22:1 · metin 5.28:1
     dolu:    zemin/kart ayrımı 6.46:1 · metin 6.46:1

   Gerçek bir silme diyaloğunda çizildi: yumuşak varyantta "Kalıcı olarak sil"
   ile "Vazgeç" neredeyse eşit ağırlıktaydı — yıkıcı eylem için yanlış
   hiyerarşi. Dolu varyantta eylem baskın, iptal sessiz.

   base.css'teki yorum "no harsh red blocks, per the design manifesto" diyordu;
   ÖLÇÜLDÜ, DESIGN.md'de böyle bir kural YOK. Aynı yorum `--tertiary`nin
   #ffb3af olduğunu söylüyordu — bu yalnız dark'ta doğru (light #ad3e38,
   mixed #F4F4F4 GRİ), üstelik kural zaten `--error` kullanıyordu.

   `1px solid` kenarlık da kaldırıldı: dolu zeminde gereksiz ve CLAUDE.md'nin
   "No-Line" kuralına aykırı. */
.btn-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.375rem 1rem;
    background: var(--state-error);
    color: var(--on-error);
    font-family: var(--font-label);
    font-weight: 700;
    font-size: var(--font-size-sm);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border: none;
    border-radius: var(--btn-radius);
    cursor: pointer;
    transition: background var(--transition-btn), box-shadow var(--transition-btn);
}

/* Hover YÜKSELTİR, rengi değiştirmez: dolu zemin zaten en güçlü sinyal;
   üstüne renk değişimi eklemek "başka bir eylem" gibi okunur. */
.btn-danger:hover {
    box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--state-error) 45%, transparent);
}

/* Decorative Card Background Icon */
/* Dekoratif kart filigranı (543 kullanım). right: 1rem onu kartın SAĞ EYLEM
   ALANININ tam üstüne koyuyordu: /system-status'ta durum rozetlerinin arkasında
   "boş gölge kutusu" gibi görünen buydu — ÖLÇÜLDÜ 2026-08-26 ekran görüntüsü.
   Filigran arka planda kalmalı, okunacak içeriğin arkasında değil: kenara itildi,
   yarısı kırpılıyor ve opaklık düşürüldü. */
.card-bg-icon {
    position: absolute;
    top: 50%;
    right: -1.25rem;
    transform: translateY(-50%);
    font-size: var(--watermark-sm);
    opacity: 0.04;
    color: var(--primary);
    pointer-events: none;
    user-select: none;
    line-height: 1;
    z-index: 0;
}

/* FİLİGRAN GRID HÜCRESİ İŞGAL ETMEMELİ. ÖLÇÜLDÜ 2026-09-04,
   /governance/privacy @1440px: `dashboard` filigranı .kpi-grid'in DOĞRUDAN
   çocuğuydu ve 80px genişlikte bir hücre kaplıyordu — sağ kenarı 1413px,
   kabuk 1393px'te bitiyor, yani 20px taşıyordu. 24 sayfada aynı yerleşim.

   `position: absolute` tek başına yetmiyor: konumlanma kabı (position:relative
   olan bir ata) yoksa öğe akıştan çıkmıyormuş gibi ölçülüyor. Grid/flex
   kabında filigranı ilk ize sabitleyip 0 genişliğe indiriyoruz — görünüşü
   değişmez (zaten mutlak konumlu), ama artık yerleşimi etkilemez. */
:where(.kpi-grid, .bento-grid, .card-grid, .stats-grid) > .card-bg-icon {
    grid-area: 1 / 1;
    width: 0;
    justify-self: start;
}

/* FİLİGRAN KENDİ KABINDAN ÇIKMAMALI. ÖLÇÜLDÜ 2026-09-18, /analytics @1280px:
   filigranın ebeveyni (`.nav-section`) `position: static` olduğu için
   `right: -1.25rem` UZAK bir atada çözülüyor ve öğe viewport'un 20px dışına
   taşıyordu — sayfa yatay kayıyordu (scrollWidth 1300 / clientWidth 1280).
   Kanıt: filigranları `display:none` yapmak kaymayı TAM olarak kaldırdı
   (1300 → 1280).

   Yukarıdaki kural yalnız IZGARA çocuğunu ele alıyordu; bu kusur ızgara
   dışındaydı. Çare ebeveyni konumlanma kabı yapmak: filigran artık kendi
   kutusuna göre çözülür, görünüşü değişmez (zaten mutlak konumlu ve %4
   opaklıkta), ama sayfayı kaydıramaz. `:has()` ile yalnız filigran TAŞIYAN
   kaplar hedeflenir — başka hiçbir yerleşim etkilenmez. */
:where(*:has(> .card-bg-icon)) {
    position: relative;
}

/* Filigranın üstündeki her şey okunabilir kalsın. */
.card-layered > *:not(.card-bg-icon),
.card > *:not(.card-bg-icon) {
    position: relative;
    z-index: 1;
}

/* Layered Card — deponun EN YAYGIN kart deseni: 994 kullanım / 296 dosya.
   ÖLÇÜLDÜ 2026-09-05 tarayıcıda, üç kusur:

   1. GÖRÜNMEZ AMA YER KAPLAYAN KENARLIK. `border: 1px solid var(--glass-border)`
      yazıyordu; --glass-border HİÇBİR temada tanımlı DEĞİL (base/light/dark/mixed
      token JSON'larının hiçbirinde yok), yani her zaman `transparent` yedeğine
      düşüyordu. Ölçüm: borderTopColor rgba(0,0,0,0), borderTopWidth 1px,
      offsetWidth 471 / clientWidth 469 — hiçbir şey göstermeyen 2px. Ayrıca
      DESIGN.md'nin "No-Line" kuralına aykırı: sınır zemin kaymasıyla verilir.

   2. ARKASINDA BULANIKLAŞTIRACAK BİR ŞEY OLMAYAN BLUR. Kartların arkasında düz
      tek renk bir yüzey var (ölçüldü: main.ws-main = rgb(244,245,247)).
      backdrop-filter'ın görsel bir işi yok; 994 kartta yalnız compositing
      katmanı maliyeti kalıyordu.

   3. %78 SAYDAM ZEMİN. Aynı sebeple: düz yüzeye karışıp kartın ayırt
      ediciliğini azaltıyordu. Referans kart (.card / .vcard) opak
      --surface-container kullanıyor; ölçümde 34 kart o imzadaydı, 11 kart
      camdaydı — aynı ekranda iki farklı kart görünümü.

   Derinlik artık kanonik ailedeki gibi tonal yüzey + gölge ile veriliyor.
   ::before degrade katmanı KORUNDU — bu desenin ayırt edici imzası odur ve
   opak zeminin üstünde de çalışır. */
.card-layered {
    position: relative;
    /* KART DUZLEMI (kit 27): `--surface-container` sayfa ZEMINI tonuydu,
       kart gorunmez kaliyordu. ÖLÇÜLDÜ 2026-09-14 /agents/workflow-runs:
       5 kartin 1'i (.card-layered) #EEEEEE basiyordu, digerleri beyaz.
       Taban kural bu sinifi YAKALAMAZ cunku adi `card-` ile BASLIYOR ve
       o desen ic parcalar (card-header/body/meta) icin disarida tutuluyor. */
    background: var(--surface-container-lowest);
    /* Ground State: golge yok (kit 27). */
    box-shadow: none;
    border-radius: var(--card-radius);
    padding: 1.5rem;
    overflow: hidden;
    transition: all var(--transition-default);
}
.card-layered::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 4%, transparent) 0%, transparent 60%);
    pointer-events: none;
}
.card-layered:hover {
    border-color: var(--glass-border-hover, transparent);
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
}

/* Hover Lift — generic transform utility */
.hover-lift { transition: transform var(--transition-default), box-shadow var(--transition-default); }
.hover-lift:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }

/* Metric Hero XL — extra large number display */
.metric-hero-xl .metric-hero-value {
    font-size: 4rem;
    letter-spacing: -0.03em;
}

/* Label Tracked — wide letter-spacing for labels */
.label-tracked {
    font-family: var(--font-label);
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
}

/* Animated Pulse Dot for status indicators */
/* DESIGN.md: Radius-full */
.pulse-dot-animated {
    width: 6px;
    height: 6px;
    border-radius: var(--radius-full);
    position: relative;
}
/* SONSUZ NABIZ KALDIRILDI. Bu nokta 29 yerde kullanılıyor ve neredeyse her
   kullanımda HEMEN YANINDA bir durum rozeti var ("ÇALIŞIYOR", "DÜŞÜK PERFORMANS"):
   rozet durumu zaten söylüyor, noktanın ayrıca titremesi bilgi eklemiyor, yalnız
   dikkat çalıyordu. ÖLÇÜLDÜ 2026-08-26: /system-status'ta aynı anda 24 sonsuz
   animasyon vardı. Yerine sabit bir hale — nokta hâlâ öne çıkıyor, ama durmuyor.
   Sınıf adı korundu ki 29 çağrı yerine dokunmak gerekmesin. */
.pulse-dot-animated::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: var(--radius-full);
    background: inherit;
    opacity: 0.22;
}

/* Accent Link — underline accent style */
.accent-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    color: var(--primary);
    font-size: var(--font-size-md);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 2px solid var(--primary);
    padding-bottom: 1px;
    transition: opacity var(--transition-fast);
}
.accent-link:hover { opacity: 0.8; }

/* Infrastructure Chip — small tag for metadata */
.infra-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
    background: var(--surface-container-highest);
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    border-radius: var(--btn-radius);
}

/* Ring Progress (SVG-based) */
.ring-svg { transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: var(--surface-container-high); }
.ring-fill { fill: none; stroke: var(--primary); stroke-linecap: square; transition: stroke-dashoffset 600ms ease-out; }
.ring-fill.secondary { stroke: var(--secondary); }
.ring-fill.tertiary { stroke: var(--tertiary); }
.ring-fill.success { stroke: var(--state-success); }
.ring-fill.warning { stroke: var(--state-warning); }
.ring-fill.error { stroke: var(--state-error); }

/* Mini Bar Chart */
.mini-bar-chart { display: flex; align-items: flex-end; gap: 2px; height: 40px; }
.mini-bar { flex: 1; height: var(--bar-h, 0%); background: var(--primary); border-radius: var(--btn-radius); min-width: 3px; transition: height var(--transition-default); }
.mini-bar:hover { background: var(--primary-fixed); }
.mini-bar.secondary { background: var(--secondary); }
.mini-bar.tertiary { background: var(--tertiary); }

/* Legend */
.chart-legend { display: flex; flex-wrap: wrap; gap: 1rem; }
.legend-item { display: flex; align-items: center; gap: 0.375rem; font-size: var(--font-size-sm); color: var(--on-surface-variant); }
.legend-swatch { width: 8px; height: 8px; border-radius: var(--btn-radius); flex-shrink: 0; }

/* Metric Subscript — unit label next to large numbers */
.metric-unit {
    font-size: var(--font-size-base);
    font-weight: 600;
    color: var(--on-surface-variant);
    margin-left: 0.25rem;
}

/* Bento Column Shortcuts */
.bento-col-1 { grid-column: span 1; }
.bento-col-2 { grid-column: span 2; }
.bento-col-3 { grid-column: span 3; }
.bento-col-4 { grid-column: span 4; }
.bento-col-5 { grid-column: span 5; }
.bento-col-6 { grid-column: span 6; }
.bento-col-7 { grid-column: span 7; }
.bento-col-8 { grid-column: span 8; }
.bento-col-9 { grid-column: span 9; }
.bento-col-10 { grid-column: span 10; }
.bento-col-11 { grid-column: span 11; }
.bento-col-12 { grid-column: span 12; }
@media (max-width: 767px) { [class*="bento-col-"] { grid-column: span 12; } }

/* Row-span helpers */
.bento-row-2 { grid-row: span 2; }
.bento-row-3 { grid-row: span 3; }

/* Empty-state hint for lists with no data */
.empty-state-hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 2rem 1rem;
    color: var(--on-surface-variant);
    font-size: 0.95rem;
    opacity: 0.8;
}
.empty-state-hint .material-symbols-outlined {
    font-size: var(--font-size-2xl);
}

/* ============================
   Visual Foundation Utilities
   See docs/design-system/foundations.md
   ============================ */

/* Type scale helpers — token-referenced text utilities */
.va-text-xs   { font-size: var(--font-size-xs);   line-height: var(--leading-normal); }
.va-text-2xs  { font-size: var(--font-size-2xs);  line-height: var(--leading-normal); }
.va-text-sm   { font-size: var(--font-size-sm);   line-height: var(--leading-normal); }
.va-text-base { font-size: var(--font-size-base); line-height: var(--leading-normal); }
.va-text-lg   { font-size: var(--font-size-lg);   line-height: var(--leading-snug); }
.va-text-xl   { font-size: var(--font-size-xl);   line-height: var(--leading-snug); }
.va-text-2xl  { font-size: var(--font-size-2xl);  line-height: var(--leading-snug); }
.va-text-3xl  { font-size: var(--font-size-3xl);  line-height: var(--leading-tight); }
.va-text-4xl  { font-size: var(--font-size-4xl);  line-height: var(--leading-tight); }
.va-text-5xl  { font-size: var(--font-size-5xl);  line-height: var(--leading-tight); }

/* Fluid display — responsive clamp'li başlık */
.va-fluid-display {
    font-size: clamp(var(--font-size-3xl), 5vw + 1rem, var(--font-size-9xl));
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tightest);
    font-family: var(--font-headline);
    font-weight: 800;
}

/* Reading width — optimal prose */
.va-prose {
    max-width: 65ch;
    line-height: var(--leading-relaxed);
}

/* Icon size helpers */
.va-icon-xs  { font-size: var(--icon-xs);  width: var(--icon-xs);  height: var(--icon-xs); }
.va-icon-sm  { font-size: var(--icon-sm);  width: var(--icon-sm);  height: var(--icon-sm); }
.va-icon-md  { font-size: var(--icon-md);  width: var(--icon-md);  height: var(--icon-md); }
.va-icon-lg  { font-size: var(--icon-lg);  width: var(--icon-lg);  height: var(--icon-lg); }
.va-icon-xl  { font-size: var(--icon-xl);  width: var(--icon-xl);  height: var(--icon-xl); }
.va-icon-2xl { font-size: var(--icon-2xl); width: var(--icon-2xl); height: var(--icon-2xl); }

/* Focus ring — unified :focus-visible */
.va-focus-ring:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
}

/* Semantic color aliases — state.* paletini top-level isimlerle expose et */

/* Vertical rhythm — consistent spacing between siblings */
.va-rhythm > * + *    { margin-top: var(--space-4); }
.va-rhythm > * + h2,
.va-rhythm > * + h3   { margin-top: var(--space-8); }
.va-rhythm > h2 + *,
.va-rhythm > h3 + *   { margin-top: var(--space-3); }

/* Spacing shortcuts — token'lı padding/gap utilities */
.va-p-4 { padding: var(--space-4); }
.va-p-5 { padding: var(--space-5); }
.va-p-6 { padding: var(--space-6); }
.va-p-7 { padding: var(--space-7); }
.va-p-8 { padding: var(--space-8); }
.va-gap-2 { gap: var(--space-2); }
.va-gap-3 { gap: var(--space-3); }
.va-gap-4 { gap: var(--space-4); }
.va-gap-5 { gap: var(--space-5); }
.va-gap-6 { gap: var(--space-6); }

/* ============================
   Focus Rings (Accessibility)
   ============================ */
/* ÖLÇÜLDÜ 2026-09-15: bu seçici listesi GÖVDESİZ kalmıştı (son satır virgülle
   bitiyordu) ve bir sonraki kuralı YUTUYORDU. Tarayıcıda ölçülen sonuç:
   `.copy-btn:focus-visible, … { font-weight: 400 }` — yani dört düğme odak
   halkası yerine font-weight alıyordu VE `.fw-400` utility'si ölüydü.
   Gövde geri verildi; ikisi de ayrı kurallar. */
.copy-btn:focus-visible,
.search-bar-clear:focus-visible,
.data-table-page-btn:focus-visible,
.filter-chip-remove:focus-visible {
    outline: var(--state-focus-ring);
    outline-offset: var(--state-focus-offset);
}

/* Font-weight utilities */
.fw-400 { font-weight: 400; }
.fw-600 { font-weight: 600; }
.fw-700 { font-weight: 700; }

/* Inline button — sits inside a sentence, inherits text flow */
.btn-inline {
    display: inline;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: var(--primary);
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--transition-btn);
}
.btn-inline:hover { text-decoration-color: var(--primary); }

.tab-btn:focus-visible,
.filter-bar select:focus-visible,
.form-input:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-ghost:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* ============================
   Reduced Motion
   ============================ */
@media (prefers-reduced-motion: reduce) {
    .card-interactive:hover,
    .card-interactive:focus-within {
        transform: none;
    }

    .scale-in {
        animation: none;
    }

    .ripple::after {
        animation: none;
    }

    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* ============================
   Workload Bar Classes
   ----------------------------
   Default tonal palette consumed by OrchestratorAgentCards.razor and
   any other un-scoped surface. AgentOrchestrator.razor.css redefines
   these (medium=state-warning, high=state-error+pulse) and wins via
   Blazor's [b-xxxxx] scope attribute (0,1,1) > (0,1,0) — no
   !important needed.
   ============================ */
.workload-high   { background: var(--error); }
.workload-medium { background: var(--brand-gold); }
.workload-low    { background: var(--brand-teal); }

/* ============================
   Orchestrator Chat Panel
   ============================ */
.orch-center {
    display: flex;
    flex-direction: column;
    background: var(--surface-container);
    min-height: 600px;
    margin-top: 2rem;
}

.chat-area {
    flex: 1;
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    overflow-y: auto;
}

.chat-greeting {
    text-align: left;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--ghost-border);
}

.chat-title { margin-bottom: 0.25rem; }

.chat-message {
    display: flex;
}

.msg-user { justify-content: flex-end; }
.msg-ai   { justify-content: flex-start; }

.msg-bubble {
    max-width: 75%;
    padding: 1rem 1.25rem;
    background: var(--surface-container-high);
    position: relative;
}

.msg-user .msg-bubble {
    background: var(--primary-container);
}

.msg-sender {
    display: block;
    margin-bottom: 0.375rem;
    color: var(--on-surface-variant);
}

.msg-bolt {
    color: var(--primary);
    margin-left: 0.25rem;
    vertical-align: middle;
}

.msg-text { margin: 0; }

.findings-list {
    list-style: none;
    padding: 0;
    margin: 0.75rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.finding-item {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
}

.finding-index {
    font-family: var(--font-mono);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    flex-shrink: 0;
    padding-top: 0.1em;
}

.finding-source {
    display: block;
    margin-top: 0.125rem;
    opacity: 0.7;
}

.msg-divider {
    height: 1px;
    background: var(--ghost-border);
    margin: 0.75rem 0;
}

.msg-suggestion { font-style: italic; opacity: 0.8; }

.chat-input-area {
    border-top: 1px solid var(--ghost-border);
    padding: 1rem 2rem 1.5rem;
    background: var(--surface-container-low);
}

.chat-input-wrapper {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--surface-container-highest);
    padding: 0.625rem 1rem;
    margin-bottom: 0.75rem;
}

.chat-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--on-surface);
    font-family: var(--font-body);
    font-size: var(--font-size-base);
}

.chat-input::placeholder { color: var(--on-surface-variant); opacity: 0.6; }

.send-btn {
    background: var(--primary);
    border: none;
    color: var(--on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    cursor: pointer;
    flex-shrink: 0;
    transition: background var(--transition-btn);
}

.send-btn:hover { background: var(--primary-container); }

.chat-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.guardrail-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.guardrail-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--state-success);
    flex-shrink: 0;
}

/* ════════════════════════════════════════════════════════════
   Shared list / table primitives — Generated admin pages
   (eh-toolbar, eh-search, ev-table, admin-grid, pager, modal)
   ════════════════════════════════════════════════════════════ */

/* ── Toolbar above tables ──────────────────────────────────── */
.eh-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.eh-search {
    flex: 1;
    min-width: 14rem;
    max-width: 24rem;
}

/* ── Generic data table (ev-table / admin-grid) ────────────── */

/* ÖLÇÜLDÜ 2026-09-15: `.table-wrapper` YİRMİ ayrı sayfa CSS'inde tek tek
   tanımlıydı ve yirmisi de aynı tek satırı yazıyordu (`overflow-x: auto`;
   iki "varyant" yalnız boşluk farkıydı). Sayfa başına kopyalanan bir kural
   standart değildir — ilk sürükleme onu sessizce böler. Kanonik tanım burada. */
.table-wrapper {
    overflow-x: auto;
}

.ev-table-wrap {
    overflow-x: auto;
    background: var(--surface-container);
}

/* KANONİK .data-table'a HİZALI. ÖLÇÜLDÜ 2026-09-03: 30 tablo-taşıyan sayfada
   9 farklı görünüm vardı; .ev-table/.admin-grid 8 sayfada ayrı bir aile olarak
   yaşıyordu (10px font, 8px/12px dolgu) — .data-table'dan (2xs/12px-16px)
   farklı. İkisini aynı değerlere çekiyoruz, sınıf adları sayfalarda kalıyor. */
.ev-table,
.admin-grid {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-md);
    background: var(--surface-container-low);
}

.ev-table thead th,
.admin-grid thead th {
    text-align: left;
    padding: 12px 16px;
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--on-surface-variant);
    background: var(--surface-container-high);
    white-space: nowrap;
}

.ev-table tbody td,
.admin-grid tbody td {
    padding: var(--space-3) 16px;
    color: var(--on-surface);
    vertical-align: middle;
}

/* Zebra striping via tonal shift — no divider lines (Monolith) */
.ev-table tbody tr:nth-child(even) td,
.admin-grid tbody tr:nth-child(even) td {
    background: var(--surface-container-low);
}

.ev-table tbody tr:hover td,
.admin-grid tbody tr:hover td {
    background: var(--surface-container-high);
}

.ev-table td code,
.admin-grid td code {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    color: var(--primary);
}

.ev-cell-bold {
    font-weight: 600;
    color: var(--on-surface);
}

.ev-cell-muted {
    color: var(--on-surface-variant);
}

/* ── Pagination controls ───────────────────────────────────── */
.pager-controls {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    margin-top: 1rem;
}

/* ── Tertiary button ───────────────────────────────────────── */
.btn-tertiary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: transparent;
    color: var(--on-surface-variant);
    font-family: var(--font-headline);
    font-weight: 700;
    font-size: var(--font-size-sm);
    letter-spacing: 0;
    text-transform: uppercase;
    border: none;
    border-radius: var(--btn-radius);
    cursor: pointer;
    transition: all var(--transition-btn);
}

.btn-tertiary:hover {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.btn-tertiary:active {
    transform: translateY(1px) scale(0.98);
}

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

/* ── Plain modal (non-VModal pages) ────────────────────────── */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(var(--overlay-scrim-rgb), 0.5);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    display: grid;
    place-items: center;
    padding: 1rem;
    animation: fadeIn 150ms ease;
}

.modal-content {
    background: var(--surface-container);
    border-radius: var(--panel-radius, var(--card-radius));
    box-shadow: var(--shadow-xl);
    max-width: 560px;
    width: 100%;
    max-height: 85vh;
    overflow-y: auto;
    padding: 1.5rem;
    animation: scale-in 150ms ease;
}

.modal-content > h3 {
    margin: 0 0 0.75rem;
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--on-surface);
}

.modal-content > p {
    margin: 0 0 1rem;
    font-size: var(--font-size-base);
    color: var(--on-surface-variant);
    line-height: 1.5;
}

/* ════════════════════════════════════════════════════════════
   RAG shared primitives — used across RagManagementPage panels
   ════════════════════════════════════════════════════════════ */

.rag-section {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    min-width: 0;
}

.rag-card {
    background: var(--surface-container);
    border-radius: var(--panel-radius);
    padding: var(--space-5);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--outline-variant) 50%, transparent);
}

.rag-card-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: 1rem;
}

.rag-card-head h3 {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--on-surface);
    letter-spacing: -0.01em;
}

.rag-card-head .card-icon {
    font-size: var(--icon-sm);
    color: var(--primary);
    flex-shrink: 0;
}

.rag-muted {
    color: var(--on-surface-variant);
    font-size: var(--font-size-base);
}

.rag-muted-sm {
    color: var(--on-surface-variant);
    font-size: var(--font-size-sm);
}

.rag-icon-btn {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: var(--btn-radius);
    border: none;
    background: transparent;
    color: var(--on-surface-variant);
    cursor: pointer;
    transition: background var(--transition-btn), color var(--transition-btn);
}

.rag-icon-btn:hover {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.rag-icon-btn.sm {
    width: 28px;
    height: 28px;
}

.rag-icon-btn.sm .material-symbols-outlined {
    font-size: 16px;
}

.rag-icon-btn.danger:hover {
    background: color-mix(in srgb, var(--error) 15%, transparent);
    color: var(--error);
}

/* =============================================================
   Sidebar navigation — group headers + nav items.
   GLOBAL (not scoped): these classes are rendered by BOTH
   Sidebar.razor and SidebarNavGroup.razor, so the rules must not
   carry a single component's scoped-CSS attribute.
   ============================================================= */

.sidebar-nav-group {
    margin-bottom: var(--space-1);
}

/* Group Header — an editorial eyebrow label. Crisper tracking + a brighter
   resting tone so it reads as a deliberate section marker, not muted noise. */
.sidebar-group-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    padding: 0 var(--space-3);
    background: transparent;
    border: none;
    border-radius: var(--btn-radius);
    color: color-mix(in srgb, var(--sidebar-on-surface) 62%, var(--sidebar-surface));
    cursor: pointer;
    transition: background var(--transition-btn), color var(--transition-btn);
    min-height: 38px;
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-align: left;
}

.sidebar-group-header:hover {
    background: color-mix(in srgb, var(--sidebar-on-surface) 6%, var(--sidebar-surface-container));
    color: var(--sidebar-on-surface);
}

.sidebar-group-header:active {
    background: color-mix(in srgb, var(--sidebar-on-surface) 10%, var(--sidebar-surface-container));
}

.sidebar-group-header:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

.sidebar-nav-group.expanded > .sidebar-group-header {
    color: var(--sidebar-primary);
}

.sidebar-group-icon {
    font-size: 20px;
    flex-shrink: 0;
    color: color-mix(in srgb, var(--sidebar-on-surface) 60%, var(--sidebar-surface));
    transition: color var(--transition-btn);
}

.sidebar-group-header:hover .sidebar-group-icon {
    color: var(--sidebar-on-surface);
}

.sidebar-nav-group.expanded > .sidebar-group-header .sidebar-group-icon {
    color: var(--sidebar-primary);
}

.sidebar-group-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Item-count chip on the group header — a quiet tabular badge. */
.sidebar-group-count {
    flex-shrink: 0;
    min-width: 1.25rem;
    text-align: center;
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    color: color-mix(in srgb, var(--sidebar-on-surface) 56%, var(--sidebar-surface));
    background: color-mix(in srgb, var(--sidebar-on-surface) 7%, var(--sidebar-surface));
    transition: color var(--transition-btn), background var(--transition-btn);
}

.sidebar-nav-group.expanded > .sidebar-group-header .sidebar-group-count {
    color: var(--sidebar-primary);
    background: color-mix(in srgb, var(--sidebar-primary) 14%, var(--sidebar-surface));
}

/* Chevron — Rotation Animation */
.sidebar-group-chevron {
    font-size: 18px;
    flex-shrink: 0;
    transition: transform var(--duration-normal) var(--ease-spring);
    border-radius: var(--btn-radius);
    opacity: 0.45;
}

.sidebar-group-header:hover .sidebar-group-chevron {
    opacity: 0.7;
}

.sidebar-nav-group.expanded > .sidebar-group-header .sidebar-group-chevron {
    opacity: 0.85;
}

/* Group Items Container — Accordion. The guide rail is a soft brand-tinted
   gradient rather than a flat 1px line (No-Line rule), fading at top/bottom. */
.sidebar-group-items {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: var(--space-1) 0 var(--space-2) var(--space-3);
    margin: var(--space-1) 0 var(--space-1) var(--space-4);
    position: relative;
    animation: accordionExpand var(--duration-normal) var(--ease-smooth);
    overflow: hidden;
}

.sidebar-group-items::before {
    content: '';
    position: absolute;
    left: 0;
    top: var(--space-1);
    bottom: var(--space-2);
    width: 1px;
    background: linear-gradient(
        to bottom,
        transparent,
        color-mix(in srgb, var(--sidebar-primary) 28%, var(--ghost-border)) 15%,
        color-mix(in srgb, var(--sidebar-primary) 28%, var(--ghost-border)) 85%,
        transparent
    );
    pointer-events: none;
}

@keyframes accordionExpand {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Navigation Item — the workhorse row. Brighter resting label, a hair of
   negative tracking and a touch more height so the text feels crisp and
   intentional rather than thin and washed out. */
.sidebar-nav-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-3);
    border-radius: var(--btn-radius);
    color: color-mix(in srgb, var(--sidebar-on-surface) 80%, var(--sidebar-surface));
    text-decoration: none;
    transition: background var(--transition-btn), color var(--transition-btn);
    min-height: 40px;
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    font-weight: 500;
    letter-spacing: -0.005em;
    position: relative;
    overflow: hidden;
}

/* Accent Bar */
.sidebar-nav-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 2px;
    height: 0;
    background: var(--sidebar-primary);
    transition: height var(--duration-normal) var(--ease-smooth);
}

.sidebar-nav-item:hover {
    background: color-mix(in srgb, var(--sidebar-on-surface) 7%, var(--sidebar-surface-container));
    color: var(--sidebar-on-surface);
}

.sidebar-nav-item:hover::before {
    height: 45%;
}

.sidebar-nav-item:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

/* Active State — Tonal Background + Accent. A restrained left-weighted tint
   (stronger at the accent bar, fading across the row) reads as "selected"
   without the flat highlighter look of a uniform fill. Brighter teal text and
   a faint icon glow make the current route unmistakable without shouting. */
.sidebar-nav-item.active {
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--sidebar-primary) 20%, var(--sidebar-surface-container)),
        color-mix(in srgb, var(--sidebar-primary) 9%, var(--sidebar-surface-container)) 70%,
        transparent
    );
    color: color-mix(in srgb, var(--sidebar-primary) 90%, var(--sidebar-on-surface));
    font-weight: 600;
    letter-spacing: 0;
}

.sidebar-nav-item.active::before {
    height: 100%;
    width: 3px;
    /* Teal→gold brand spine on the active row — the signature accent that ties
       the rail to splash/login/today. */
    background: linear-gradient(
        to bottom,
        var(--sidebar-primary),
        var(--brand-gold)
    );
    box-shadow: 0 0 10px -1px color-mix(in srgb, var(--sidebar-primary) 70%, transparent);
}

.sidebar-nav-item.active .sidebar-item-icon {
    color: var(--sidebar-primary);
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--sidebar-primary) 45%, transparent));
}

.sidebar-item-icon {
    font-size: var(--icon-md);
    flex-shrink: 0;
    color: color-mix(in srgb, var(--sidebar-on-surface) 56%, var(--sidebar-surface));
    transition: color var(--transition-btn);
}

.sidebar-nav-item:hover .sidebar-item-icon {
    color: var(--sidebar-on-surface);
}

.sidebar-item-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* Crisper glyph edges for light text on the dark rail. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Badge */
.sidebar-item-badge {
    font-size: var(--font-size-xs);
    font-weight: 700;
    padding: 0.1rem var(--space-2);
    border-radius: var(--btn-radius);
    background: var(--error);
    color: var(--on-error, var(--on-primary));
    line-height: 1.4;
    font-family: var(--font-label);
    letter-spacing: 0.03em;
    flex-shrink: 0;
    animation: badgeIn var(--duration-fast) var(--ease-spring);
}

@keyframes badgeIn {
    from { transform: scale(0); }
    to { transform: scale(1); }
}

/* Section — a labelled cluster of nav items */
.sidebar-section {
    display: flex;
    flex-direction: column;
}

.sidebar-section + .sidebar-section {
    margin-top: var(--space-2);
}

.sidebar-section-label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-1);
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--sidebar-on-surface) 50%, var(--sidebar-surface));
    white-space: nowrap;
}

/* Trailing rule after the label text — a fading tonal divider (No-Line rule:
   a gradient that dissolves to nothing, not a hard 1px hairline). */
.sidebar-section-label::after {
    content: '';
    flex: 1;
    height: 1px;
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--sidebar-on-surface) 16%, transparent),
        transparent
    );
}

.sidebar-section-items {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* Labelled sections indent their items slightly to read as children */
.sidebar-section:not(.sidebar-section--unlabeled) .sidebar-nav-item {
    padding-left: var(--space-4);
}

.sidebar-section:not(.sidebar-section--unlabeled) .sidebar-nav-item::before {
    left: var(--space-2);
}

/* Favorite button */
.sidebar-fav-btn {
    margin-left: auto;
    border: none;
    background: transparent;
    color: color-mix(in srgb, var(--sidebar-on-surface) 45%, var(--sidebar-surface));
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    opacity: 0;
    transition: color var(--transition-btn), transform var(--transition-btn),
                opacity var(--transition-btn);
}

.sidebar-nav-item:hover .sidebar-fav-btn,
.sidebar-nav-item:focus-within .sidebar-fav-btn,
.sidebar-fav-btn:focus-visible {
    opacity: 1;
}

.sidebar-fav-btn.is-fav {
    opacity: 1;
    /* Gold "favorite" star — brand-gold stays gold in Light too (--secondary is charcoal there). */
    color: var(--brand-gold-text);
}

.sidebar-fav-btn:hover {
    color: var(--brand-gold-text);
    transform: scale(1.15);
}

.sidebar-fav-btn:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

.sidebar-fav-btn .material-symbols-outlined {
    font-size: var(--icon-sm);
}

/* Collapsed rail — center the icon, hide labels */
.sidebar-nav-group.rail-collapsed > .sidebar-group-header {
    justify-content: center;
    padding: 0;
    gap: 0;
}

@media (prefers-reduced-motion: reduce) {
    .sidebar-group-items,
    .sidebar-nav-item::before,
    .sidebar-group-chevron,
    .sidebar-item-badge,
    .sidebar-fav-btn {
        animation: none;
        transition: none;
    }
}

/* ════════════════════════════════════════════════════════════
   Form field + action primitives — shared across feature pages
   ════════════════════════════════════════════════════════════ */

/* `.form-label` KANONİĞE BAĞLANDI. ÖLÇÜLDÜ 2026-09-04: depoda 165 kullanımı
   var ama HİÇBİR kanonik tanımı YOKTU — Bootstrap'tan kalma bir ad ve Bootstrap
   yüklü değil. Sonuç: etiketler satır içi kalıyor ve alanla yan yana,
   HİZASIZ görünüyordu (/admin/rules/create ekran görüntüsüyle doğrulandı:
   "Rule Name" solda, girdi sağda; "Description" alanın ortasında).
   display:block eklendi — etiket kendi satırını alır, alan altına iner. */
/* `.field-label` KENDİ TABANINI ALDI. ÖLÇÜLDÜ 2026-09-16: bu ad depoda
   224 kez kullanılıyor ama kanonik bir tanımı YOKTU — aşağıdaki ipucu-ikonu
   kuralının seçici listesine virgülle bağlıydı ve araya giren açıklama
   yorumu bunu gizliyordu. Tarayıcıda ölçülen sonuç: `.field-label` bir
   ETİKET değil bir İKON gibi stilleniyordu — `display:flex`,
   `cursor: help`, `margin-inline-start: 4px`, ve tipografi hiç
   uygulanmadığı için 16px/w400/none (kardeşi `.form-label` 12.8px/w600/
   uppercase).

   Anatomi `.form-label` ile AYNI: ikisi de aynı işi yapan iki addır
   (`.form-label` 163 kullanım, `.field-label` 224). Ayrı kural yazmak
   yerine ortak kurala alınmadı, çünkü `.form-label`'ın sayfa ezmeleri
   (23 canlı tanım, 0.8/0.85rem) yalnız o adı hedefliyor — ikisini tek
   kurala bağlamak `.field-label`'ı da o ezmelere açardı. */
.field-label {
    /* ref-34 (2026-09-25): etiket cumle duzeninde, 14px/500, govde renginde. */
    display: block;
    text-transform: none;
    margin-bottom: var(--space-1);
    font-family: var(--font-label);
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--on-surface);
}

/* Etiket ici yardim ikonu (VInfoLabel Hint). Etiket `display:block` oldugu
   icin ikon ancak inline-flex ile satira oturur; ayri bir kap eklemek
   etiketin tiklama alanini bolerdi. */
.form-label__hint {
    display: inline-flex;
    align-items: center;
    margin-inline-start: var(--space-1);
    color: var(--on-surface-variant);
    cursor: help;
    vertical-align: middle;
}
.form-label__hint .material-symbols-outlined { font-size: var(--icon-sm); }
.form-label__hint:focus-visible {
    outline: var(--state-focus-ring);
    outline-offset: var(--state-focus-offset);
    border-radius: 50%;
}

.form-label {
    /* ref-34 (2026-09-25): etiket cumle duzeninde, 14px/500, govde renginde. */
    display: block;
    text-transform: none;
    margin-bottom: var(--space-1);
    font-family: var(--font-label);
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--on-surface);
}

/* .field-input taban kuralın KOPYASIYDI, yalnız dolgu ve zemin farklıydı —
   ve taban kuraldan SONRA geldiği için onu eziyordu. Ortak bildirimler
   kaldırıldı; geriye yalnız bu varyantın gerçek farkı kalır.
   ÖLÇÜLDÜ 2026-09-03: p=8/12 bg=#252f3f, taban ise p=10/14 bg=#2f3a4a. */
.field-input {
    width: 100%;
    box-sizing: border-box;
}

.field-input:focus {
    outline: none;
    box-shadow: inset 0 0 0 1px var(--primary);
}

.field-input.field-sm {
    padding: 0.375rem 0.5rem;
    font-size: var(--font-size-md);
}

.btn-primary-action {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    background: var(--gradient-accent);
    color: var(--on-primary);
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-headline);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-transform: uppercase;
    cursor: pointer;
    transition: opacity var(--transition-btn);
}

.btn-primary-action:hover:not(:disabled) {
    opacity: 0.9;
}

.btn-primary-action:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.page-inner {
    max-width: 1200px;
    margin-inline: 0;
}

/* Small button variants */
.btn-primary-sm,
.btn-secondary-sm {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    /* Alanlarla aynı dokunma hedefi — yalnız padding vardı, 44px girdinin
       yanında kısa kardeş kayması üretiyordu (~140 sayfa). */
    min-height: var(--touch-target-min, 44px);
    padding: 0 0.625rem;
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-headline);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--transition-btn), opacity var(--transition-btn);
    box-sizing: border-box;
}

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

.btn-primary-sm:hover {
    opacity: 0.9;
}

.btn-secondary-sm {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.btn-secondary-sm:hover {
    background: var(--surface-container-highest);
}

/* ════════════════════════════════════════════════════════════
   Config page topbar — shared across Config/* pages
   ════════════════════════════════════════════════════════════ */

.config-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.75rem 1.5rem;
    background: var(--surface-container-low);
    box-shadow: 0 0 0 1px var(--ghost-border);
}

.topbar-left,
.topbar-right {
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.topbar-brand {
    font-family: var(--font-headline);
    font-size: 0.9375rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--primary);
    text-decoration: none;
    white-space: nowrap;
}

.topbar-nav {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-wrap: wrap;
}

.topbar-nav-item {
    padding: 0.375rem 0.75rem;
    background: transparent;
    border: none;
    color: var(--on-surface-variant);
    font-family: var(--font-body);
    font-size: var(--font-size-md);
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    border-radius: var(--btn-radius);
    transition: background var(--transition-btn), color var(--transition-btn);
}

.topbar-nav-item:hover {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.topbar-icons {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.topbar-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    font-size: var(--icon-sm);
    color: var(--on-surface-variant);
    cursor: pointer;
    border-radius: var(--btn-radius);
    transition: background var(--transition-btn), color var(--transition-btn);
}

.topbar-icon:hover {
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.topbar-deploy-btn {
    white-space: nowrap;
}

/* Filter badge counter — shared utility (paired with body-sm) */
.filter-active-count {
    display: inline-block;
}

/* ════════════════════════════════════════════════════════════
   Shared utility / layout primitives — used across feature pages
   ════════════════════════════════════════════════════════════ */

/* Wizard step navigation row (prev/next) */
.wizard-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

/* Interactive affordance — clickable table headers, rows, etc. */
.clickable {
    cursor: pointer;
    user-select: none;
}

/* Monospace text helper (alias of font-mono) */
.mono {
    font-family: var(--font-mono);
}

/* Inline input variant — sits within a sentence/row */
/* .input-inline SATIR İÇİ bir varyanttır: tabloda/satırda gömülü kullanılır,
   bu yüzden DAHA DAR dolgu ve 44px yerine içeriğe uyan yükseklik ister.
   Bu FARK KASITLIDIR; ortak bildirimler (zemin, kenar, yarıçap, renk) taban
   kuraldan gelir, burada yinelenmez. */
.input-inline {
    min-height: 0;
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-size-md);
}

.input-inline:focus {
    outline: none;
    box-shadow: inset 0 0 0 1px var(--primary);
}

/* KPI tile — compact metric card, often a button */
.kpi-tile {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    background: var(--surface-container);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--outline-variant) 45%, transparent);
    padding: 0.875rem 1rem;
    border: none;
    cursor: pointer;
    font-family: inherit;
    transition: background var(--transition-btn);
}

.kpi-tile:hover {
    background: var(--surface-container-high);
}

/* Dashboard section block */
.dashboard-section {
    background: var(--surface-container);
    border-radius: var(--panel-radius);
    padding: 1.25rem;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--outline-variant) 45%, transparent);
}

.dashboard-section + .dashboard-section {
    margin-top: 1.25rem;
}

/* Custom thin scrollbar hook */
.custom-scrollbar {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--on-surface) 18%, transparent) transparent;
}

.custom-scrollbar::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
    background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--on-surface) 16%, transparent);
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--on-surface) 30%, transparent);
}

/* Skeleton button placeholder (pairs with .skeleton) */
.skeleton-button {
    height: 36px;
    width: 96px;
    border-radius: var(--btn-radius);
}

.skeleton-button.skeleton-button-small {
    width: 64px;
    height: 30px;
}

.skeleton-button.skeleton-button-secondary {
    width: 80px;
}

/* ── Blazor circuit reconnect (branded) ───────────────────────────────────── */
#components-reconnect-modal {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-error) - 1);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-6, 1.5rem);
    background: color-mix(in srgb, var(--surface) 72%, transparent);
    backdrop-filter: blur(var(--blur-sm));
}

#components-reconnect-modal.components-reconnect-hide {
    display: none;
}

.veraius-reconnect-panel {
    width: min(420px, 100%);
    padding: var(--spacing-6, 1.5rem);
    background: var(--glass-bg, rgba(var(--surface-container-high-rgb), 0.8));
    border: 1px solid var(--ghost-border, rgba(var(--outline-variant-rgb), 0.15));
    box-shadow: var(--shadow-xl);
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4, 1rem);
}

.veraius-reconnect-panel .label-sm {
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--primary);
}

.veraius-reconnect-trace {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
}

.veraius-reconnect-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-3, 0.75rem);
}

/* Jo toggles components-reconnect-{show,failed,rejected}; hide terminal copy until then. */
#components-reconnect-modal .components-reconnect-failed-message,
#components-reconnect-modal .components-reconnect-rejected-message {
    display: none;
    color: var(--tertiary);
}

#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-message,
#components-reconnect-modal.components-reconnect-resume-failed .components-reconnect-failed-message {
    display: block;
}

#components-reconnect-modal.components-reconnect-rejected .components-reconnect-rejected-message {
    display: block;
}

/* Reload is for terminal states; keep primary retry visible while still attempting. */
#components-reconnect-reload {
    display: none;
    align-items: center;
    justify-content: center;
    min-height: 2.5rem;
    padding: 0 var(--spacing-4, 1rem);
    border: 0;
    border-radius: 0;
    background: var(--surface-container-highest);
    color: var(--on-surface);
    font-family: inherit;
    font-size: var(--font-size-base);
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background-color var(--transition-btn), color var(--transition-btn);
}

#components-reconnect-reload:hover {
    background: var(--surface-bright, var(--surface-container-high));
}

#components-reconnect-modal.components-reconnect-failed #components-reconnect-reload,
#components-reconnect-modal.components-reconnect-rejected #components-reconnect-reload,
#components-reconnect-modal.components-reconnect-resume-failed #components-reconnect-reload {
    display: inline-flex;
}

/* ── VForm ─────────────────────────────────────────────────────────────────── */
.vform__summary.validation-summary {
    margin-bottom: var(--spacing-4, 1rem);
    color: var(--error);
    font-size: var(--font-size-base);
}

.vform__summary.validation-summary ul {
    margin: 0;
    padding-left: 1.25rem;
}

/* ============================================================
   Nexus toast (chat-hud channel) — owned globally here instead of the
   NexusToastProvider scoped sheet, because that scoped CSS ships in the
   lazy-loaded dept bundle (core.css) and was not reliably applied when the
   toast fired, leaving voice/error toasts as unstyled text at the bottom of
   the page. Plain global classes guarantee the toast is always styled.
   ============================================================ */
.toast-stack {
    position: fixed;
    top: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-notify);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    pointer-events: none;
}

.nexus-toast {
    pointer-events: auto;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    box-shadow: 0 0 0 1px var(--state-active-border), var(--shadow-lg);
    border-radius: var(--card-radius);
    padding: 0.75rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    animation: toastPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    overflow: hidden;
    position: relative;
}

.nexus-toast .toast-icon { color: var(--primary); font-size: var(--icon-sm); }
.nexus-toast .toast-message {
    font-size: var(--font-size-md);
    font-weight: 700;
    color: var(--on-surface);
    letter-spacing: -0.01em;
    white-space: nowrap;
}
.nexus-toast .toast-progress-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 2px;
    background: var(--primary);
    animation: toastProgress linear forwards;
    width: 100%;
    animation-duration: var(--toast-duration, 3000ms);
}

@keyframes toastPop {
    from { opacity: 0; transform: translateY(-20px) scale(0.9); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes toastProgress {
    from { width: 100%; }
    to { width: 0%; }
}

/* ============================================================
   Nexus HUD notification (chat "Message sent / Waiting for a reply")
   — owned globally here instead of the NexusHudNotification scoped sheet,
   which ships in the lazy-loaded dept bundle and was not reliably applied
   when the HUD alert fired, leaving it as unstyled text at the page bottom.
   Same fix as the chat-hud toast. Plain global classes (the markup is one
   .hud-container wrapping .hud-alert items).
   ============================================================ */
.hud-container {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    z-index: 10000;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    pointer-events: none;
}
.hud-container .hud-alert {
    pointer-events: auto;
    width: 320px;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--blur-sm));
    -webkit-backdrop-filter: blur(var(--blur-sm));
    box-shadow: inset 0 0 0 1px var(--ghost-border), var(--shadow-lg);
    border-radius: var(--card-radius);
    display: flex;
    flex-direction: column;
    position: relative;
    overflow: hidden;
    animation: hudSlideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.hud-container .hud-edge {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, var(--primary) 0%, var(--primary-container) 100%);
}
.hud-container .hud-body { display: flex; align-items: flex-start; gap: 1rem; padding: 1.25rem; }
.hud-container .hud-icon { color: var(--primary); font-size: 24px; margin-top: 0.125rem; }
.hud-container .hud-text { display: flex; flex-direction: column; gap: 0.25rem; }
.hud-container .hud-title {
    font-family: var(--font-label);
    font-size: 10px;
    font-weight: 800;
    color: var(--primary);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}
.hud-container .hud-msg { font-size: var(--font-size-base); color: var(--on-surface-variant); line-height: 1.4; font-weight: 500; }
.hud-container .hud-progress-track { height: 2px; width: 100%; background: var(--primary-glow); }
.hud-container .hud-progress-fill { height: 100%; background: var(--primary); transition: width var(--transition-toast); box-shadow: 0 0 10px var(--primary); }
.hud-container .hud-alert.warning .hud-edge,
.hud-container .hud-alert.warning .hud-icon,
.hud-container .hud-alert.warning .hud-title { color: var(--state-warning-text-on-fill); }
.hud-container .hud-alert.terminal .hud-body { background: var(--primary-glow); }
.hud-container .hud-alert.terminal .hud-msg { font-family: var(--font-body); font-size: 11px; color: var(--primary); }

/* ── Theme-token rounding for legacy chat/shell scoped CSS ───────────────────
   Per-component scoped CSS still hardcodes border-radius: 0 from the old
   brutalist pass. Re-apply per-theme radii from tools/tokens/*.json here.
   [data-theme] .x (0,2,0) outranks scoped .x[b-id] (0,1,1). Cosmetic only. */
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-user-bubble,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-user-message-bubble,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-assistant-body,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-ask-card,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .transparency-card,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .thinking-panel,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .code-sandbox-wrapper,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-pinned-context,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-user-edit-input {
    border-radius: var(--card-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-text pre,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-text .code-block-container,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-text .mermaid-container {
    border-radius: var(--card-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-text code,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .msg-text .citation-chip,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .source-ref-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .step-status,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .step-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .step-score,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-source-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-confidence-strip,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-answer-sources__label,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-ask-card__pip,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .action-btn,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .landing-action-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .landing-result-tag,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .skeleton-line {
    border-radius: var(--btn-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .command-input-wrap,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .model-dropdown,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .mission-briefing-hero {
    border-radius: var(--card-radius) !important;
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-dock-mode-group,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-seg-btn,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .va-mode-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .model-dropdown-item,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .hud-badge,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .kbd-item kbd {
    border-radius: var(--btn-radius) !important;
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .cmd-palette,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .cmd-result-item {
    border-radius: var(--card-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .cmd-result-item.selected,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .cmd-esc {
    border-radius: var(--btn-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .topbar-right,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .user-menu-panel,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .tenant-switcher-panel,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .env-badge {
    border-radius: var(--card-radius);
}
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .user-menu-item,
:is([data-theme="dark"], [data-theme="light"], [data-theme="mixed"]) .tenant-switcher-item {
    border-radius: var(--btn-radius);
}

@keyframes hudSlideIn {
    from { opacity: 0; transform: translateX(50px) scale(0.9); }
    to { opacity: 1; transform: translateX(0) scale(1); }
}

/* ============================================================================
   Platform rozetleri — PWA yukleme banner'i (PlatformBadges.razor)
   ----------------------------------------------------------------------------
   NEDEN SCOPED (.razor.css) DEGIL: Shared RCL'in scoped stilleri build
   pipeline'i tarafindan uretilen depts/core.css paketine giriyor; yeni eklenen
   bir .razor.css o paket yeniden uretilene kadar SESSIZCE yuklenmiyor (olculdu,
   2026-07-29: PwaInstallBanner.razor.css de ayni durumda). Bu dosya App.razor'dan
   KOSULSUZ linklendigi icin stil her zaman uygulanir.

   Tasarim sistemi: 1px kenarlik YOK (tonal gecis), Manrope, 50ms gecis.
   ========================================================================== */
.va-platform-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.va-platform-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    padding: 0.4375rem 0.6875rem;
    /* Tonal derinlik: kenarlik yerine bir kademe acik yuzey. */
    background: var(--surface-container-high);
    color: var(--on-surface-variant);
    border-radius: var(--btn-radius);
    transition: background var(--transition-btn), color var(--transition-btn);
}

/* Kullanicinin BULUNDUGU platform vurgulanir — "senin cihazin destekleniyor"
   mesaji goz taramasinda hemen okunsun. */
.va-platform-badge--active {
    background: color-mix(in srgb, var(--primary) 18%, var(--surface-container-high));
    color: var(--on-surface);
}

.va-platform-badge__icon {
    display: inline-flex;
    line-height: 0;
    opacity: 0.85;
}

.va-platform-badge--active .va-platform-badge__icon {
    opacity: 1;
    color: var(--primary);
}

.va-platform-badge__label {
    font-size: var(--font-size-sm);
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .va-platform-badge { transition: none; }
}

/* Banner icindeki rozet bloğunun yerlesimi (PwaInstallBanner.razor).
   Ayni gerekce: scoped .razor.css bu host'ta yuklenmiyor. */
.pwa-install-platforms {
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
}

@media (max-width: 768px) {
    .pwa-install-platforms { justify-content: flex-start; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   .va-kv — etiket/değer çiftleri için tanım listesi.

   Bu içerik <table> ile yazılmıştı ama tablo DEĞİL: tek bir varlığın nitelikleri,
   iki boyutlu veri değil. Ekran okuyucu bunu "3 satır 2 sütunlu tablo" diye okuyordu.
   <dl> semantiği doğrudur ve audit:raw-tables guard'ının işaret ettiği şey de budur.
   Görsel çıktı iki sütunlu ızgara olarak korunur.
   ───────────────────────────────────────────────────────────────────────────── */
.va-kv {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.375rem 1rem;
    margin: 0.5rem 0;
    align-items: baseline;
}

.va-kv dt { margin: 0; }
.va-kv dd { margin: 0; text-align: right; }

/* ─────────────────────────────────────────────────────────────────────────────
   .va-grid — VGrid (AG Grid Community) kabı.

   AG Grid'in KENDİ tema CSS'i yüklenmiyor (.noStyle derlemesi): renkler, tipografi
   ve köşe yarıçapı js/veraius-grid.js içinde bu deponun token'larından üretiliyor.
   Buradaki kurallar yalnız kabın yerleşimi içindir — ızgaranın iç görünümü tokendan
   gelir, böylece tema anahtarı ızgarayı da çevirir.

   --grid-radius: veraius-grid.js bu değeri okur. Tanımlanmadığı temada '0'a düşer.
   ───────────────────────────────────────────────────────────────────────────── */
:root {
    --color-success: var(--state-success);
    --color-warning: var(--state-warning);
    --color-error:   var(--state-error);
    --color-info:    var(--state-info);
    --color-success-bg: var(--state-success-bg);
    --color-warning-bg: var(--state-warning-bg);
    --color-error-bg:   var(--state-error-bg);
    --color-info-bg:    var(--state-info-bg);
    --grid-radius: var(--card-radius, 0);
}

.va-grid {
    width: 100%;
    overflow: hidden;                 /* yuvarlak köşe ızgarayı kırpsın */
    border-radius: var(--grid-radius);
    background: var(--surface-container);
}

/* ── VGrid hücre renderer'ları ────────────────────────────────────────────
   Bu sınıflar JS'ten (veraius-grid.js) basılır, dolayısıyla scoped CSS
   (::deep) onlara ULAŞMAZ — paylaşılan katmanda olmak zorundalar. */

/* Bos izgara katmani — JS'ten basilir, paylasilan katmanda olmali. */
.va-grid__empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-6);
    text-align: center;
}
.va-grid__empty-icon { font-size: var(--icon-2xl); color: var(--on-surface-variant); opacity: 0.7; }
.va-grid__empty-text { margin: 0; font-size: var(--font-size-sm); color: var(--on-surface-variant); }

/* Baslik yanindaki sayac rozeti. OLCULDU 2026-09-13: .channels-count-badge
   markup'ta kullaniliyordu ama CSS'te tanimsizdi — sayi duz metin olarak
   basliga yapisiyordu. Rozet her sayfada ayni gorunmeli, o yuzden burada. */
.va-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 1.5rem;
    padding: 0 var(--space-2);
    border-radius: var(--chip-radius);
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.va-grid__badge {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem var(--space-2);
    border-radius: var(--chip-radius);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
}
.va-grid__badge--success { background: color-mix(in srgb, var(--brand-teal) 16%, transparent); color: var(--brand-teal-text); }
.va-grid__badge--warning { background: color-mix(in srgb, var(--brand-gold) 16%, transparent); color: var(--brand-gold-text); }
.va-grid__badge--danger  { background: color-mix(in srgb, var(--error) 16%, transparent); color: var(--error); }
.va-grid__badge--info    { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }

.va-grid__icontext { display: inline-flex; align-items: center; gap: var(--space-2); min-inline-size: 0; }
.va-grid__icon { font-size: var(--icon-sm); color: var(--on-surface-variant); flex: none; }

/* Marka logosu hucresi — SVG'de fill yok, currentColor miras alinir. */
.va-grid__brand { display: inline-flex; inline-size: var(--icon-sm); block-size: var(--icon-sm); flex: none; }
.va-grid__brand svg { inline-size: 100%; block-size: 100%; fill: currentColor; }

.va-grid__actions { display: inline-flex; align-items: center; gap: var(--space-1); }

/* Hedef boyutu 2.75rem (WCAG 2.2 AA); ızgara satırı daha kısa olabildiği
   için yükseklik %100'e sabitlenip genişlik korunur. */
.va-grid__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    border: none;
    border-radius: var(--btn-radius);
    background: transparent;
    color: var(--on-surface-variant);
    cursor: pointer;
    transition: background var(--transition-btn), color var(--transition-btn);
}
.va-grid__action:hover { background: var(--surface-container-highest); color: var(--on-surface); }
.va-grid__action:focus-visible { outline: var(--state-focus-ring); outline-offset: var(--state-focus-offset); }
.va-grid__action .material-symbols-outlined { font-size: var(--icon-sm); }

/* Yikicilik rengi HOVER'da tasinir: her satirda dolgulu kirmizi bir dugme
   gozu once silmeye cekerdi. */
.va-grid__action--danger:hover {
    background: color-mix(in srgb, var(--error) 14%, transparent);
    color: var(--error);
}

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

/* Dar ekranda ızgara kendi içinde yatay kayar — sayfa gövdesi ASLA kaymaz. */
@media (max-width: 768px) {
    .va-grid { overflow-x: auto; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   .cb-* — Kanal Bağlamaları ailesi (dead-letters, circuits, channel-events,
   inbound-dead-letters, zamanlayıcı formları).

   Bu sınıfların HİÇBİRİ tanımlı değildi — ÖLÇÜLDÜ 2026-08-26: dört sayfa da
   markup'ı doğru yazıyor ama stilsiz düz metin olarak render oluyordu (200 kayıt
   alt alta, kart yok, ayırıcı yok, düğmeler yığılmış). Kullanıcı için okunamaz
   bir ekrandı.

   Tasarım sistemi kuralları: opak 1px kenarlık yok (tonal katman + ghost border),
   yalnız Manrope, boş hücre em-dash, 50ms geçiş.
   ───────────────────────────────────────────────────────────────────────────── */

.cb-shell,
.cb-root,
.cb-container {
    max-width: var(--content-max-width, 2040px);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-4, 1rem);
}

/* ── Hero başlık ─────────────────────────────────────────────────────────── */
.cb-hero {
    background: var(--surface-container-low);
    border-radius: var(--card-radius);
    padding: 1.75rem 2rem;
}

.cb-hero-eyebrow {
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    margin-bottom: 0.5rem;
}

.cb-hero-title {
    font-family: var(--font-headline);
    font-size: clamp(1.75rem, 3vw, 2.25rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
    margin: 0 0 0.5rem;
    color: var(--on-surface);
}

.cb-hero-title strong { color: var(--primary); font-weight: 800; }

.cb-hero-sub {
    /* 65ch: uzun satır okumayı yorar — tarama ">95ch" bulgusu veriyordu. */
    max-width: 65ch;
    margin: 0;
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--on-surface-variant);
}

.cb-back { align-self: flex-start; }

/* ── Panel / bölüm ───────────────────────────────────────────────────────── */
.cb-panel,
.cb-section {
    background: var(--surface-container);
    border-radius: var(--card-radius);
    padding: var(--space-5) var(--space-5);
}

.cb-panel-title,
.cb-section-title {
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 1rem;
    color: var(--on-surface);
}

/* ── Liste + satır: 200 kayıt okunabilir olmalı ──────────────────────────── */
.cb-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.cb-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.875rem 1.125rem;
    background: var(--surface-container);
    border-radius: var(--card-radius);
    transition: background var(--transition-default, 150ms ease);
}

.cb-row:hover { background: var(--surface-container-high); }

.cb-row--off,
.cb-disabled { opacity: 0.55; }

.cb-row-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    flex: 1 1 22rem;
}

.cb-row-name {
    font-weight: 600;
    color: var(--on-surface);
    overflow-wrap: anywhere;
}

.cb-row-target,
.cb-details,
.cb-label,
.cb-time-label {
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
}

.cb-row-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
}

/* ── Rozetler ────────────────────────────────────────────────────────────── */
.cb-chip,
.cb-next-chip,
.cb-tz-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1875rem 0.5rem;
    border-radius: var(--btn-radius);
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.cb-chip--ok,
.cb-ready,
.cb-enabled { background: var(--state-success-bg); color: var(--state-success-text-on-fill, var(--state-success-text, var(--state-success))); }

.cb-chip--err,
.cb-error,
.cb-missing { background: var(--state-error-bg); color: var(--state-error-text-on-fill, var(--state-error-text, var(--state-error))); }

.cb-chip--cron { background: var(--state-info-bg); color: var(--state-info-text-on-fill); }

.cb-chip-code,
.cb-raw-input {
    font-family: var(--font-mono, ui-monospace, monospace);
    text-transform: none;
    letter-spacing: 0;
}

.cb-chips { display: flex; flex-wrap: wrap; gap: 0.375rem; }

/* ── Form ────────────────────────────────────────────────────────────────── */
.cb-form,
.cb-fields,
.cb-form-group {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.cb-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 1rem;
    align-items: end;
}

.cb-field,
.cb-raw-row,
.cb-time-row {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}

.cb-field--check {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    /* WCAG 2.5.8: 24px minimum dokunma alanı. */
    min-height: 24px;
}

.cb-field--check input { accent-color: var(--primary); width: 1rem; height: 1rem; }

.cb-field-label,
.cb-raw-label,
.cb-next-label {
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
}

.cb-input,
.cb-field-select,
.cb-time-select,
.cb-search {
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: var(--surface-container-highest);
    color: var(--on-surface);
    border: none;
    border-radius: var(--input-radius, var(--btn-radius));
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    transition: box-shadow var(--transition-btn, 50ms ease);
}

.cb-input:focus-visible,
.cb-field-select:focus-visible,
.cb-time-select:focus-visible,
.cb-search:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.cb-actions,
.cb-cap-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.cb-grow { flex: 1 1 auto; min-width: 0; }

/* ── Boş durum ───────────────────────────────────────────────────────────── */
.cb-empty {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--on-surface-variant);
    font-size: 0.9375rem;
}

/* ── Yetenek kartları ────────────────────────────────────────────────────── */
.cb-cap-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: 1rem;
    align-items: start;
}

.cb-cap-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: var(--space-5);
    background: var(--surface-container);
    border-radius: var(--card-radius);
}

.cb-cap-header { display: flex; align-items: center; gap: 0.75rem; }
.cb-cap-icon { font-size: var(--font-size-3xl); color: var(--primary); flex-shrink: 0; }
.cb-cap-name { font-weight: 700; color: var(--on-surface); }
.cb-cap-desc { font-size: var(--font-size-md); line-height: 1.55; color: var(--on-surface-variant); }
.cb-cap-meta,
.cb-cap-status { font-size: var(--font-size-sm); color: var(--on-surface-variant); }

/* ── Zamanlayıcı (gün/ay seçici) ─────────────────────────────────────────── */
.cb-day-picker,
.cb-month-day-picker,
.cb-presets { display: flex; flex-wrap: wrap; gap: 0.375rem; }

.cb-day-btn,
.cb-mday-btn,
.cb-preset,
.cb-add-btn {
    padding: 0.375rem 0.75rem;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-label);
    font-size: var(--font-size-sm);
    font-weight: 700;
    cursor: pointer;
    /* WCAG 2.5.8 */
    min-height: 24px;
    transition: background var(--transition-btn, 50ms ease), color var(--transition-btn, 50ms ease);
}

.cb-day-btn:hover,
.cb-mday-btn:hover,
.cb-preset:hover,
.cb-add-btn:hover { background: var(--surface-bright); color: var(--on-surface); }

.cb-day-active,
.cb-preset-active { background: var(--primary); color: var(--on-primary); }

/* ── Önizleme / sonraki koşular ──────────────────────────────────────────── */
.cb-preview,
.cb-event-preview,
.cb-next-runs,
.cb-qlist {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem;
    background: var(--surface-container-low);
    border-radius: var(--card-radius);
    /* TASMA. ÖLÇÜLDÜ 2026-09-14 /agents/channels/events: 100 ogenin 9'u
       kabindan tasiyordu (594px ve 629px icerik, 525px kap).

       Sebep SINIF CAKISMASI: ayni eleman hem `.cb-row-actions` hem
       `.cb-event-preview` tasiyor. Ilki `flex: 0 0 auto` diyor — yani
       "ASLA KUCULME"; ikincisi onu bir sutun blogu yapiyor. Sonucta kutu
       icerigi kadar buyuyor ve kabin disina sarkiyor.

       `min-width: 0` flex ogesinin varsayilan `min-width: auto` kilidini
       acar (icerikten kucuk olamama kurali); `max-inline-size` de kabi
       ustun kilar. Ikisi birlikte tasmayi kesin olarak bitirir. */
    min-inline-size: 0;
    max-inline-size: 100%;
    overflow-wrap: anywhere;
}

.cb-preview-summary { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; }
.cb-preview-icon { color: var(--primary); flex-shrink: 0; }
.cb-preview-text { font-size: var(--font-size-md); color: var(--on-surface-variant); line-height: 1.55; }
.cb-next-day { font-weight: 600; color: var(--on-surface); }
.cb-next-time { font-size: var(--font-size-md); color: var(--on-surface-variant); }

.cb-error-icon { color: var(--error); flex-shrink: 0; }
.cb-name-err { color: var(--error); font-size: var(--font-size-sm); }
.cb-needs-data { color: var(--secondary); font-size: var(--font-size-sm); }
.cb-maplink { color: var(--primary); text-decoration: none; }
.cb-maplink:hover { text-decoration: underline; }

@media (max-width: 768px) {
    .cb-hero { padding: 1.25rem 1rem; }
    .cb-panel, .cb-section { padding: var(--space-4); }
    .cb-row { flex-direction: column; align-items: stretch; }
    .cb-row-actions { justify-content: flex-start; }
}


/* ── DENETİM LİSTESİ (.va-audit-*) ─────────────────────────────────────────
   Bu 21 sınıf AuditLogPage.razor.css içinde SCOPED olarak duruyordu. Blazor'da
   scoped CSS bileşenler arasında GEÇMEZ: kurallar [b-xxxxx] attribute'u taşır ve
   yalnız o bileşenin markup'ına uygulanır.
   SagaMonitoringPage (/admin/sagas) aynı 20 sınıfı kullanıyor ama kendi scoped
   dosyası yok — dolayısıyla HİÇBİR kural eşleşmiyordu ve sayfa çıplak metin
   yığını olarak render oluyordu. ÖLÇÜLDÜ 2026-08-27, /admin/sagas:
       table=0  tbody tr=0  .status-badge=0
       .va-audit-row kuralları yalnız [b-dok0htjrk1] ve [b-eg52ka59n0] altında
   İki sayfanın 20 ortak sınıfı bunun paylaşılan bir kalıp olduğunu gösteriyor;
   doğru yer global katman. */
.va-audit-screen {
    display: flex;
    flex-direction: column;
    gap: var(--space-6, 1.5rem);
    padding: var(--space-6, 1.5rem);
    max-width: var(--content-max-width, 2040px);
    margin: 0 auto;
    width: 100%;
}

.va-audit-header {
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
}

.va-audit-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
}

.va-audit-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: var(--space-3, 0.75rem);
    padding: var(--space-4, 1rem);
    background: var(--surface-container);
    border-radius: var(--card-radius);
}

.va-audit-row-icon {
    color: var(--primary);
    opacity: 0.85;
}

.va-audit-row-body {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

.va-audit-row-title {
    color: var(--on-surface);
    font-size: 0.9375rem;
    font-weight: 500;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2, 0.5rem);
}

.va-audit-action {
    font-weight: 700;
    color: var(--primary);
    text-transform: uppercase;
    font-size: var(--font-size-sm);
    letter-spacing: 0.06em;
    font-family: var(--font-label);
}

.va-audit-entity {
    color: var(--on-surface);
}

.va-audit-entity-id {
    color: var(--on-surface-variant);
    font-family: var(--font-mono, monospace);
    font-size: var(--font-size-sm);
}

.va-audit-sep {
    color: var(--on-surface-variant);
    opacity: 0.5;
}

.va-audit-row-meta {
    color: var(--on-surface-variant);
    font-size: var(--font-size-2xs);
    font-family: var(--font-label);
}

.va-audit-row-time {
    color: var(--on-surface-variant);
    font-size: var(--font-size-2xs);
    font-variant-numeric: tabular-nums;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.va-audit-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3, 0.75rem);
    padding: var(--space-10, 4rem) var(--space-4, 1rem);
    /* ref-33 bos durum: gri kuyu degil, hayalet cerceveli sade kart. */
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
    border-radius: var(--card-radius);
}

.va-audit-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
}

.va-audit-row--skeleton {
    height: 64px;
    background: linear-gradient(90deg,
        var(--surface-container-low) 0%,
        var(--surface-container) 50%,
        var(--surface-container-low) 100%);
    background-size: 200% 100%;
    animation: vaShimmer 1500ms ease-in-out infinite;
}

@keyframes vaShimmer {
    from { background-position: 0% 50%; }
    to { background-position: -200% 50%; }
}

@media (max-width: 640px) {
    .va-audit-row {
        grid-template-columns: auto 1fr auto;
    }
    .va-audit-row-time {
        grid-column: 2 / -1;
    }
}

/* Time-range segmented control. Tonal-shift only — no borders. */
.va-audit-ranges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1, 0.25rem);
    margin-bottom: var(--space-2, 0.5rem);
}

.va-audit-range {
    padding: var(--space-1, 0.25rem) var(--space-3, 0.75rem);
    background: transparent;
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--btn-radius);
    font-family: var(--font-body);
    font-size: var(--font-size-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition: background var(--transition-btn), color var(--transition-btn);
}

.va-audit-range:hover {
    background: var(--surface-container);
    color: var(--on-surface);
}

.va-audit-range.is-active {
    background: var(--surface-container-high);
    color: var(--primary);
}

/* Today-back link in the header — small, muted, primary on hover. Sits
   below the subtitle so it doesn't compete with the page title. */
.va-audit-header-link {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: var(--space-2, 0.5rem);
    color: var(--on-surface-variant);
    text-decoration: none;
    font-size: var(--font-size-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    transition: color var(--transition-btn);
}
.va-audit-header-link:hover,
.va-audit-header-link:focus-visible {
    color: var(--primary);
    outline: none;
}

/* Actor filter chips — compact horizontal strip between range and tabs. */
.va-audit-actors {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    align-items: center;
}

.va-audit-actor-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.625rem;
    background: var(--surface-container-high);
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--btn-radius);
    cursor: pointer;
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    transition: background var(--transition-btn), color var(--transition-btn);
}
.va-audit-actor-chip:hover {
    background: var(--surface-container-highest);
    color: var(--on-surface);
}
.va-audit-actor-chip.is-active {
    background: var(--primary-glow);
    color: var(--primary);
}

/* ══ KATEGORİ AKSANI (--acc) ════════════════════════════════════════════════
   Uygulama neredeyse tek renkti. ÖLÇÜLDÜ 2026-08-27, global CSS'te:
       uygulama  primary 170 · secondary 37 · tertiary 16   -> %76 tek renk
       wp teması primary 62  · secondary 55 · tertiary 47   -> dengeli
   wp'nin kalıbı: bir kap `style="--acc: var(--secondary)"` ile aksanını ilan
   eder, tek bir kural kümesi şeridi, ikon zeminini ve konturu ondan türetir.
   Renk DEKORASYON değil, AYIRT EDİCİ: yan yana duran farklı boyutlar (departman,
   ajan tipi, saga ailesi) tek bakışta ayrılır.

   Aksan verilmezse primary'ye düşer — mevcut hiçbir görünüm değişmez. */

.va-acc {
    position: relative;
    padding-left: 1.25rem;
}

/* Sol şerit: kabın tam yüksekliği. Bu bir 1px kenarlık DEĞİL — tasarım sistemi
   1px kenarlığı yasaklar; bu, ölçülebilir kalınlıkta bir aksan bandıdır. */
.va-acc::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--acc, var(--primary));
}

/* İkon kovası: aksanın düşük opaklıkta zemini + tam opak konturu. */
.va-acc-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--acc, var(--primary) 16%, transparent));
    color: var(--acc, var(--primary));
}

/* Aksanlı etiket/rozet: aynı renkten türer, ayrı token istemez. */
.va-acc-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--acc, var(--primary));
    background: color-mix(in srgb, var(--acc, var(--primary) 14%, transparent));
}

/* Kategori paleti: ADLANDIRILMIŞ, sayı değil. Bir kap --acc'yi bunlardan
   biriyle ilan eder; hangi rengin hangi anlama geldiği tek yerde durur. */
.va-acc--flow    { --acc: var(--primary); }
.va-acc--data    { --acc: var(--secondary); }
.va-acc--agent   { --acc: var(--tertiary); }
.va-acc--warn    { --acc: var(--state-warning); }
.va-acc--danger  { --acc: var(--error); }
.va-acc--ok      { --acc: var(--state-success); }

/* ══ YARIÇAP TABANI ═════════════════════════════════════════════════════════
   Aynı TÜR öğe farklı yarıçaplar taşıyordu. ÖLÇÜLDÜ 2026-08-27, 6 sayfada
   tarayıcıda:
       buton  5 FARKLI değer: 12px×610 · 0px×43 · 50%×11 · 16px×8 · 20px×1
       rozet  3 FARKLI: 12px×123 · 9999px×13 · 0px×10
       kart   3 FARKLI: 16px×11 · 0px×4 · 20px×3
       tablo  0px
   Kök neden: TABAN KURAL YOKTU. Her bileşen kendi yarıçapını yazıyor, yazmayan
   tarayıcı varsayılanı olan 0px alıyordu — FavoritesBar (15 sapma) hiç
   border-radius tanımlamıyor.

   Aşağıdaki kurallar TABANDIR, dayatma değil: :where() ile özgüllük sıfır,
   yani kendi yarıçapını bilerek veren her bileşen kazanmaya devam eder.
   (:where() burada DOĞRU araç — dikey ritimde yanlıştı çünkü orada sonraki
   stylesheet'lerdeki sınıf kuralları eziyordu; burada ezilmesi ZATEN İSTENEN
   davranış: bilinçli bir yarıçap her zaman tabanı geçmeli.) */

:where(button, [role="button"], .btn, [class*="-btn"]) {
    border-radius: var(--btn-radius);
}

:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
       select, textarea) {
    border-radius: var(--input-radius);
}

:where([class*="badge"], [class*="chip"], [class*="tag"]) {
    border-radius: var(--btn-radius);
}

:where([class*="card"], [class*="panel"]) {
    border-radius: var(--card-radius);
}

/* Tablo: köşeleri sarmalayıcı taşır. <table> kendi border-radius'unu hücre
   kenarlıklarıyla birlikte YOK SAYAR (collapse), bu yüzden overflow:hidden
   ile kırpılır. ÖLÇÜLDÜ: tablo tek düz öğe olarak kalıyordu (0px). */
:where(.data-table-wrapper, .table-responsive, .data-table-scroll, .data-table-wrap) {
    border-radius: var(--card-radius);
    overflow: hidden;
}

/* İçeride yatay kaydırma gerekiyorsa overflow:hidden onu öldürür; bu yüzden
   kaydırma sarmalayıcının KENDİSİNDE kalır ve yalnız köşeler kırpılır. */
:where(.data-table-wrapper, .table-responsive, .data-table-scroll) {
    overflow-x: auto;
    overflow-y: hidden;
}

/* ══ DURUM AKSANI: kart şeridi rozetle AYNI renkten türer ═══════════════════
   ÖLÇÜLDÜ 2026-08-28: 92 sayfa döngüyle kart basıyor ve kartlar bir durum/
   kategori alanı taşıyor (Status, Severity, Priority, Category), ama hiçbiri
   aksan kullanmıyordu — yan yana duran farklı durumlar tek bakışta ayrılmıyor.
   Aksan kullanan dosya sayısı: 2. Renk dengesi primary 177 / secondary 39 /
   tertiary 18, yani %75 tek renk.

   YENİ RENK SÖZLÜĞÜ UYDURULMADI. Sistem zaten StatusBadge'de bir durum
   sözlüğü taşıyor (success/warning/error/critical/pending/active/inactive/
   info/neutral) ve --state-* tokenleri var. Kart şeridi ROZETLE AYNI
   kaynaktan beslenir; ikisi ayrışamaz.

   Kullanım: <div class="x-card va-status va-status--warning">
   Şerit 3px — 1px kenarlık DEĞİL; tasarım sistemi 1px kenarlığı yasaklar. */

.va-status {
    position: relative;
    padding-left: 1.25rem;
}

.va-status::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--va-status-c, var(--outline-variant));
}

.va-status--success  { --va-status-c: var(--state-success); }
.va-status--warning  { --va-status-c: var(--state-warning); }
.va-status--error    { --va-status-c: var(--state-error); }
.va-status--critical { --va-status-c: var(--state-critical, var(--state-error)); }
.va-status--pending  { --va-status-c: var(--state-pending, var(--state-warning)); }
.va-status--active   { --va-status-c: var(--state-active, var(--state-success)); }
.va-status--inactive { --va-status-c: var(--outline-variant); }
.va-status--info     { --va-status-c: var(--state-info, var(--primary)); }
.va-status--neutral  { --va-status-c: var(--outline-variant); }

/* ── Durum sözlüğü EŞDEĞERLİKLERİ ───────────────────────────────────────────
   ÖLÇÜLDÜ 2026-08-28: depoda ÜÇ ayrı durum sözlüğü yan yana yaşıyor ve eşleme
   metotları hangisini döndüreceğine sayfa sayfa karar veriyor:
       StatusBadge : success · warning · error · info · neutral        (26-35 kez)
       badge-*     : badge-ok · badge-warn · badge-error · badge-info  (88-119 kez)
       status-*    : status-completed · status-failed · status-running (4-9 kez)

   42 farklı badge-* değeri sayıldı ve çoğu DURUM BİLE DEĞİL (badge-count,
   badge-label, badge-user). Sayfaları tek tek dönüştürmek yerine — kör dönüşüm
   yanlış renk üretirdi — YALNIZ durum anlamı taşıyan adlar bağlanır. Anlamı
   olmayan adlara dokunulmaz; aksan almazlar ve nötr kalırlar.

   ÇIPLAK adlar da gerekli: eşleme metotlarının çoğu StatusBadge'in Variant'ına
   doğrudan "success"/"warning" döndürüyor ve bu ad karta taşındığında önek
   taşımaz. Bu kural olmadan aksan sessizce nötr kalıyordu — ÖLÇÜLDÜ: 36 sayfada
   şerit rengi hep rgb(64,72,73) yani --outline-variant fallback'i. */

.va-status.success,   .va-status.badge-ok,      .va-status.badge-success,
.va-status.badge-pass, .va-status.status-completed  { --va-status-c: var(--state-success); }

.va-status.warning,   .va-status.badge-warn,    .va-status.badge-warning,
.va-status.status-warn, .va-status.pending,     .va-status.badge-pending,
.va-status.badge-wait                                { --va-status-c: var(--state-warning); }

.va-status.error,     .va-status.danger,        .va-status.badge-error,
.va-status.badge-fail, .va-status.badge-danger, .va-status.status-failed
                                                     { --va-status-c: var(--state-error); }

.va-status.critical,  .va-status.badge-critical      { --va-status-c: var(--state-critical, var(--state-error)); }

.va-status.active,    .va-status.badge-active,
.va-status.status-running                            { --va-status-c: var(--state-active, var(--state-success)); }

.va-status.inactive,  .va-status.badge-inactive,
.va-status.badge-expired, .va-status.badge-revoked,
.va-status.status-draft, .va-status.neutral,
.va-status.badge-neutral                             { --va-status-c: var(--outline-variant); }

.va-status.info,      .va-status.badge-info,
.va-status.status-info                               { --va-status-c: var(--state-info, var(--primary)); }

/* ============================
   Gradyan yardımcıları — SIRA DÜZELTMESİ
   ============================ */
/* .gradient-primary veraius-base.css'te tanımlı ama veraius-components.css
   ONDAN SONRA yükleniyor ve .section-card gibi bileşen zeminleri onu SESSİZCE
   eziyordu. Sonuç: kutu --surface-container zeminde kalıyor ama içindeki metin
   --on-primary kullanıyor — yani "primary zemin üstündeyim" varsayımıyla.

   ÖLÇÜLDÜ 2026-09-02 /reports, .rdp-cta:
       beklenen zemin : linear-gradient(--primary → --primary-container)
       GERÇEK zemin   : rgb(28,38,54)  (--surface-container, .section-card'tan)
       h2.rdp-cta-title  #003739 üzerinde #1c2636  → 1.2:1  (WCAG AA: 4.5)

   Yardımcı sınıf, bileşen zemininden SONRA gelmeli. Özgüllük yükseltilmedi —
   yalnız aynı özgüllükte, daha sonra bildirilerek kazanıyor. 5 sayfa kullanıyor. */
.gradient-primary {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-container) 100%);
}

/* ─────────────────────────────────────────────────────────────────────────────
   SOHBET YANITI — A+B yeniden tasarımı (2026-09-02)

   Neden: asistan balonunun BAŞLIĞINDA 18 ayrı görsel öğe vardı (ajan adı, model
   adı, rota rozeti, güven şeridi, kaynak sayısı, kaynak rozetleri…) ve yanıt metni
   bileşende ancak 237. satırda başlıyordu. Kullanıcının aradığı tek şey — rakam —
   en sonda kalıyordu. Şimdi: cevap ilk satırda, kanıt katmanı yanıtın ALTINDA ve
   kapalı; bekleme sırasında sistemin o an ne yaptığı görünüyor.

   Tasarım sistemi kuralları korunur: 1px kenarlık YOK (tonal geçiş), dark/light'ta
   yuvarlak köşe YOK, yalnız Manrope, yeni palet eklenmedi (mevcut token seti).
   ───────────────────────────────────────────────────────────────────────────── */

/* Sade başlık: yalnız avatar. Kimlik metni kaldırıldı — kullanıcı kiminle
   konuştuğunu zaten biliyor; her yanıtta tekrarı gürültü. */
.va-answer-head {
    display: flex;
    align-items: center;
    margin-bottom: 0.75rem;
}

/* ── Bekleme: sistemin o an ne yaptığı ───────────────────────────────────── */
/* ÖLÇÜLDÜ 2026-09-03: kendi yüzeyi olan bir panel, mesaj balonunun İÇİNDE ikinci bir kutu olarak
   görünüyordu (iç içe iki kap). Panelin kabı kaldırıldı — balonun içinde yaşar, kendi zemini yok. */
.va-answer-progress {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.va-answer-progress__now {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0;
}

/* Geçen süre: durumun yanında, sessiz. Tek yerde gösterilir — eskiden yanıt gövdesinde ayrı bir
   cümle olarak da yazılıyordu ve ekranda iki durum metni birden duruyordu. */
.va-answer-progress__elapsed {
    margin-left: auto;
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
    font-variant-numeric: tabular-nums;
}

/* Nabız: "çalışıyor" sinyalini tek bir sakin öğeyle taşır (üç zıplayan nokta yerine). */
.va-answer-progress__spark {
    width: 0.5rem;
    height: 0.5rem;
    flex: none;
    background: var(--primary);
}

@media (prefers-reduced-motion: no-preference) {
    .va-answer-progress__spark {
        animation: va-answer-progress-pulse 1.4s ease-in-out infinite;
    }
    @keyframes va-answer-progress-pulse {
        0%, 100% { opacity: 0.35; }
        50%      { opacity: 1; }
    }
}

.va-answer-progress__title {
    font-weight: 600;
    font-size: var(--font-size-base);
    line-height: 1.4;
    color: var(--on-surface);
}

.va-answer-progress__count {
    margin-left: auto;
    font-size: var(--font-size-2xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 0.125rem 0.375rem;
    background: var(--surface);
    color: var(--on-surface-variant);
    font-variant-numeric: tabular-nums;
}


/* Tamamlanan adımlar: sıra bilgi taşıdığı için numaralı liste. */
.va-answer-progress__done {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
}

.va-answer-progress__done li::before {
    content: "✓";
    margin-right: 0.5rem;
    color: var(--primary);
}

/* İçerik iskeleti: yanıtın şekli beklerken de görünür, ekran boş kalmaz. */
.va-answer-skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.25rem;
}

.va-answer-skeleton span {
    display: block;
    height: 0.625rem;
    background: var(--surface-container-high);
    position: relative;
    overflow: hidden;
}

.va-answer-skeleton span:nth-child(1) { width: 62%; }
.va-answer-skeleton span:nth-child(2) { width: 88%; }
.va-answer-skeleton span:nth-child(3) { width: 45%; }

/* Opacity nabzı KALDIRILDI: shimmer (aşağıda) yön duygusu olan tek hareket olarak kalır;
   ikisi üst üste binince çubuklar titrek görünüyordu. */

/* ── Kanıt katmanı: yanıtın altında, kapalı ──────────────────────────────── */
.va-answer-provenance {
    margin-top: 0.75rem;
    background: var(--surface-container-high);
}

.va-answer-provenance__toggle {
    cursor: pointer;
    padding: 0.5rem 0.75rem;
    font-size: var(--font-size-sm);
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--on-surface-variant);
    list-style: none;
    transition: color var(--transition-btn);
}

.va-answer-provenance__toggle::-webkit-details-marker { display: none; }

.va-answer-provenance__toggle::before {
    content: "› ";
    color: var(--primary);
    font-weight: 800;
}

.va-answer-provenance[open] .va-answer-provenance__toggle::before { content: "⌄ "; }

.va-answer-provenance__toggle:hover,
.va-answer-provenance__toggle:focus-visible { color: var(--on-surface); }

.va-answer-provenance__body {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: 0 0.75rem 0.75rem;
}

.va-answer-provenance__row {
    display: grid;
    grid-template-columns: minmax(6rem, 9rem) 1fr;
    gap: 0.75rem;
    align-items: baseline;
    font-size: var(--font-size-sm);
}

.va-answer-provenance__key {
    color: var(--on-surface-variant);
    letter-spacing: 0.04em;
}

.va-answer-provenance__val {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    align-items: center;
    color: var(--on-surface);
}

@media (max-width: 600px) {
    .va-answer-provenance__row { grid-template-columns: 1fr; gap: 0.125rem; }
}

/* KAYNAK KARTLARI (plan #2). Kaynaklar künyenin içinde yaşar; ayrı bir kart AÇMAZ — üstünde
   zaten kapalı bir <details> var, ikinci kutu beşinci bir şeffaflık katmanı olurdu.
   Anahtar/değer ızgarası burada bozulur: pasaj metni 9rem'lik bir sütunun yanında okunmaz,
   bu yüzden satır tek sütuna geçer (--stack). */
.va-answer-provenance__row--stack {
    grid-template-columns: 1fr;
    gap: 0.375rem;
}

.va-source-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1px; /* 1px KENARLIK DEĞİL: kartlar arası tonal ayrım, altındaki zemin sızar */
    background: var(--surface-container);
}

.va-source-item {
    background: var(--surface-container-low);
    padding: 0.5rem 0.625rem;
    border-radius: var(--btn-radius);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.va-source-item__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
}

.va-source-item__title {
    color: var(--on-surface);
    font-size: var(--font-size-sm);
    font-weight: 500;
    overflow-wrap: anywhere;
}

.va-source-item__score {
    color: var(--on-surface-variant);
    font-size: var(--font-size-xs);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Pasaj uzun olabilir: kırpmak yerine üç satırda sınırla. Kırpılmış metin okuyucuya
   doğrulama imkânı vermez; üç satır bağlamı taşır, kartı da şişirmez. */
.va-source-item__snippet {
    margin: 0;
    color: var(--on-surface-variant);
    font-size: var(--font-size-xs);
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Kanıt zinciri (C birleşimi): yanıta hangi adımlardan geçilerek varıldığı. Numaralandırma
   gerçek bir sırayı temsil ediyor — dekoratif değil, bu yüzden <ol> ve görünür sayı. */
.va-answer-provenance__chain {
    list-style: none;
    counter-reset: va-proof;
    margin: 0 0 0.5rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.va-answer-provenance__chain li {
    counter-increment: va-proof;
    display: grid;
    grid-template-columns: 1.25rem 1fr;
    gap: 0.5rem;
    align-items: baseline;
    font-size: var(--font-size-sm);
}

.va-answer-provenance__chain li::before {
    content: counter(va-proof);
    color: var(--primary);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.va-answer-provenance__chain-title {
    color: var(--on-surface);
    font-weight: 600;
}

/* Satır grid'i 2 sütunlu (numara | metin) ama 3 çocuk taşır (::before, başlık, açıklama). ÖLÇÜLDÜ 2026-10-04:
   açıklama alt satırda 1,25rem'lik NUMARA sütununa düşüyor, "Algılanan / niyet: / arama." diye kelime kelime
   kırılıyordu. Açıklama başlığın altında, metin sütununda durur. */
.va-answer-provenance__chain-detail {
    grid-column: 2;
    display: block;
    color: var(--on-surface-variant);
    line-height: 1.5;
}

/* Halkanın SONUCU (2026-10-23): başarısız adım numarası durum rengini alır ve yanında "Başarısız" rozeti +
   gerekçe yazılır — renk tek başına anlam taşımaz. Süre yalnız ölçülmüşse basılır, sayılar hizalı. */
.va-answer-provenance__chain-title {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.375rem;
}

.va-answer-provenance__chain-latency {
    color: var(--on-surface-variant);
    font-weight: 400;
    font-size: var(--font-size-xs);
    font-variant-numeric: tabular-nums;
}

.va-answer-provenance__chain li.va-answer-provenance__chain-item--failed::before {
    color: var(--state-error-text);
}

.va-answer-provenance__chain-error {
    color: var(--state-error-text);
}

/* Bekleme adımları: sistemin attığı adımların TAMAMI akar. Son adım vurgulu, öncekiler tamamlandı.
   Eski zaman çizelgesinden farkı: bilgi taşımayan "0.00s" sütunu ve tekrar eden açıklama satırı yok. */
.va-answer-progress__steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.va-answer-progress__steps li {
    display: grid;
    grid-template-columns: 0.75rem 1fr auto;
    gap: 0.5rem;
    align-items: baseline;
    font-size: var(--font-size-md);
}

.va-answer-progress__mark {
    width: 0.375rem;
    height: 0.375rem;
    align-self: center;
    background: var(--on-surface-variant);
    opacity: 0.5;
}

.va-answer-progress__steps li.is-done .va-answer-progress__step-title {
    color: var(--on-surface-variant);
}

.va-answer-progress__steps li.is-current .va-answer-progress__step-title {
    color: var(--on-surface);
    font-weight: 600;
}

.va-answer-progress__steps li.is-current .va-answer-progress__mark {
    background: var(--primary);
    opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
    .va-answer-progress__steps li.is-current .va-answer-progress__mark {
        animation: va-answer-progress-pulse 1.4s ease-in-out infinite;
    }
}

/* Henüz ulaşılmamış aşama: görünür ama sessiz — kullanıcı kaç adım kaldığını görür. */
.va-answer-progress__steps li.is-pending .va-answer-progress__step-title {
    color: var(--on-surface-variant);
    opacity: 0.45;
}

.va-answer-progress__steps li.is-pending .va-answer-progress__mark { opacity: 0.25; }

/* Tamamlanan aşama işareti: onay. */
.va-answer-progress__steps li.is-done .va-answer-progress__mark {
    background: var(--primary);
    opacity: 0.7;
}

/* Dönen adım satırı: yeni adım geldiğinde @key DOM düğümünü yenilediği için bu giriş animasyonu
   her adımda yeniden çalışır — satır "değişti" hissi verir, ani sıçrama olmaz. */
@media (prefers-reduced-motion: no-preference) {
    .va-answer-progress__now {
        animation: va-answer-step-in 260ms var(--ease-smooth, ease-out) both;
    }
    @keyframes va-answer-step-in {
        from { opacity: 0; transform: translateY(0.25rem); }
        to   { opacity: 1; transform: none; }
    }
}

/* Shimmer: iskelet çubukları üzerinde soldan sağa geçen parlama. Yalnız opacity nabzı "donmuş"
   duruyordu; yön duygusu olan bir hareket beklemenin sürdüğünü daha iyi anlatıyor. */

@media (prefers-reduced-motion: no-preference) {
    .va-answer-skeleton span::after {
        content: "";
        position: absolute;
        inset: 0;
        background: linear-gradient(90deg,
            transparent,
            color-mix(in srgb, var(--on-surface) 8%, transparent) 45%,
            color-mix(in srgb, var(--on-surface) 12%, transparent) 55%,
            transparent);
        transform: translateX(-100%);
        animation: va-skeleton-shimmer 1.8s ease-in-out infinite;
    }

    .va-answer-skeleton span:nth-child(2)::after { animation-delay: 0.15s; }
    .va-answer-skeleton span:nth-child(3)::after { animation-delay: 0.3s; }

    @keyframes va-skeleton-shimmer {
        to { transform: translateX(100%); }
    }
}

/* Bekleme spinner'ı: kare bir nokta yerine dönen halka. Nokta "duruyor" gibi okunuyordu; dönen bir
   halka beklemenin sürdüğünü tek başına anlatır. Kalınlık ve boyut satır yüksekliğine oranlı. */
.va-answer-progress__spinner {
    width: 0.9375rem;
    height: 0.9375rem;
    flex: none;
    margin-top: 0.1875rem;
    border-radius: 50%;
    /* Halkanın kendisi: üç yanı sönük, biri vurgulu → dönerken yön okunur. */
    background:
        conic-gradient(from 0deg,
            transparent 0deg,
            color-mix(in srgb, var(--primary) 20%, transparent) 180deg,
            var(--primary) 340deg,
            transparent 360deg);
    /* Ortası boş: dolu daire yerine ince bir halka. */
    /* stylelint-disable color-no-hex -- mask: siyah/beyaz renk değil, alfa kanalıdır */
    mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    /* stylelint-enable color-no-hex */
}

@media (prefers-reduced-motion: no-preference) {
    .va-answer-progress__spinner { animation: va-answer-spin 900ms linear infinite; }
    @keyframes va-answer-spin { to { transform: rotate(360deg); } }
}

/* Hareket azaltma tercihinde: dönmeyen ama görünür bir halka kalır. */
@media (prefers-reduced-motion: reduce) {
    .va-answer-progress__spinner {
        background: color-mix(in srgb, var(--primary) 60%, transparent);
    }
}

/* Bekleme satırı: spinner solda, başlık ve açıklaması sağda alt alta. */
.va-answer-progress__text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

/* Açıklama: başlığın altında, sessiz. Uzun adım metni satırı büyütmesin diye tek satıra kırpılır. */
.va-answer-progress__detail {
    margin: 0;
    font-size: var(--font-size-sm);
    line-height: 1.45;
    color: var(--on-surface-variant);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Yanıt tipografisi — sunulan tasarımdaki okunabilirlik ayarları.
   Uzun satır okumayı yorar; ölçü satırı ~70 karakterde tutulur. Tablolar, kod ve grafikler bu
   sınırdan muaftır (kendi genişliklerini kullanırlar), yoksa veri sıkışır. */
.msg-assistant-body .msg-text > p,
.msg-assistant-body .msg-text > ul,
.msg-assistant-body .msg-text > ol,
.msg-assistant-body .msg-text > blockquote {
    max-width: 70ch;
}

/* İlk paragraf = cevabın özü. Sunulan tasarımda bu satır daha büyük ve sakin bir ağırlıkta:
   kullanıcı taradığında önce onu görür, gerisi destekleyici metin olarak geride kalır. */
.msg-assistant-body .msg-text > p:first-child {
    font-size: 1.0625rem;
    line-height: 1.55;
    font-weight: 500;
    text-wrap: pretty;
}

/* Rakamlar sütunlarda hizalansın (tablo ve liste içinde). */

/* Dönen gradyan kenarlığın açısı. @property GLOBAL olmalı: scoped bileşen CSS'inde (b-xxxx nitelikli)
   kaydolmuyor ve conic-gradient açısı 0deg'de takılı kalıyor (ÖLÇÜLDÜ 2026-09-03: açı t0=0deg → t1=0deg,
   animasyon adı atanmış olmasına rağmen). Tip bildirimi olmadan CSS özel özelliği interpole edilemez. */
@property --va-sweep-angle {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
}

/* Akış sırasında grafik hazırlanıyor göstergesi: kapanmamış ```mermaid bloğunun yerini alır.
   Ham mermaid kaynağı kullanıcıya kod olarak akıyordu (ÖLÇÜLDÜ 2026-09-03). */
.va-chart-pending {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    /* Arka plan YOK: mesaj balonunun içinde ayrı bir kutu gibi durmasın — satır olarak akar. */
    padding: 0.5rem 0;
    /* Grafigin yerini SIMDIDEN ayir. OLCULDU 2026-09-30: gosterge 37px, gelen grafik 231px idi —
       yanit bittigi an icerik ~194px asagi itiliyordu ("bozulup sonra duzelen" duzen). */
    min-height: 14rem;
    justify-content: center;
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
}

.va-chart-pending__spinner {
    width: 0.875rem;
    height: 0.875rem;
    flex: none;
    border-radius: 50%;
    background: conic-gradient(from 0deg,
        transparent 0deg,
        color-mix(in srgb, var(--primary) 20%, transparent) 180deg,
        var(--primary) 340deg,
        transparent 360deg);
    /* stylelint-disable color-no-hex -- mask: siyah/beyaz renk değil, alfa kanalıdır */
    mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    /* stylelint-enable color-no-hex */
}

@media (prefers-reduced-motion: no-preference) {
    .va-chart-pending__spinner { animation: va-answer-spin 900ms linear infinite; }
}

/* ── Sohbet yanıtındaki tablolar ──────────────────────────────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-03: başlık 10px, gövde 13px — başlık gövdeden KÜÇÜKtü, hiyerarşi tersti ve
   tablo okunmuyordu. Ayrıca sayısal sütunlar sola dayalıydı (rakamlar hizalanmıyordu) ve satır
   yüksekliği sıkışıktı. Yeniden tasarımdaki veri tablosu ölçüleri: okunur başlık, sağa dayalı
   sayılar, rahat satır. Kenarlık yok — ayrım tonal (tasarım sistemi kuralı).
   Geniş tablo kendi kabında kaydırılır — sayfa yatay kaymaz (tasarım sistemi kuralı). */
.msg-assistant-body .msg-text table {
    font-size: var(--font-size-base);
    line-height: 1.55;
    /* HÜCRELER HARF HARF SARMASIN. ÖLÇÜLEN KUSUR 2026-09-11 (video karesi): 6 sütunlu mağaza
       tablosu dar alana sıkışınca tarayıcı her kelimeyi DİKEY olarak harf harf kırıyordu —
       "İstanbul" → İ/s/t/a/n/b/u/l alt alta, "2.105.141" → "2.105.14" + "1". Sayı ortadan
       bölünmek okunamaz olmanın ötesinde YANLIŞ OKUNUR.
       Çözüm: içeriğe göre genişleyen düzen + hücre içi kırılmanın kapatılması. Tablo kabına
       sığmazsa aşağıdaki sarmalayıcı ile YATAY KAYDIRILIR (sayfa gövdesi kaymaz). */
    table-layout: auto;
    width: max-content;
    max-width: 100%;
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.msg-assistant-body .msg-text table td,
.msg-assistant-body .msg-text table th {
    font-variant-numeric: tabular-nums;
    /* Kelime ortasından kırma YOK; hücre gerektiği kadar geniş olur. */
    overflow-wrap: normal;
    word-break: normal;
    hyphens: none;
    white-space: nowrap;
}

/* Uzun serbest metin taşıyan hücreler (başlık/açıklama) yine sarabilsin — yalnız KELİME
   sınırından. Sayı ve kısa etiket sütunları yukarıdaki nowrap ile tek satırda kalır. */
.msg-assistant-body .msg-text table td:last-child {
    white-space: normal;
    overflow-wrap: break-word;
    min-width: 12ch;
}

.msg-assistant-body .msg-text th {
    /* 10px → 11.5px: başlık artık gövdeyle uyumlu, yine de etiket karakterini korur. */
    font-size: 0.71875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    padding-block: 0.625rem;
    white-space: nowrap;
}

.msg-assistant-body .msg-text td {
    padding-block: 0.625rem;
}

/* Sayısal hücreler sağa dayalı: rakamlar sütun içinde hizalanır, karşılaştırma gözle yapılabilir.
   :has() ile yalnız gerçekten sayısal olan hücreler hedeflenemediği için son sütunlar hizalanır —
   agent tablolarında değer sütunu neredeyse her zaman sonda. */
.msg-assistant-body .msg-text td:not(:first-child),
.msg-assistant-body .msg-text th:not(:first-child) {
    text-align: right;
}

/* İlk sütun etiket taşır: sola dayalı ve biraz baskın. */
.msg-assistant-body .msg-text td:first-child {
    font-weight: 500;
    color: var(--on-surface);
}

/* Zebra yerine daha sakin bir ayrım: satır arası tonal çizgi (kenarlık değil, gölge). */
.msg-assistant-body .msg-text tbody tr:not(:last-child) td {
    box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--on-surface) 7%, transparent);
}

/* ── Sohbet tablosu: kurumsal veri tablosu görünümü ───────────────────────────────────────────
   Tablolar akış sırasında "Tablo hazırlanıyor…" göstergesiyle beklenir, tamamlanınca burada
   tanımlanan ölçülerle çizilir. Kenarlık yok (tasarım sistemi kuralı) — ayrım tonal. */
.msg-assistant-body .msg-text .nexus-table-wrapper {
    margin-block: 1rem;
    /* Balonun kendi zemininden bir kademe yukarı — ayrı bir "kart" gibi durmasın ama ayrışsın.
       Sabit bir yüzey tokenı yerine balonla aynı aileden: açık temada da doğru çalışır. */
    background: color-mix(in srgb, var(--on-surface) 4%, var(--surface-container-lowest));
    overflow: hidden;
}

.msg-assistant-body .msg-text .nexus-table-container {
    overflow-x: auto;
}

.msg-assistant-body .msg-text .nexus-table-wrapper table {
    width: 100%;
    border-collapse: collapse;
    margin: 0;
}

/* Başlık bandı: tonal olarak bir kademe yukarı — çizgi değil, yüzey farkı. */
.msg-assistant-body .msg-text .nexus-table-wrapper thead th {
    background: color-mix(in srgb, var(--on-surface) 8%, var(--surface-container-lowest));
    box-shadow: none;
    padding: 0.75rem 1rem;
    white-space: nowrap;
}

.msg-assistant-body .msg-text .nexus-table-wrapper td {
    padding: 0.6875rem 1rem;
}

/* Son satırda ayrım çizgisi olmasın (tablo kapanışı temiz kalsın). */
.msg-assistant-body .msg-text .nexus-table-wrapper tbody tr:last-child td {
    box-shadow: none;
}

/* Tablo başlık çubuğu: yalnız dışa aktarma eylemi. Sağa yaslanır, sessiz durur — tablonun kendisi
   asıl içerik, düğme ona rekabet etmemeli. */
.msg-assistant-body .msg-text .table-header-actions {
    display: flex;
    justify-content: flex-end;
    padding: 0.375rem 0.75rem 0;
}

.msg-assistant-body .msg-text .export-csv-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: none;
    border: none;
    cursor: pointer;
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--on-surface-variant);
    padding: 0.25rem 0.375rem;
    transition: color var(--transition-btn);
}

.msg-assistant-body .msg-text .export-csv-btn:hover,
.msg-assistant-body .msg-text .export-csv-btn:focus-visible {
    color: var(--primary);
}

.msg-assistant-body .msg-text .export-csv-btn .material-symbols-outlined {
    font-size: var(--icon-sm);
}

/* ── Tur hatası kurtarma şeridi ───────────────────────────────────────────────────────────────
   Kaynak deseni (parallelhq, thefrontkit): hatayı gizleme, nedenini söyle ve kurtarma yolu ver.
   Kritik hata rengi yalnız sol şeritte — panel kendi başına alarm gibi durmamalı, kullanıcı zaten
   bir şeyin ters gittiğini biliyor; burada aranan şey ne yapılacağı. */
/* BAĞLAM KIRPILMA ŞERİDİ (plan #4). Hata DEĞİL, sistem normal çalışıyor — bu yüzden hata
   şeridinin kırmızı iç gölgesini değil, nötr bir vurgu taşır. Aynı yerleşimi paylaşır ki iki
   şerit üst üste geldiğinde hizalı görünsünler. */
/* SEÇİP-SOR BALONCUĞU (plan #5). position:fixed — seçim viewport koordinatı verir; sayfa
   akışına girmesi kaydırmada baloncuğu metinden koparırdı (scroll'da zaten kapanıyor). */
.va-selection-ask {
    position: fixed;
    z-index: 60;
    padding: 0.4rem 0.75rem;
    background: var(--surface-container-highest, var(--surface-container-high));
    color: var(--on-surface);
    border: none;
    border-radius: var(--btn-radius);
    font-family: inherit;
    font-size: var(--font-size-sm);
    cursor: pointer;
    box-shadow: var(--shadow-lg);
    transition: background var(--transition-btn);
}

.va-selection-ask:hover,
.va-selection-ask:focus-visible { background: var(--surface-container-high); }

.va-context-trim {
    margin-block: 0.5rem;
    padding: 0.625rem 1rem;
    background: var(--surface-container);
    border-radius: var(--btn-radius);
    box-shadow: inset 3px 0 0 var(--outline-variant);
}

.va-context-trim__text {
    color: var(--on-surface-variant);
    font-size: var(--font-size-sm);
    line-height: 1.5;
}

/* HATA KURTARMA — asistan balonu diliyle (2026-09-03 yeniden tasarım). `.va-turn-failure` artık
   `.msg-assistant-body`'nin ÜZERİNE binen bir ek sınıf: dolgu/zemin/köşe/gölge zaten oradan geliyor.
   Burada yalnız İKİ şey değişir: sol kenar vurgusu kırmızıya döner (persona rengi yerine — bu bir
   hata, departman rengi anlamsız), ve iç tipografi/eylemler LLM metin akışıyla aynı ölçekte kalır. */
/* ÖLÇÜLDÜ 2026-09-03 (canlı koşu, Ollama ölü porta yönlendirildi): şerit `.msg-assistant-body`
   sınıfını taşıyor ama O STİLİ ALMIYOR — `.msg-assistant-body` yalnız `ChatMessageItem.razor.css`
   içinde, yani Blazor SCOPED CSS olarak tanımlı. Kurtarma şeridi başka bir bileşende
   (ChatPageCommandInterfaceMessages) yaşadığı için o bileşenin scope niteliğini taşımıyor ve
   kural hiç eşleşmiyor. Ölçüm: `backgroundColor: rgba(0,0,0,0)` — zemin tamamen şeffaftı.
   Bu yüzden görsel özellikler BURADA açıkça verilir; sınıfı paylaşmak yetmiyor. */
.va-turn-failure {
    flex: 1;
    width: 100%;
    max-width: 52rem;
    display: flex;
    flex-direction: column;
    padding: clamp(1rem, 2vw, 1.375rem);
    background: var(--surface-container-lowest);
    border: none; /* No-Line */
    /* Persona vurgusu yerine hata tonu: bu bir departman yanıtı değil, bir arıza. */
    border-left: 3px solid var(--state-error);
    border-radius: var(--card-radius);
    position: relative;
    box-shadow: var(--shadow-lg);
    color: var(--on-surface);
}

.va-turn-failure__reason {
    margin: 0 0 0.25rem;
    font-size: var(--font-size-base);
    line-height: 1.55;
    color: var(--on-surface);
}

.va-turn-failure__hint {
    margin: 0 0 0.875rem;
    font-size: var(--font-size-md);
    line-height: 1.5;
    color: var(--on-surface-variant);
}

.va-turn-failure__actions {
    display: flex;
    gap: 1.25rem;
}

/* Kutulu buton değil, metin-bağlantısı çipi — eylem zincirindeki diğer çiplerle (kaynak, kopyala,
   yeniden oluştur) aynı ağırlıkta durur, "sistem uyarısı" değil "asistanın önerdiği sonraki adım"
   gibi okunur. */
.va-turn-failure__btn {
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--on-surface-variant);
    transition: color var(--transition-btn);
}

.va-turn-failure__btn:hover,
.va-turn-failure__btn:focus-visible {
    color: var(--on-surface);
}

.va-turn-failure__btn--primary {
    color: var(--primary);
}

.va-turn-failure__btn--primary:hover,
.va-turn-failure__btn--primary:focus-visible {
    color: color-mix(in srgb, var(--primary) 80%, var(--on-surface));
}

/* ============================
   Detay listesi ve form eylem şeridi

   ÖLÇÜLDÜ 2026-09-04: /admin/rules/create sayfası etiket/değer çiftlerini Bootstrap'in
   `dl.row` + `dt.col-sm-5` + `dd.col-sm-7` üçlüsüyle diziyordu ve form altındaki
   düğmeleri `d-grid gap-2` ile. Bootstrap YÜKLÜ DEĞİL — üç sınıfın da tanımı yok,
   dolayısıyla çiftler alt alta yığılıyor ve düğmeler yan yana yapışıyordu. Bu iki
   kalıp her detay/form ekranında tekrar ettiği için sayfaya değil tasarım sistemine
   ait: aksi hâlde her sayfa kendi ızgarasını yeniden icat eder (aynı hata
   .form-input ailesinde 4 farklı dolgu değeri üretmişti).
   ============================ */
.detail-list {
    display: grid;
    grid-template-columns: minmax(6rem, auto) 1fr;
    gap: var(--space-2) var(--space-4);
    margin: 0;
    align-items: baseline;
}

.detail-list > dt {
    margin: 0;
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
}

.detail-list > dd {
    margin: 0;
    min-width: 0;
    font-size: var(--font-size-md);
    color: var(--on-surface);
    overflow-wrap: anywhere;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* Kenar çubuğundaki eylem yığını — düğmeler tam genişlikte alt alta. */
.form-actions--stacked {
    flex-direction: column;
    align-items: stretch;
}

/* Ana içerik + yardımcı kenar sütunu. Bootstrap `row`/`col-lg-8`/`col-lg-4`
   üçlüsünün kanonik karşılığı; o sınıfların hiçbirinin tanımı yok (ölçüldü). */
.work-layout {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
    gap: var(--space-4);
    align-items: start;
}

@media (max-width: 1100px) {
    .work-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Onay kutusu alanı — etiket ve kutu aynı taban çizgisinde, tıklama alanı etiketi kapsar.
   Bootstrap `.form-check` / `.form-check-input` / `.form-check-label` üçlüsünün kanonik
   karşılığı; üçünün de tanımı yok (ölçüldü 2026-09-04). */
.checkbox-field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 44px;
    cursor: pointer;
    color: var(--on-surface);
}

.checkbox-field > input[type="checkbox"] {
    width: 1.125rem;
    height: 1.125rem;
    flex: 0 0 auto;
    accent-color: var(--primary);
    cursor: pointer;
}

/* İkincil açıklama satırı (öneri, ipucu). `.text-muted` tanımsızdı. */
.detail-hint {
    margin: 0;
    font-size: var(--font-size-2xs);
    color: var(--on-surface-variant);
}

/* Filtre şeridindeki tek alan. Bootstrap `col-md-4`/`col-md-3`/`col-md-2` yerine:
   o sınıfların tanımı yok (ölçüldü 2026-09-04), dolayısıyla filtre girdileri
   sayfa boyu uzuyor ya da tek sütuna yığılıyordu. Esneme tabanı, alanın içeriğine
   göre büzülmesini engeller — .form-row'daki min-width:auto kusurunun aynısı. */
.filter-bar > .filter-field {
    flex: 1 1 12rem;
    min-width: 0;
}

/* ══ KURUMSAL FORM YERLEŞİMİ ═══════════════════════════════════════════════
   ÖLÇÜLDÜ 2026-09-05 /admin/rules/create: form kabı 1148px genişti ama her
   girdi 350px'te bitiyor, sağda ~800px boş kalıyordu — tek-alan satırları
   (Rule Name, Description) hiçbir genişleme kuralı taşımıyordu. Ayrıca hiçbir
   alanda yardım metni, zorunluluk işareti ya da odak göstergesi yoktu ve
   etiketler `text-transform: uppercase` yüzünden Türkçe yerelde bozuluyordu
   ("DESCRİPTİON", "PRİORİTY" — tarayıcı lang="tr" iken i→İ çevirir).
   ═════════════════════════════════════════════════════════════════════════ */

/* Alan sarmalayıcı: etiket + girdi + yardım metni tek dikey blok.

   `.form-field` AYNI ŞEYİN TANIMSIZ ADIYDI. ÖLÇÜLDÜ 2026-09-05: 39 dosyada
   kullanılıyor ve CSS'te HİÇBİR tanımı yok — yani o 39 sayfada etiket ve girdi
   bir blok oluşturmuyor, satır içinde akıyordu. Sınıfı silmek 39 sayfayı
   düzenlemek demekti; kanonik davranışa bağlamak hepsini tek hamlede düzeltir.
   Aynı örüntü .form-label ve .card-header'da da vardı. */
.field,
.form-field {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Girdiler kabı doldurur. Bir alanın dar olması gerekiyorsa bunu ALAN söyler
   (.field--narrow), girdi değil — aksi hâlde her sayfa kendi genişliğini icat
   eder ve hizalama sayfadan sayfaya kayar. */
.field > input,
.field > select,
.field > textarea,
.form-field > input,
.form-field > select,
.form-field > textarea,
.form-grid > .field > input,
.form-grid > .field > select,
.form-grid > .field > textarea {
    width: 100%;
}

.field--narrow > input,
.field--narrow > select {
    max-width: 12rem;
}

/* ETİKET DİL KİLİDİ KALDIRILDI (ölçüldü 2026-09-30). Buradaki `-webkit-locale: "en"`
   "etiketler İngilizce yazılıyor" öncülüne dayanıyordu ve "çevrilen etiketlerde de doğru
   sonuç verir" diyordu — ikisi de çürüdü: sabit etiketlerin çoğu artık Türkçe, İngilizce
   çevrim kuralı ise Türkçe "i"yi "I" yapar ("Öncelik" → "ÖNCELIK", "Aktif" → "AKTIF").
   Büyük harf çevrimi belgenin diline bırakılır; İngilizce kalmış etiket çevrilir. */

/* Zorunluluk işareti — yıldız rengi değil, anlamı taşır.

   OLCULDU 2026-09-12: kural yalniz `.field-label`e bagliydi (20 sayfa), ama
   sayfalarin cogu `.form-label` yaziyor (40 sayfa) — orada yildiz HIC
   basilmiyordu, yani zorunlu alan zorunlu gorunmuyordu. Iki sinif da ayni
   kurala baglandi. */
.field-label[data-required]::after,
.form-label[data-required]::after {
    content: " *";
    color: var(--error);
    font-weight: 700;
}

/* Alan altı yardım metni. `.detail-hint`ten ayrı: o bir kart içi ikincil
   satır, bu bir girdiye BAĞLI açıklama ve girdiyle arasında boşluk taşımaz.

   `.vformfield__helper` ile AYNI DAVRANIŞ. VFormField bileşeni (Label +
   HelperText + Required + otomatik aria-describedby) bu depoda ZATEN VARDI ama
   yalnız 4 dosyada kullanılıyordu — bu sınıflar onu bilmeden ikinci kez icat
   edildi. İki adı ayrı tutmak iki ayrı görünüm üretirdi; aynı kurala bağlandı.
   Yeni sayfalar <VFormField> kullanmalı: markup sınıfı değil, aria bağlantısını
   da kuran bir sözleşme verir. */
.field-help,
.vformfield__helper {
    margin: var(--space-1) 0 0;
    font-size: var(--font-size-2xs);
    line-height: 1.45;
    color: var(--on-surface-variant);
}

/* Odak göstergesi. Taban kural yalnız hayalet kenar veriyordu; açık temada
   --ghost-border %15 opaklıkta ve girdi zeminden ayrışmıyordu. */
.field > input:focus-visible,
.field > select:focus-visible,
.field > textarea:focus-visible,
.form-field > input:focus-visible,
.form-field > select:focus-visible,
.form-field > textarea:focus-visible,
.form-input:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Kart içi bölüm başlığı + açıklaması. Başlık tek başına yönlendirmiyordu:
   "Basic Information" ne beklendiğini söylemiyor. */
.section-intro {
    margin: 0 0 var(--space-4);
    font-size: var(--font-size-md);
    line-height: 1.5;
    color: var(--on-surface-variant);
    max-width: 60ch;
}

/* Form bölümü — kart içinde bir grup alanı ayıran blok. 11 dosyada
   kullanılıyordu ve tanımı yoktu (ölçüldü 2026-09-05), yani gruplar
   birbirinden ayrışmıyor, tek uzun yığın gibi okunuyordu. */
.form-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
}

.form-section + .form-section {
    margin-block-start: var(--space-6);
}

/* ══ TANIMSIZ SINIFLAR KANONİĞE BAĞLANDI ══════════════════════════════════
   ÖLÇÜLDÜ 2026-09-05 (audit-missing-components): dört sınıf toplam 49 dosyada
   kullanılıyordu ve HİÇBİRİNİN CSS tanımı yoktu. Eksik CSS derlemeyi kırmaz,
   test düşürmez — sayfa sessizce stilsiz çıkar. Sınıfları markup'tan silmek 49
   dosyayı düzenlemek demekti; kanonik davranışa bağlamak hepsini tek hamlede
   düzeltir. Aynı örüntü .form-field (39), .form-section (11), .form-label (165)
   ve .card-header (30) için de uygulandı.
   ═══════════════════════════════════════════════════════════════════════ */

/* Sayfa başlığının altındaki eylem şeridi — 33 dosya. */
.page-actions-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-block-end: var(--space-4);
    min-width: 0;
}

/* Kimlik ekranlarının kartı — 6 dosya. Oturum açma yüzeyi dar ve ortalıdır. */
.v-auth-card {
    width: 100%;
    max-width: 28rem;
    margin-inline: auto;
    padding: var(--space-6);
    border-radius: var(--card-radius);
    background: var(--surface-container);
    box-shadow: var(--shadow-md);
}

/* Kimlik ekranı düğmesi — 5 dosya. Kanonik .btn ailesiyle aynı ölçüler. */
.v-auth-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 44px;
    padding: 0.625rem 1.25rem;
    border: none;
    border-radius: var(--btn-radius);
    background: var(--primary);
    color: var(--on-primary);
    font-family: var(--font-label);
    font-size: var(--font-size-md);
    font-weight: 700;
    cursor: pointer;
    transition: background var(--transition-btn);
}

.v-auth-btn:hover { background: var(--primary-dim); }

.v-auth-btn:disabled { opacity: 0.55; cursor: not-allowed; }

.v-auth-btn-danger,
.v-auth-btn.v-danger {
    background: var(--error);
    color: var(--on-error);
}

/* VDatePicker/VTextField girdi kabuğu — 5 dosya. Kanonik girdi ailesiyle
   aynı yükseklik ve yarıçapı taşır ki alanlar yan yana hizalansın. */
.vtextfield {
    width: 100%;
    min-height: 44px;
    border-radius: var(--input-radius);
}

/* ══ DÜĞME BOYUT TABANI ════════════════════════════════════════════════════
   ÖLÇÜLDÜ 2026-09-05 /admin/rules/create: aynı ekranda düğme yükseklikleri
   40px, 44px ve 42px — üç farklı değer. Kurumsal bir arayüzde yan yana duran
   iki düğmenin farklı yükseklikte olması, hizasız bir satır demektir.

   Kök neden: HİÇBİR düğme varyantında min-height yoktu ve dolgular ayrışmıştı
   (btn-primary 1.25rem, btn-ghost 1rem, btn-tertiary 0.75rem). Yükseklik
   metnin ve ikonun boyuna göre kendiliğinden oluşuyordu, yani düğmede ikon
   olup olmaması ölçüyü değiştiriyordu.

   Taban BURADA verilir, varyantlarda değil: varyant RENGİ ve TONU belirler,
   ÖLÇÜYÜ değil. Dikey dolgu kaldırılıp yerine min-height + hizalama konur —
   böylece içerik ne olursa olsun yükseklik sabittir. Yatay dolgu varyantın
   kendi kararı olarak kalır (ghost daha dar durur, bu kasıtlı).

   44px: dokunma hedefi alt sınırı (--touch-target-min). Küçük varyant
   (.btn-sm) 36px'e iner — yoğun araç çubukları için, ama yalnız orada. */
.btn,
.btn-primary,
.btn-secondary,
.btn-tertiary,
.btn-ghost,
.btn-danger,
.btn-outline-secondary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--touch-target-min, 44px);
    padding-block: 0;
    box-sizing: border-box;
    /* SARILAN DÜĞME METNİNDE SATIRLAR YAPIŞMAMALI.
       ÖLÇÜLDÜ 2026-09-06 /business-scenarios: "Seçim Modu" düğmesi iki satıra
       sarılıyor ve 1.2 aralık 11px metinde yalnız 2.2px boşluk bırakıyordu —
       harfler alt satıra değiyor. Boşluk ölçüsü orandan bağımsızdır:
           11px @ 1.20 → 2.2px      11px @ 1.35 → 3.9px
           12px @ 1.20 → 2.4px      12px @ 1.35 → 4.2px
           14px @ 1.20 → 2.8px      14px @ 1.35 → 4.9px
       3px alt sınır (verify-text-readability). Tek satırlık düğmede görünür
       etkisi yok: yükseklik min-height'tan geliyor, dolgu değil.
       BU KURAL KANONİK OLANDIR — aynı değeri veraius-base.css'teki
       .btn-primary/.btn-secondary bloklarına yazmak ETKİSİZDİR, bu gruplu
       kural sonra yüklenip eziyor (ölçüldü ve o deneme geri alındı). */
    line-height: 1.35;
}

/* stylelint-disable-next-line no-duplicate-selectors -- bilinçli katman: arada aynı özgüllükte .btn-* kuralları var; birleştirme dolgu/yazıyı değiştirdi (ölçüldü 2026-10-09: 20px→12px, 13px→14px) */
.btn-sm {
    /* Eski 36px: yoğun araç çubuğu için kasıtlıydı ama VTextField/VSelect
       (44px) ile aynı satırda kardeş kayması üretiyordu. Dokunma hedefi
       kanonuyla hizala — tipografi hâlâ sm kalır. */
    min-height: var(--touch-target-min, 44px);
    padding-block: 0;
}

/* ── TABLO GÖVDE TİPOGRAFİSİ ─────────────────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-05, 25 rotada 28 tablo: 3 farklı görsel imza. Başlık satırı
   her yerde aynıydı (11px/700/uppercase), sapan tek şey GÖVDE yazı boyuydu —
   referans 13px, dört tablo 14px. Kök neden: hiçbir hücre font-size YAZMIYOR,
   değer kalıtımla geliyor; .admin-grid kökünde `font-size: var(--font-size-md)`
   var, tek-kullanımlık sınıflarda (saga-runs-table, conn-table, ra-table,
   sj-table) yok, o yüzden sayfa kabının boyunu miras alıyorlardı.
   Kap değiştiğinde tablo boyu da sessizce değişiyordu.

   Düzeltme kabı değil TABLOYU pinliyor: aynı sınıflar artık kanonik boyu
   açıkça taşıyor. Dolgular zaten doğruydu (14px 16px) — dokunulmadı. */
.saga-runs-table,
.conn-table,
.ra-table,
.sj-table,
.oed-table,
.rf-table,
.aad-table,
.ubd-table,
.akm-table,
.atb-table,
.mcdm-table,
.v-admin-table {
    font-size: var(--font-size-md);
}

/* atb-table hücre dolgusu 48px ölçüldü — referansın üç katı, satırlar aşırı
   yüksek görünüyordu. Kanonik 14px 16px'e çekildi. */
.atb-table tbody td {
    padding: var(--space-3) 16px;
}

/* ── YAPILANDIRMA FORMU ALANLARI ─────────────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-05 /custom-models: "Yeni Model" formunda etiketler alanların
   soluna düşmüş, alanlar 175px (tarayıcı varsayılanı), "Sistem promptu"
   etiketi alanın altında kalmıştı. Tarayıcıda ölçüldü:
       .config-fields  display: block   (grid/flex YOK)
       .config-group   display: block
       eşleşen kural sayısı: 0
   Kök neden: bu dört sınıf HİÇBİR ortak stil sayfasında tanımlı DEĞİLDİ.
   Yalnız iki bileşen onları kendi scoped CSS'inde tanımlamış
   (AgentConfiguration, AgentConfigurator); CustomModelsPage aynı adları
   kullanmış ama kendi scoped CSS'i olmadığı için hiç stil almıyordu —
   ödünç alınan ad, gelmeyen stil. 34 kullanım / 4 dosya, sıfır global tanım.

   Kanonik değerler AgentConfiguration.razor.css'ten alındı (ölçülüp doğru
   göründüğü teyit edildi); scoped kopyalar özgüllük sırasında önde olduğu
   için oradaki davranış DEĞİŞMEZ, yalnız tanımsız kalan sayfalar toparlanır. */
.config-fields {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.config-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.config-input,
.config-textarea {
    background: var(--surface-container-high);
    border: none;
    border-radius: var(--input-radius, var(--btn-radius));
    padding: var(--space-3) var(--space-4);
    color: var(--on-surface);
    font-size: var(--font-size-base);
    font-family: inherit;
    transition: box-shadow var(--transition-btn), background var(--transition-btn);
}

.config-input { max-width: 20rem; width: 100%; }

.config-textarea { width: 100%; resize: vertical; min-height: 8rem; }

/* ── ALAN DÜZEYİ DOĞRULAMA ───────────────────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-06 /admin/rules/create: form BOŞ haliyle kaydedilebiliyordu
   ve hiçbir alan hatası gösterilmiyordu. Doğrulama eklendi; bu da onun görsel
   karşılığı. Hata ALANIN HEMEN ALTINDA durur — kurumsal bir formda kullanıcı
   hangi alanı düzelteceğini sayfanın tepesindeki listeden aramamalı. */
.field-error {
    margin: var(--space-1) 0 0;
    color: var(--tertiary);
    font-size: var(--font-size-2xs);
    line-height: 1.4;
}

/* Geçersiz alan tonal kayma ile işaretlenir — "No-Line" kuralı gereği
   opak kenarlıkla değil (DESIGN.md). */
.form-input.is-invalid,
.config-input.is-invalid,
.config-textarea.is-invalid,
input.is-invalid,
textarea.is-invalid,
select.is-invalid {
    background: color-mix(in srgb, var(--tertiary) 8%, var(--surface-container-high));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tertiary) 45%, transparent);
}

/* ================================================================
   DURUM SOZLESMESI — form ailesi (VOIT DS Text field / Select / Text Area
   matrisinden). OLCULDU 2026-09-12: bu aile 13 sinifla 150+ sayfada
   kullaniliyordu ama yalniz default/focus/disabled tanimliydi.
   HOVER, ACTIVE, ERROR, LOADING, READONLY yoktu — bu yuzden 366 sayfa
   kendi <input> stilini yazdi. Yedi durumun tamami burada, TEK yerde. */

/* ---- HOVER: yuzey bir kademe yukari (VOIT "Hover on Default") ---- */
.form-input:hover:not(:disabled):not([readonly]):not(:focus),
.input-field:hover:not(:disabled):not([readonly]):not(:focus),
.va-input:hover:not(:disabled):not([readonly]):not(:focus),
.field-input:hover:not(:disabled):not([readonly]):not(:focus),
.form-control:hover:not(:disabled):not([readonly]):not(:focus),
.search-input:hover:not(:disabled):not([readonly]):not(:focus),
.filter-select:hover:not(:disabled):not([readonly]):not(:focus),
.form-select:hover:not(:disabled):not([readonly]):not(:focus),
.input-sm:hover:not(:disabled):not([readonly]):not(:focus),
.input-inline:hover:not(:disabled):not([readonly]):not(:focus),
.ace-input:hover:not(:disabled):not([readonly]):not(:focus),
.rsm-input:hover:not(:disabled):not([readonly]):not(:focus),
.field-sm:hover:not(:disabled):not([readonly]):not(:focus),
.form-input-alt:hover:not(:disabled):not([readonly]):not(:focus),
.vtextfield:hover:not(:disabled):not([readonly]):not(:focus) {
    background: var(--surface-container-high);
}

/* ---- ACTIVE: basili hissi ---- */
.form-input:active:not(:disabled):not([readonly]),
.input-field:active:not(:disabled):not([readonly]),
.va-input:active:not(:disabled):not([readonly]),
.field-input:active:not(:disabled):not([readonly]),
.form-control:active:not(:disabled):not([readonly]),
.search-input:active:not(:disabled):not([readonly]),
.filter-select:active:not(:disabled):not([readonly]),
.form-select:active:not(:disabled):not([readonly]),
.input-sm:active:not(:disabled):not([readonly]),
.input-inline:active:not(:disabled):not([readonly]),
.ace-input:active:not(:disabled):not([readonly]),
.rsm-input:active:not(:disabled):not([readonly]),
.field-sm:active:not(:disabled):not([readonly]),
.form-input-alt:active:not(:disabled):not([readonly]),
.vtextfield:active:not(:disabled):not([readonly]) {
    background: var(--surface-container);
}

/* ---- FILLED: deger var — placeholder tonundan tam murekkebe
       (VOIT matrisinde "Filled" ayri satir; :placeholder-shown tersi) ---- */
.form-input:not(:placeholder-shown),
.input-field:not(:placeholder-shown),
.va-input:not(:placeholder-shown),
.field-input:not(:placeholder-shown),
.form-control:not(:placeholder-shown),
.search-input:not(:placeholder-shown),
.filter-select:not(:placeholder-shown),
.form-select:not(:placeholder-shown),
.input-sm:not(:placeholder-shown),
.input-inline:not(:placeholder-shown),
.ace-input:not(:placeholder-shown),
.rsm-input:not(:placeholder-shown),
.field-sm:not(:placeholder-shown),
.form-input-alt:not(:placeholder-shown),
.vtextfield:not(:placeholder-shown) {
    color: var(--on-surface);
}

/* ---- ERROR: renk TEK BASINA anlam tasimaz (WCAG 1.4.1) —
       zemin + kenarlik + metin birlikte degisir ---- */
.form-input[aria-invalid="true"],
.input-field[aria-invalid="true"],
.va-input[aria-invalid="true"],
.field-input[aria-invalid="true"],
.form-control[aria-invalid="true"],
.search-input[aria-invalid="true"],
.filter-select[aria-invalid="true"],
.form-select[aria-invalid="true"],
.input-sm[aria-invalid="true"],
.input-inline[aria-invalid="true"],
.ace-input[aria-invalid="true"],
.rsm-input[aria-invalid="true"],
.field-sm[aria-invalid="true"],
.form-input-alt[aria-invalid="true"],
.vtextfield[aria-invalid="true"],
.form-input.is-error,
.input-field.is-error,
.va-input.is-error,
.field-input.is-error,
.form-control.is-error,
.search-input.is-error,
.filter-select.is-error,
.form-select.is-error,
.input-sm.is-error,
.input-inline.is-error,
.ace-input.is-error,
.rsm-input.is-error,
.field-sm.is-error,
.form-input-alt.is-error,
.vtextfield.is-error {
    background: var(--state-error-bg);
    color: var(--state-error-text);
    box-shadow: inset 0 0 0 1px var(--state-error-border);
}
.form-input[aria-invalid="true"]:focus,
.input-field[aria-invalid="true"]:focus,
.va-input[aria-invalid="true"]:focus,
.field-input[aria-invalid="true"]:focus,
.form-control[aria-invalid="true"]:focus,
.search-input[aria-invalid="true"]:focus,
.filter-select[aria-invalid="true"]:focus,
.form-select[aria-invalid="true"]:focus,
.input-sm[aria-invalid="true"]:focus,
.input-inline[aria-invalid="true"]:focus,
.ace-input[aria-invalid="true"]:focus,
.rsm-input[aria-invalid="true"]:focus,
.field-sm[aria-invalid="true"]:focus,
.form-input-alt[aria-invalid="true"]:focus,
.vtextfield[aria-invalid="true"]:focus,
.form-input[aria-invalid="true"]:focus-visible,
.input-field[aria-invalid="true"]:focus-visible,
.va-input[aria-invalid="true"]:focus-visible,
.field-input[aria-invalid="true"]:focus-visible,
.form-control[aria-invalid="true"]:focus-visible,
.search-input[aria-invalid="true"]:focus-visible,
.filter-select[aria-invalid="true"]:focus-visible,
.form-select[aria-invalid="true"]:focus-visible,
.input-sm[aria-invalid="true"]:focus-visible,
.input-inline[aria-invalid="true"]:focus-visible,
.ace-input[aria-invalid="true"]:focus-visible,
.rsm-input[aria-invalid="true"]:focus-visible,
.field-sm[aria-invalid="true"]:focus-visible,
.form-input-alt[aria-invalid="true"]:focus-visible,
.vtextfield[aria-invalid="true"]:focus-visible {
    box-shadow:
        inset 0 0 0 1px var(--state-error),
        0 0 0 3px color-mix(in srgb, var(--state-error) 18%, transparent);
}

/* ---- READONLY: okunur ama degistirilemez. DISABLED'DAN FARKLI:
       solgunlasmaz (icerik hala onemli), yalniz duz yuzey + text imleci ---- */
.form-input[readonly],
.input-field[readonly],
.va-input[readonly],
.field-input[readonly],
.form-control[readonly],
.search-input[readonly],
.filter-select[readonly],
.form-select[readonly],
.input-sm[readonly],
.input-inline[readonly],
.ace-input[readonly],
.rsm-input[readonly],
.field-sm[readonly],
.form-input-alt[readonly],
.vtextfield[readonly] {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--outline-variant);
    cursor: text;
}

/* ---- LOADING: sag tarafta spinner; icerik GORUNUR kalir.
       Sarmalayiciya .is-loading verilir, input'a degil. ---- */
.is-loading > :where(.form-input, .input-field, .va-input, .field-input, .form-control, .search-input, .filter-select, .form-select, .input-sm, .input-inline, .ace-input, .rsm-input, .field-sm,
.form-input-alt,
.vtextfield) {
    padding-inline-end: 2.5rem;
}
.is-loading::after {
    content: "";
    position: absolute;
    inset-inline-end: var(--space-3);
    inset-block-start: 50%;
    width: var(--loading-size-sm);
    height: var(--loading-size-sm);
    margin-block-start: calc(var(--loading-size-sm) / -2);
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0%,
        color-mix(in srgb, var(--primary) 25%, transparent) 45%, var(--primary) 100%);
    /* stylelint-disable color-no-hex -- mask: siyah/beyaz renk değil, alfa kanalıdır */
    mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    /* stylelint-enable color-no-hex */
    animation: spin var(--loading-spin) linear infinite;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .is-loading::after { animation: none; }
}

/* OLCULDU 2026-09-12: VTextField/VTextArea/VNumberInput hata durumunda
   'vtextfield--error' basiyordu ama bu sinifin HIC CSS'i yoktu — uc
   bilesende de hata GORUNMUYORDU. aria-invalid ile ayni davranis. */
.vtextfield--error,
.form-input-alt.vtextfield--error {
    background: var(--state-error-bg);
    color: var(--state-error-text);
    box-shadow: inset 0 0 0 1px var(--state-error-border);
}
.vtextfield--error:focus,
.vtextfield--error:focus-visible {
    box-shadow:
        inset 0 0 0 1px var(--state-error),
        0 0 0 3px color-mix(in srgb, var(--state-error) 18%, transparent);
}

/* ================================================================
   DURUM SOZLESMESI — buton ailesi (VOIT DS Button matrisinden).
   OLCULDU 2026-09-12: VaButton 644 sayfada kullaniliyor ama
   varyantlarin durum kapsami 0-3/5 arasindaydi:
     · HICBIR varyantta loading yoktu
     · active neredeyse hic yoktu (7 varyantta 2)
     · btn-link ve btn-icon-only 0/5 — hicbir durum
   Eksikler burada, TEK yerde tamamlandi. */

/* ---- ACTIVE: basili hissi. Tum varyantlarda AYNI jest —
       yuzey degil OLCEK degisir, boylece her varyantta calisir. ---- */
.btn:active:not(:disabled):not([aria-disabled="true"]),
.btn-primary:active:not(:disabled):not([aria-disabled="true"]),
.btn-secondary:active:not(:disabled):not([aria-disabled="true"]),
.btn-tertiary:active:not(:disabled):not([aria-disabled="true"]),
.btn-ghost:active:not(:disabled):not([aria-disabled="true"]),
.btn-danger:active:not(:disabled):not([aria-disabled="true"]),
.btn-icon-only:active:not(:disabled):not([aria-disabled="true"]) {
    transform: scale(0.97);
}

/* ---- FOCUS: klavye kullanicisi icin ZORUNLU (WCAG 2.4.7).
       btn-danger, btn-tertiary, btn-link ve btn-icon-only'de YOKTU. ---- */
.btn-tertiary:focus-visible,
.btn-danger:focus-visible,
.btn-link:focus-visible,
.btn-icon-only:focus-visible,
.btn-sm:focus-visible,
.btn-lg:focus-visible {
    outline: var(--state-focus-ring);
    outline-offset: var(--state-focus-offset);
}

/* ---- btn-link: metin baglantisi gibi davranir ama BUTON'dur.
       Alt cizgi hover'da gelir; renk aksandan. ---- */
.btn-link {
    background: transparent;
    color: var(--primary);
    padding-inline: 0;
    text-decoration: none;
}
.btn-link:hover:not(:disabled) { text-decoration: underline; color: var(--primary-dim, var(--primary)); }
.btn-link:active:not(:disabled) { opacity: 0.8; }

/* ---- btn-icon-only: kare hedef, kanonik ikon olceginden.
       Etiketi YOK — aria-label zorunlu, boyut WCAG hedefini tutmali. ---- */
.btn-icon-only {
    inline-size: var(--icon-shell-md);
    block-size: var(--icon-shell-md);
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.btn-icon-only .material-symbols-outlined { font-size: var(--icon-md); }
.btn-icon-only:hover:not(:disabled) { background: var(--surface-container-high); }

/* ---- btn-lg: buyuk boyut; btn-sm vardi, btn-lg YOKTU ---- */
.btn-lg {
    min-block-size: 3.25rem;
    padding: 0.75rem 1.5rem;
    font-size: var(--font-size-lg);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    border-radius: var(--btn-radius);
    cursor: pointer;
    transition: background var(--transition-btn), transform var(--transition-btn);
}

/* ---- LOADING: hicbir varyantta yoktu.
       Etiket GORUNMEZ olur ama yer tutar — buton genisligi degismez,
       yoksa yanindaki butonlar ziplar. Spinner ustune biner. ---- */
.btn.is-loading,
.btn-primary.is-loading,
.btn-secondary.is-loading,
.btn-tertiary.is-loading,
.btn-ghost.is-loading,
.btn-danger.is-loading,
.btn-sm.is-loading,
.btn-lg.is-loading {
    position: relative;
    pointer-events: none;
    cursor: progress;
}
.btn.is-loading > *,
.btn-primary.is-loading > *,
.btn-secondary.is-loading > *,
.btn-tertiary.is-loading > *,
.btn-ghost.is-loading > *,
.btn-danger.is-loading > *,
.btn-sm.is-loading > *,
.btn-lg.is-loading > * {
    visibility: hidden;
}
.btn.is-loading::after,
.btn-primary.is-loading::after,
.btn-secondary.is-loading::after,
.btn-tertiary.is-loading::after,
.btn-ghost.is-loading::after,
.btn-danger.is-loading::after,
.btn-sm.is-loading::after,
.btn-lg.is-loading::after {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    inline-size: var(--loading-size-sm);
    block-size: var(--loading-size-sm);
    margin-block-start: calc(var(--loading-size-sm) / -2);
    margin-inline-start: calc(var(--loading-size-sm) / -2);
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0%,
        color-mix(in srgb, currentColor 25%, transparent) 45%, currentColor 100%);
    /* stylelint-disable color-no-hex -- mask: siyah/beyaz renk değil, alfa kanalıdır */
    mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
    /* stylelint-enable color-no-hex */
    animation: spin var(--loading-spin) linear infinite;
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    .btn:active, .btn-primary:active, .btn-secondary:active,
    .btn-tertiary:active, .btn-ghost:active, .btn-danger:active,
    .btn-icon-only:active { transform: none; }
    .btn.is-loading::after, .btn-primary.is-loading::after,
    .btn-secondary.is-loading::after, .btn-ghost.is-loading::after,
    .btn-danger.is-loading::after { animation: none; }
}

/* ============================================================================
   KPI ŞERİDİ — Architectural Monolith kart anatomisi (kit k18/k20)

   TodayPage'in scoped CSS'inden BURAYA taşındı 2026-09-14: Ana Sayfa da aynı
   şeridi basıyor ve Blazor scoped CSS yalnız tanımlayan bileşenin ağacını
   etiketler — kural orada kalsaydı Home'da HİÇ eşleşmezdi (bu deponun
   tekrarlayan kusuru: sınıf basılır, stil hiç uygulanmaz).

   İki karşılama ekranı aynı dili konuşur: kullanıcı Bugün'den Ana Sayfa'ya
   geçince kutucuğu yeniden öğrenmez.

   Anatomi: etiket + durum çipi / değer + birim / nokta + neden.
   Çip SÖZCÜK taşır — renk tek sinyal değildir (WCAG 1.4.1).
   ============================================================================ */
/* --- KPI şeridi — Architectural Monolith kart anatomisi (kit k18/k20) ---
   DÖRT kutucuk. ÖLÇÜLDÜ 2026-09-13: yedi kutucukla 1920px'de etiketler
   KIRPILIYORDU — "Okunmamış Bildirim" 132px metin, 116px kutu. Şerit
   "bakışla oku" bandıdır; kırpılmış etiket okunamaz.

   minmax(17rem, 1fr): en uzun etiket ("Kalan onboarding adımı") kırpılmadan
   sığar. auto-fit ile 1920'de dört sütun, dar ekranda kendiliğinden azalır. */
.va-kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: var(--space-4, 1rem);
    align-items: stretch;
}

/* min-height 97px — kit k10'un SM kart ölçüsü (257×97). */
/* KUTUCUK BEYAZ. VCard varsayılanı --surface-container (#eeeeee) veriyor ama o
   artık sayfa zemini seviyesi — kutucuk zeminle aynı renk kalıyordu.
   k24 referansında ölçülen: KPI kutucuğu #FFFFFF, zemin #EEEEEE.

   ÇİFT SINIF ŞART. `.va-kpi` tek başına kaybediyordu: VCard'ın kuralı
   `.vcard--default[b-5htel0mplu]` biçiminde SCOPED yazılıyor ve öznitelik
   seçicisi özgüllüğü (0,2,0) yapıyor — düz sınıf (0,1,0) altta kalır.
   `.va-kpi.va-kpi` özgüllüğü (0,2,0)'a çıkarır ve sonra geldiği için kazanır;
   !important gerekmez. ÖLÇÜLDÜ 2026-09-14: tek sınıfla kutucuk #eeeeee
   kalıyordu. */
.va-kpi.va-kpi {
    background: var(--surface-container-lowest);
}

/* AKSAN ŞERİDİ `.kpi-card` ile ORTAK. ÖLÇÜLDÜ 2026-09-16: iki KPI anatomisi
   yan yana yaşıyordu — `.kpi-card` soldan 3px teal şerit taşırken (35 kartın
   31'i), `/today`'in `VCard Class="va-kpi"` kutucukları şeritsizdi. İkisi de
   aynı işi yapan KPI kutucuğu; kurallar TEK yerde yazıldı ki ayrışamasınlar.
   `position: relative` + `overflow: hidden` şart: şerit mutlak konumlu ve
   kartın yuvarlak köşesinden taşmamalı. */
.va-kpi {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--space-1, 0.25rem);
    padding: var(--space-4, 1rem);
    min-height: 97px;
    min-width: 0;
}

.va-kpi__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2, 0.5rem);
    min-width: 0;
}

/* Etiket KIRPILMAZ: şeridin tek işi okunmak. Uzun bir çeviri gelirse
   (Türkçe/Almanca %40 daha uzun olabilir) satır kaydırır, üç nokta koymaz. */

/* Çip SÖZCÜK taşır — renk tek sinyal değildir (WCAG 1.4.1). */
.va-kpi__chip {
    flex: 0 0 auto;
    padding: 0.125rem 0.375rem;
    border-radius: var(--btn-radius);
    font-family: var(--font-label);
    font-weight: 700;
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    font-size: var(--font-size-2xs);
    letter-spacing: normal;
    text-transform: none;
}

.va-kpi__chip--ok {
    background: var(--state-success-bg);
    color: var(--state-success-text-on-fill);
}

.va-kpi__chip--alert {
    background: var(--state-error-bg);
    color: var(--state-error-text-on-fill);
}

.va-kpi__value {
    display: flex;
    align-items: baseline;
    gap: var(--space-2, 0.5rem);
    min-width: 0;
}

/* tabular-nums: sayaç güncellenirken rakam genişliği değişip satırı oynatmasın. */

/* Aciliyet RENKLE anlatılır, yüzeyle değil — aynı rol aynı yüzey kademesinde. */
.va-kpi__n.is-urgent { color: var(--state-error-text); }

/* Birim sayının İÇİNDE değil yanında: "44 onay", "6 / 7 sağlıklı". */
.va-kpi__unit {
    font-size: var(--font-size-2xs);
    color: var(--on-surface-variant);
}

/* Durum satırı: nokta + NEDEN. Sayıyı eyleme çeviren cümle burada. */
.va-kpi__foot {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--font-size-2xs);
    color: var(--on-surface-variant);
    min-width: 0;
}

.va-kpi__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex: 0 0 auto;
}

.va-kpi__dot--ok { background: var(--state-success); }
.va-kpi__dot--alert { background: var(--state-error); }

/* İlerleme çubuğu — k21 KPI kutucuklarında değerin altında ince bir bant.
   Sayının yanında GÖRSEL bir oran verir: %95,13 rakamı tek başına "iyi mi
   kötü mü" demiyor, çubuk onu bir ölçeğe oturtuyor.
   aria-hidden: bilgi zaten değer + durum satırında yazılı; ekran okuyucuya
   üçüncü kez okutmak gürültü olur. */
.va-kpi__meter {
    display: block;
    height: 3px;
    border-radius: 2px;
    background: var(--surface-container-highest);
    overflow: hidden;
    margin: var(--space-1, 0.25rem) 0;
}

.va-kpi__meter-fill {
    display: block;
    height: 100%;
    background: var(--primary);
    transition: width var(--transition-card, 150ms ease);
}

.va-kpi__meter-fill--alert { background: var(--state-error); }

@media (prefers-reduced-motion: reduce) {
    .va-kpi__meter-fill { transition: none; }
}

/* KPI ikon karesi — k24'te her kutucuğun solunda durum rengiyle boyalı bir
   kare var (ölçüldü 2026-09-14, ikon karesi zemin pikselleri):
     kritik #FEF2F2 · uyarı #FFF7ED · iyi #F0FDFA · nötr #F8F9FA
   Bende kutucuklar tamamen griydi; sayfa renksiz görünüyordu.
   Tint METİN ZEMİNİ DEĞİL, durum işaretidir — ikon rengi --state-*-text'ten
   gelir ve kontrastı orada ölçülür. */
/* ÇİFT SINIF: VCard'ın scoped kuralları (0,2,0) düz sınıfı (0,1,0) yener —
   aynı tuzağa .va-kpi'de de düşülmüştü (ölçüldü 2026-09-14: tint zemini
   rgba(0,0,0,0) geliyordu). */
.va-kpi__icon.va-kpi__icon {
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2.5rem;
    display: grid;
    place-items: center;
    border-radius: var(--control-radius, 0.625rem);
    background: var(--tint-neutral);
    color: var(--on-surface-variant);
}

.va-kpi__icon.va-kpi__icon--ok       { background: var(--tint-ok);       color: var(--brand-teal-text, var(--primary)); }
.va-kpi__icon.va-kpi__icon--warning  { background: var(--tint-warning);  color: var(--state-warning-text, var(--state-warning)); }
.va-kpi__icon.va-kpi__icon--critical { background: var(--tint-critical); color: var(--state-error-text, var(--state-error)); }

/* İkon kare gelince kutucuk yatay düzene geçer: kare solda, içerik sağda. */
.va-kpi:has(.va-kpi__icon) {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    column-gap: var(--space-3, 0.75rem);
    align-items: center;
}

/* ============================================================
   KART DÜZLEMİ — tek kanonik kural (kit 27, 2026-09-14)

   ÖLÇÜLDÜ: uygulamada 407 "kart" kuralı kendi zeminini elle yazıyor ve
   çoğu YANLIŞ basamağı seçiyordu:

     --surface-container       228   (#EEEEEE — sayfa ZEMİNİYLE aynı aile)
     --surface-container-high  134   (#E8E8E8 — KUYU tonu)
     --surface-container-low    27
     --surface-container-highest 9
     --surface-container-lowest  6   ← doğru olan, yalnız 6 kullanım

   Sonuç kullanıcının bildirdiği şeydi: "sayfalar birbirinden farklı
   gözüküyor". /today'de kartlar beyaz kabartma, /agents/catalog'da aynı
   kart düz gri bir blok — çünkü zeminle aynı tonu basıyordu.

   Kit 27 sözleşmesi: "Surface plane defaults to surface-container-lowest
   (#FFFFFF) sitting upon #EEEEEE." Kartın zeminden AYRI bir düzlem olması
   "No-Line" kuralının taşıyıcısıdır: ayrımı kenarlık değil düzlem kayması
   yapar, iki yüzey eşitse kart görünmez olur.

   Kapsam DAR tutuldu, üç sebeple:
   1) Yalnız `.app-content` İÇİ — kabuk (sidebar, üst bar, bildirim paneli)
      kendi tonal dilini korur.
   2) Kart sınıfı listenin SONUNDA olmak zorunda değil: `[class$="card"]`
      tek başına `"agent-gallery-card hover-lift"` gibi bir listeyi KAÇIRIR —
      öznitelik "hover-lift" ile biter. ÖLÇÜLDÜ 2026-09-14 /agents/registry:
      419 kartın 26'sı bu yüzden #F4F3F3 kalmıştı. `[class*="card "]` (sondaki
      BOŞLUK anlamlı) kart sınıfını listenin ortasında da yakalar.
      Yalnız adı `card` ile biten sınıflar — `*-card-header`, `*-card-body`,
      `*-cards` (ızgara kabı) ve `card-well` gibi iç/kap öğeler DIŞARIDA
      kalır; onlar kartın İÇİNDEki şeritlerdir ve kendi tonlarını taşır.
   3) Özgüllük: `.app-content` + öznitelik seçici = (0,2,0). Bu, bileşenin
      kendi tek-sınıf kuralını (0,1,0) KAZANIR — kasıtlı. İlk deneme
      `:where()` ile yazılmıştı (özgüllük 0) ve ÖLÇÜLDÜ: 36 kartın hiçbiri
      değişmedi, çünkü her biri kendi `background`'unu yazıyor ve 0'ı yener.
      Özgüllük 0 olan bir "taban", zemin yazan bir bileşen için ulaşılamaz.

      Bilinçli farklılık isteyen bileşen iki sınıf ya da scoped CSS
      kullanarak hâlâ kazanır; aşağıdaki `:not()` listesi de kuyu/terminal
      gibi ÇIKARIMSAL yüzeyleri baştan dışarıda tutar.
   ============================================================ */
/* ── Ajan alt sayfa hizli-gezinme seridi ────────────────────────────────────
   ÖLÇÜLDÜ 2026-09-15. Bu sekmeler `/agents/*` alt sayfalarinin TAMAMINDA
   ciziliyor ve ekranda DUZ METIN gibi goruniyordu — padding 0, zemin seffaf,
   aktif sekme isaretsiz.

   Kurallar `AgentsSubpageShell.razor.css` icinde `.agents-subpage-shell ::deep`
   ile yazilmisti ve yanindaki yorum "::deep pierces into the NavLink" diyordu.
   Tarayicida olculdu: link elemaninin kapsam ozniteligi listesi **BOS** —
   `NavLink` bir BILESEN ve kok elemani sarmalayan bilesenin `b-xxxxx`
   ozniteligini TASIMAZ. `::deep` de `[b-xxxxx] .secici` uretir, yani yine ayni
   oznitelige dayanir; komsu bilesenin KENDI kok elemanina ULASMAZ.
   Dort kural da oluydu (bkz. "Scoped CSS BASKA bilesenin kok elemanina
   ULASMAZ" maddesi). Kanonik tanim paylasilan katmandadir. */
.agents-hub-quick-link {
    display: inline-flex;
    align-items: center;
    padding: var(--space-2) var(--space-4);
    font-family: var(--font-label);
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    border-radius: var(--btn-radius);
    color: var(--on-surface-variant);
    background: var(--surface-container-low);
    transition: color var(--transition-btn), background var(--transition-btn);
}

.agents-hub-quick-link:hover {
    color: var(--on-surface);
    background: var(--surface-container);
}

/* Aktif sekme: ana sidebar ile AYNI dil — soldan saga sonen tonal degrade.
   (bkz. "Ikincil gezinme, ANA gezinmeyle ayni dili konusmali") */
.agents-hub-quick-link-active {
    color: color-mix(in srgb, var(--primary) 90%, var(--on-surface));
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--primary) 20%, transparent),
        color-mix(in srgb, var(--primary) 9%, transparent) 70%,
        transparent
    );
    box-shadow: inset 0 -2px 0 0 var(--primary);
}

/* ── Bölüm panosu (AgentsSectionBoard) — NavLink'e aynı sebeple taşındı ───────
   ÖLÇÜLDÜ 2026-09-19. Aynı ders, aynı klasörde ikinci kez: `.asb-link*`
   kuralları `AgentsSectionBoard.razor.css` içinde scoped yazılmıştı ve
   NavLink'in kök elemanı sayfanın kapsam özniteliğini TAŞIMADIĞI için hiçbiri
   eşleşmiyordu. `.agents-hub-quick-link` emsalinin AYNI deseni. */
.asb-link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0.4rem var(--space-3);
    border-radius: var(--btn-radius);
    text-decoration: none;
    color: var(--on-surface-variant);
    /* WCAG 2.5.8: tiklanabilir her sey en az 24x24. */
    min-height: 30px;
    transition: background var(--transition-btn), color var(--transition-btn);
}

.asb-link-ico {
    font-size: var(--icon-sm);
    color: var(--outline-variant);
    flex: 0 0 auto;
}

.asb-link-t {
    font-size: var(--font-size-sm);
    font-weight: 600;
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.asb-link:hover {
    background: var(--surface-container-low);
    color: var(--on-surface);
}

.asb-link:hover .asb-link-ico { color: var(--primary); }

.asb-link:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
}

.asb-link-active {
    background: color-mix(in srgb, var(--primary) 11%, transparent);
    color: var(--primary);
    box-shadow: inset 3px 0 0 var(--primary);
}

.asb-link-active .asb-link-t { font-weight: 800; }
.asb-link-active .asb-link-ico { color: var(--primary); }

/* ── KPI kutucuklari: sayfaya OZGU adlarin kanonik anatomiye hizalanmasi ──────
   ÖLÇÜLDÜ 2026-09-15. Kullanici "bizim kartlarimiz yok" dedi; olcum nedenini
   gosterdi: **95 dosya / 69 rotali sayfa** kanonik `StatCard`/`.stat-card`
   YERINE kendi KPI sinifini yaziyordu — `rsm-kpi`, `ops-stat`, `va-kpi` gibi
   **86 ayri ad**. Sapma kozmetik degil, anatomik:

     zemin   : 5 ayri ton  (34 kez `--surface-container` = SAYFA ZEMINI;
                            dogru olan `-lowest` yalniz 1 kez)
     yaricap : 2 ayri deger (`panel-radius` 18, `card-radius` 11)
     padding : **19 ayri deger**

   Yani kart, zeminden ayrilmiyordu ("No-Line" kuralinda duzlem kaymasi ayrimi
   tasir) ve her ekran kendi olcusunu uyduruyordu.

   86 adi tek tek listelemek kirilgan olur; desen tabanli kural kullanilir.
   Sonek `-kpi` / `-stat` olan KUTU siniflari hedeflenir; `-label`, `-value`,
   `-icon`, `-row`, `-grid` gibi IC parcalar ve `-card` zaten taban kuralda
   oldugu icin DISARIDA birakilir. Ozgullugu `.app-content` tasir (0,2,0) —
   sayfa scoped CSS'i (`[b-xxxxx]` ile 0,2,0) padding/duzen varyantini hala
   yazabilir; burada yalniz DUZLEM tanimlanir. */
/* ÖLÇÜLDÜ 2026-09-15: ilk surum `:not([class*="-stat-"])` ile varyant sonekli
   kartlari da eliyordu — `ops-stat ops-stat-ok` #EEEEEE, `v-stat v-stat--neutral`
   seffaf kaliyordu. Varyant (durum rengi) kartin KENDISIDIR; elenmesi gereken
   yalniz IC PARCALARdir (`-kpi-label`, `-stat-value`, `-kpi-row` ...).
   Bu yuzden eleme, sinif ADININ `-kpi`/`-stat` ile BITMESI kosuluna cekildi:
   `[class*="-kpi "]` zaten "ad bitti, baska sinif geliyor" demektir. */
.app-content :is([class$="-kpi"], [class*="-kpi "], [class$="-stat"], [class*="-stat "]) {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    /* GOLGE YOK — kit 27 "Ground State (Cards): No shadow". */
    box-shadow: none;
}

.app-content :is([class$="card"], [class*="card "]):not([class*="card-"]):not([class*="well"]):not([class*="terminal"]):not([class*="code"]) {
    background: var(--surface-container-lowest);
    /* GÖLGE YOK — kit 27, "Elevation & Depth": "Ground State (Cards,
       Modules): No shadow. Edges are pure value shifts."

       ÖLÇÜLDÜ 2026-09-14: KAYNAK dosyalarda 112 kart kuralı kendi gölgesini
       yazıyordu (`--shadow-md`, `--shadow-lg`, elle yazılmış rgba'lar) ve
       ~60 dosyaya yayılmıştı. Sonuç: aynı ekranda bazı kartlar havada
       yüzüyor, bazıları düz duruyordu — kullanıcının bildirdiği tutarsızlık.

       Tek tek düzeltmek yerine taban kural gölgeyi de sıfırlar. Gerçekten
       yükselmesi gereken yüzeyler (açılır menü, modal, sürüklenen kart)
       zaten `.app-content` dışında ya da kendi `--elevated`/`--overlay`
       varyantını taşıyor; hover'da yükselme aşağıdaki kuralda. */
    box-shadow: none;
}

/* BOYUT SONEKLI kart adlari. Yukaridaki `[class$="card"]` bunlari KACIRIR
   cunku ad `card` ile bitmiyor (`stat-card-lg`, `bento-card-wide`...).
   ÖLÇÜLDÜ 2026-09-14 /ai-strategy/readiness: 4 kartin 2'si #E8E8E8 (KUYU
   tonu) basiyordu, digerleri beyazdi. Envanter kucuk (4 ad), o yuzden
   deseni genisletmek yerine tek tek hedefleniyor — `card-` ile baslayan
   ic parcalari (card-header/body) yanlislikla yakalamamak icin. */
.app-content [class*="card-lg"],
.app-content [class*="card-sm"],
.app-content [class*="card-md"],
.app-content [class*="card-wide"],
.app-content [class*="card-full"],
.app-content [class*="card-compact"] {
    background: var(--surface-container-lowest);
    box-shadow: none;
}

/* Yükselme YALNIZ etkileşimde — kit'in "Raised Interactive State" değeri. */
.app-content :is([class$="card"], [class*="card "]):not([class*="card-"]):not([class*="well"]):not([class*="terminal"]):not([class*="code"]):hover {
    box-shadow:
        0 12px 32px -4px rgba(var(--overlay-scrim-rgb), 0.06),
        0 4px 12px -2px rgba(var(--overlay-scrim-rgb), 0.04);
}


/* ── Ust bar sistem durumu gostergesi ──────────────────────────────────
   SystemStatusIndicator bileseninde render edilir; scoped CSS oraya
   ulasmadigi icin (kapsam ozniteligi yok) stiller BURADA yasar. */
/* (tasindi) 
   Kurumsal ust barin standart "sistem saglikli mi" sinyali. Veri gercek
   saglik yoklamalarindan gelir; kayit yoksa bilesen HIC render edilmez
   (bkz. SystemStatusIndicator.razor) — yesil nokta gostermek "olcum yok"u
   "her sey yolunda" diye okurdu.

   Renk TEK sinyal degil: durum sozcugu title + aria-label'da (WCAG 1.4.1). */

.topbar-status:hover {
    background: color-mix(in srgb, var(--on-surface) 10%, transparent);
}

.topbar-status:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* NOKTA yerine IKON (karar 2026-09-14). Duz bir nokta + metin, seritteki
   ikon tasiyan diger kontrollerin yaninda madde imi gibi okunuyordu.
   Ikon durumu TEK BASINA tasir; renk yalnizca pekistirir. */
/* ::deep SART: VIcon AYRI bir bilesen, scoped CSS ::deep olmadan alt
   bilesene INMEZ ve kural hic eslesmez. ÖLÇÜLDÜ 2026-09-14: kural yazildi,
   token dogruydu (#15803d) ama ikon rgb(26,28,28) kaliyordu. Ayni tuzak
   breadcrumb kuralinda da bir kez olculmustu. */
/* RENK DUGMEDEN MIRAS ALINIR — ikona DOGRUDAN kural yazilamaz.
   ÖLÇÜLDÜ 2026-09-14: ikon eleman uzerinde `b-xxxxx` kapsam ozniteligi YOK
   (yalnizca class + aria-hidden), dolayisiyla `::deep` de eslesmez: o,
   `[b-topbar] .secici` seklinde derlenir ve kapsamsiz elemani bulamaz.
   Tarayicida olculdu: ikonla eslesen HICBIR renk kurali yoktu, deger
   miras yoluyla rgb(26,28,28) geliyordu.

   Cozum: rengi BUTONA ver, ikon miras alsin. Metin kendi rengini
   `.topbar-status__text` ile geri alir. */
.topbar-status {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 28px;
    padding: 0 var(--space-2);
    border: none;
    border-radius: var(--chip-radius);
    background: color-mix(in srgb, var(--on-surface) 5%, transparent);
    font: inherit;
    font-size: var(--font-size-2xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    align-self: center;
    transition: background var(--transition-btn);
    color: var(--state-success-text, var(--primary));
}
.topbar-status--warn { color: var(--state-warning-text, var(--tertiary)); }
.topbar-status--down { color: var(--state-error-text, var(--error)); }

.topbar-status__icon { flex: none; font-variation-settings: 'FILL' 1; }

/* Sayi/sozcuk notr kalir: renk DURUMU ikon tasir, metin okunabilirligi korur. */
.topbar-status__text { color: var(--on-surface-variant); }
@media (max-width: 1200px) {
    .topbar-status__text { display: none; }
    .topbar-status { padding-inline: var(--space-1); }
}

/* --- Sayfa bileşenlerine geçen ExtraClass/class kuralları ---------------
   Bu sınıflar alt bileşenlerin KÖK elemanına iner; sayfa scoped CSS'i
   (::deep dahil) oraya ULAŞAMAZ, bu yüzden paylaşılan katmanda dururlar. */

/* /admin/rules/manage — arama alanı araç şeridini doldurur. */
.rule-search { flex: 1 1 220px; min-width: 0; }

/* /ai-strategy/admin/data — JSON düzenleyici gövdesi. */
.json-editor {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    background: var(--surface-container-high);
    white-space: pre;
    overflow-x: auto;
}

/* --- Sayfalarda kullanılıp hiçbir yerde TANIMLI OLMAYAN yardımcılar ------
   ÖLÇÜLDÜ: aşağıdaki sınıflar 25 sayfanın markup'ında geçiyordu ama hiçbir
   CSS'te karşılığı yoktu — yani düz, stilsiz öğe olarak render oluyorlardı.
   Tek tek sayfa CSS'ine yazmak yerine ortak katmanda dururlar: hepsi
   sayfaya özgü değil, tekrar eden düzen/atom kalıpları. */

/* Tanım listesi: etiket/değer çiftleri iki sütunda hizalanır. */
.va-dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem 0.75rem;
    align-items: baseline;
    margin: 0;
}
.va-dl dt { font-weight: 600; color: var(--on-surface-variant); }
.va-dl dd { margin: 0; color: var(--on-surface); overflow-wrap: anywhere; }

/* Madde listesi: kendi imleci, sayfa ritmini bozmayan boşluk. */
.va-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin: 0;
    padding-inline-start: 1.25rem;
    list-style: disc;
}

/* Gövde metni içindeki bağlantı — renk TEK sinyal değil, altı çizili. */
.va-link {
    color: var(--primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.va-link:hover { color: var(--primary-container-text); }
.va-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 2px; }

/* Satır içinde açılan form kabuğu (tablo satırı altında). */
.form-shell {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    padding: var(--space-4, 1rem);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* Başlık + eylem aynı satırda, iki uca yaslı. */
.flex-row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Model katmanı rozeti (T0–T3, EMB).
   ÖLÇÜLDÜ 2026-09-15: bu kural ÜÇ sayfanın inline <style> bloğunda ayrı ayrı
   yazılıydı (Overview / Department / Marketing) ve inline blok en son
   yüklendiği için paylaşılan tanımı EZİYORDU — ekranda 115 rozetin dolgusu
   paylaşılandan, metin rengi inline'dan geliyordu. Tek tanım burada yaşar.
   Sayfaların kanıtlanmış tasarımı korundu: rozet METİN renkli, nötr zeminli
   (dolgu değil) — katman ayrımını renk taşır, kutu değil. */
.tier-badge {
    display: inline-block;
    border-radius: var(--chip-radius);
    padding: 0.1rem 0.5rem;
    font-size: var(--label-sm-size, 0.6875rem);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    background: var(--surface-container-highest);
    color: var(--on-surface);
}
.tier-badge.tier-t0 { color: var(--primary); }
.tier-badge.tier-t1 { color: var(--on-surface-variant); }
.tier-badge.tier-t2 { color: var(--secondary); }
.tier-badge.tier-t3 { color: var(--tertiary); }
.tier-badge.tier-emb { color: var(--on-surface-variant); }

/* Aynı inline bloklardan taşındı. */
.model-name { font-size: 0.75rem; color: var(--on-surface-variant); }

/* Üçüncül rozet — badge ailesinin eksik varyantı. */
.badge-tertiary { background: var(--tertiary-container); color: var(--on-tertiary-container); }

/* Dead-letter satırındaki son hata metni + tükenmiş satır.
   ÖLÇÜLDÜ 2026-09-15: bu iki kural İKİ sayfanın inline <style> bloğunda
   ayrı ayrı yazılıydı (Outbound/InboundDeadLettersPage) ve inline en son
   yüklendiği için paylaşılanı eziyordu. Sayfaların ölçülmüş değerleri
   (--error, 0.6875rem) korundu; tek tanım burada. */
.dl-status {
    color: var(--error);
    font-size: 0.6875rem;
    overflow-wrap: anywhere;
}
.dl-exhausted { opacity: 0.6; }

/* Denetim satırındaki hata metni. */
.va-audit-row-error {
    color: var(--state-error-text);
    font-size: var(--font-size-sm);
    overflow-wrap: anywhere;
}

/* Giriş ekranı hata metni — v-auth-* ailesinin eksik üyesi. */
.v-auth-error { color: var(--state-error-text); margin-top: 12px; }

/* Geniş tablo kendi kabında yatay kayar; SAYFA gövdesi kaymaz. */
.overflow-x-auto { overflow-x: auto; max-width: 100%; }

/* /admin/process/instances/{id} — örnek başlık kartı + eylem şeridi.
   Kart ZEMİNDEN AYRI bir tondur (container-lowest), "No-Line": ayrımı
   kenarlık değil düzlem kayması taşır. */
.instance-header-card {
    background: var(--surface-container-lowest);
    border-radius: var(--card-radius);
    padding: var(--space-4, 1rem);
}
.instance-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* ══ VWizard — adım göstergesi ve gövde ritmi ═══════════════════════════════
   BURADA, bileşenin `.razor.css`'inde DEĞİL. ÖLÇÜLDÜ 2026-09-18:

   VWizard başlık/altlık içeriğini `RenderTreeBuilder` ile üretiyor
   (11 `builder.OpenElement`). Blazor kapsam özniteliğini yalnız RAZOR
   MARKUP'ına ekler; elle açılan eleman onu ALMAZ. Tarayıcıda doğrulandı —
   `.vwizard__steps` düğümünün öznitelikleri yalnız `class, aria-label`,
   `b-xxxxx` YOK.

   `::deep` de çözmez: o da `[b-xxxxx] .seçici` üretir, yani yine kapsam
   özniteliğine dayanır. Sonuç: 20 kuralın 20'si ÖLÜYDÜ — gösterge yatay
   şerit yerine düz bir liste olarak çiziliyordu (`display: block`,
   `::before` = none) ve kimse fark etmemişti çünkü bileşenin ilk gerçek
   tüketicisi bu turda ortaya çıktı.

   Aynı ders CLAUDE.md'de "Elle RenderTreeBuilder ile üretilen düğüm KAPSAM
   ÖZNİTELİĞİ TAŞIMAZ" başlığında yazılı. */
/* VWizard — kanonik çok adımlı akış. Kabuk (arka plan, odak tuzağı, boyut)
   VDialog'dan gelir; burada yalnız adım göstergesi ve gövde ritmi tanımlanır.

   ::deep gerekli: başlık/gövde/altlık içerikleri VDialog'un slotlarına
   render edildiği için bu bileşenin scope özniteliğini taşımıyorlar. */

.vwizard__header {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.vwizard__eyebrow {
    margin: 0;
    font-family: var(--font-label);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    /* ÖLÇÜLDÜ 2026-09-30: burada `-webkit-locale: "en"` vardı ("PRİORİTY" için). Sihirbaz başlıklarının
       dokuzu da artık TÜRKÇE ("Yeni kayıt", "Yeni politika") ve kilit onları "YENI" yapıyordu.
       Büyük harf çevrimi belgenin diline bırakılır. */
}

.vwizard__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--on-surface);
}

.vwizard__title:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 4px;
}

.vwizard__description {
    margin: 0;
    max-width: 60ch;
    font-size: var(--font-size-md);
    line-height: 1.5;
    color: var(--on-surface-variant);
}

/* Adım göstergesi. Sayı yerine BAŞLIK gösterir: "3/5" kullanıcıya nerede
   olduğunu söylemez, "Doğrulama" söyler. */
.vwizard__steps {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
    counter-reset: vwizard-step;
}

.vwizard__step {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    counter-increment: vwizard-step;
    font-size: var(--font-size-2xs);
}

.vwizard__step::before {
    content: counter(vwizard-step);
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    flex: 0 0 auto;
    border-radius: var(--chip-radius);
    background: var(--surface-container-highest);
    color: var(--on-surface-variant);
    font-weight: 700;
}

.vwizard__step--current::before {
    background: var(--primary);
    color: var(--on-primary);
}

.vwizard__step--done::before {
    content: "✓";
    background: var(--state-success-bg);
    color: var(--state-success-text-on-fill);
}

.vwizard__step-btn {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--on-surface-variant);
    text-align: start;
}

.vwizard__step--current .vwizard__step-btn {
    color: var(--on-surface);
    font-weight: 700;
}

/* Tamamlanan adımlar tıklanabilir — geriye dönüş serbest. İleri atlamak
   aradaki doğrulama kapılarını atlatırdı, o yüzden yalnız geri. */
.vwizard__step--done .vwizard__step-btn {
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.vwizard__step--done .vwizard__step-btn:hover {
    color: var(--primary);
}

.vwizard__step-btn:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: var(--btn-radius);
}

.vwizard__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    min-width: 0;
}

.vwizard__validation {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-2xs);
    color: var(--error);
}

.vwizard__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: flex-end;
}

/* Dar ekranda eylemler tam genişlik — başparmakla erişilebilir olsun. */
@media (max-width: 560px) {
    ::deep .vwizard__actions {
        flex-direction: column-reverse;
        align-items: stretch;
    }
}

/* ══ VFileDrop — gizli dosya girdisi ════════════════════════════════════════
   BURADA, bileşenin `.razor.css`'inde DEĞİL. `<InputFile>` bir BİLEŞENDİR ve
   kök `<input>`'u sarmalayanın `b-xxxxx` kapsam özniteliğini almaz; scoped
   kural (ve `::deep`) o özniteliğe dayandığı için eşleşmez.
   ÖLÇÜLDÜ 2026-09-18: input'ta kapsam listesi BOŞ, kardeşi `.vdrop__body`'de
   `b-7ofa740mw2` var. Kural ölüyken `opacity: 1` kalıyor ve tarayıcının ham
   "Choose File …" metni stilli bırakma alanının üstünde görünüyordu.
   Aynı ders bu oturumda ÜÇÜNCÜ kez ölçüldü (VWizard, mega menü, burası). */
.vdrop__input {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    opacity: 0;
    cursor: pointer;
}


/* ═══════════════════════════════════════════════════════════════════════════
   2026-09 Reference alignment — Light theme component surfaces
   ---------------------------------------------------------------------------
   These are role-level refinements, not page-specific skins. The existing
   sidebar remains the navigation anchor; content surfaces use the same
   neutral ramp with quieter controls and clearer action hierarchy.
   ═══════════════════════════════════════════════════════════════════════════ */

.page-section {
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

.section-surface {
    background: var(--surface-container-low);
    box-shadow: none;
}

:is(.toolbar),
.page-toolbar,
.section-toolbar,
.table-toolbar {
    border-radius: var(--control-radius);
}

:is(.toolbar) {
    background: var(--surface-container-low);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

:is(.inline-alert) {
    border-radius: var(--control-radius);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 18%, transparent);
}

:is(.inline-alert-info) {
    background: var(--state-info-bg);
    color: var(--state-info-text);
}

:is(.inline-alert-warning) {
    background: var(--state-warning-bg);
    color: var(--state-warning-text);
}

:is(.inline-alert-success) {
    background: var(--state-success-bg);
    color: var(--state-success-text);
}

:is(.inline-alert-error) {
    background: var(--state-error-bg);
    color: var(--state-error-text);
}

:is(.inline-alert-dismiss) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: var(--touch-target-min-aa, 2.75rem);
    min-block-size: var(--touch-target-min-aa, 2.75rem);
    border-radius: var(--control-radius);
}

:is(.inline-alert-dismiss):focus-visible {
    outline: var(--state-focus-ring, 2px solid var(--primary));
    outline-offset: var(--state-focus-offset, 2px);
}

@media (max-width: 767px) {
    :is(.toolbar),
    .page-toolbar,
    .section-toolbar,
    .table-toolbar {
        align-items: stretch;
    }
}


/* ══ ADMIN DATA SURFACES ═══════════════════════════════════════════════════
   Generated admin pages intentionally share these semantic hooks so the
   route-level pages do not fork table/filter CSS. */
.ws-shell--admin .ev-table-wrap {
    overflow-x: auto;
    border-radius: var(--card-radius);
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

.ws-shell--admin .ev-table {
    width: 100%;
    min-width: 42rem;
    border-collapse: separate;
    border-spacing: 0;
}

.ws-shell--admin .ev-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: var(--space-3) var(--space-4);
    background: var(--surface-container-low);
    color: var(--on-surface-variant);
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-align: start;
    white-space: nowrap;
}

.ws-shell--admin .ev-table td {
    padding: var(--space-3) var(--space-4);
    color: var(--on-surface);
    border-top: 1px solid var(--ghost-border);
    vertical-align: middle;
}

.ws-shell--admin .ev-table tbody tr {
    transition: background-color var(--duration-fast, 120ms) ease;
}

.ws-shell--admin .ev-table tbody tr:hover {
    background: color-mix(in srgb, var(--primary) 5%, var(--surface-container-lowest));
}

.ws-shell--admin .eh-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.ws-shell--admin .eh-search {
    min-inline-size: min(24rem, 100%);
}

@media (max-width: 767px) {
    .ws-shell--admin .ev-table-wrap {
        margin-inline: calc(-1 * var(--space-2));
    }

    .ws-shell--admin .ev-table th,
    .ws-shell--admin .ev-table td {
        padding-inline: var(--space-3);
    }
}


/* ══ ADMIN DETAIL FRAME — Phase 2/3 legacy route normalization ═════════════
   Legacy detail/timeline pages now share the same light enterprise surface as
   generated admin pages without changing their domain contracts. */
.admin-detail-shell .admin-detail-content {
    display: grid;
    gap: var(--space-6, 1.5rem);
    max-width: 1180px;
    width: 100%;
    margin-inline: auto;
    padding-block: var(--space-2, 0.5rem) var(--space-8, 2rem);
}

.admin-detail-shell .admin-detail-heading {
    margin: 0;
    color: var(--on-surface);
    font-size: clamp(1.25rem, 1.7vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -0.02em;
}

.admin-detail-shell .admin-detail-content > p,
.admin-detail-shell .admin-detail-content .subtitle {
    color: var(--on-surface-variant);
    line-height: 1.6;
}

.admin-detail-shell .admin-detail-content > h2:not(.admin-detail-heading),
.admin-detail-shell .admin-detail-content > h3 {
    margin: var(--space-4, 1rem) 0 0;
    color: var(--on-surface);
    font-size: 1rem;
    font-weight: 700;
}

.admin-detail-shell .admin-detail-content .data-table,
.admin-detail-shell .admin-detail-content .kv,
.admin-detail-shell .admin-detail-content .saga-timeline {
    margin: 0;
}

.admin-detail-shell .admin-detail-content .kv {
    display: grid;
    grid-template-columns: minmax(8rem, 0.32fr) minmax(0, 1fr);
    gap: 0;
    padding: var(--space-4, 1rem);
    border-radius: var(--radius-lg);
    background: var(--surface-container-lowest);
}

.admin-detail-shell .admin-detail-content .kv dt,
.admin-detail-shell .admin-detail-content .kv dd {
    margin: 0;
    padding: 0.7rem 0;
}

.admin-detail-shell .admin-detail-content .kv dt {
    color: var(--on-surface-variant);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.admin-detail-shell .admin-detail-content .kv dd {
    color: var(--on-surface);
}

.admin-detail-shell .admin-detail-content .saga-timeline {
    display: grid;
    gap: 0.75rem;
    padding: 0;
    list-style: none;
}

.admin-detail-shell .admin-detail-content .saga-timeline li {
    position: relative;
    padding: 0.9rem 1rem 0.9rem 1.2rem;
    border-left: 3px solid var(--ghost-border);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    background: var(--surface-container-lowest);
    color: var(--on-surface);
}

.admin-detail-shell .admin-detail-content .saga-timeline li.ok {
    border-left-color: var(--state-success-text);
}

.admin-detail-shell .admin-detail-content .saga-timeline li.fail {
    border-left-color: var(--state-error-text);
}

.admin-detail-shell .admin-detail-content .saga-timeline li.comp {
    border-left-color: var(--state-warning-text);
}

.admin-detail-shell .admin-detail-content .saga-timeline .err {
    margin-top: 0.5rem;
    color: var(--state-error-text);
    font-size: 0.875rem;
}

@media (max-width: 700px) {
    .admin-detail-shell .admin-detail-content {
        gap: var(--space-4, 1rem);
        padding-block-end: var(--space-6, 1.5rem);
    }

    .admin-detail-shell .admin-detail-content .kv {
        grid-template-columns: 1fr;
    }

    .admin-detail-shell .admin-detail-content .kv dt {
        padding-block-end: 0.15rem;
        border-bottom: 0;
    }

    .admin-detail-shell .admin-detail-content .kv dd {
        padding-block-start: 0.15rem;
    }
}

/* ============================================================
   REF-34 HIZALAMASI (2026-09-25) — Manus tasarim referanslari
   (artifacts/design-options-2026-09-23/reference-33..37).
   Dosyanin SONUNDA durur: ayni ozgulluktaki eski paket kurallarini
   kaynak sirasiyla yener; sayfa scoped CSS'i bilincli varyant olarak kalir.
   ============================================================ */

/* Butonlar: cumle duzeni, 14px/600, duz dolgu — buyuk harf ve harf araligi YOK. */
.btn,
.btn-primary,
.btn-secondary,
.btn-tertiary,
.btn-ghost,
.btn-outline,
.btn-danger,
.btn-success,
.btn-warning,
.btn-info {
    font-family: var(--font-label);
    font-size: var(--font-size-base);
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
}

/* stylelint-disable-next-line no-duplicate-selectors -- bilinçli katman: arada aynı özgüllükte .btn-* kuralları var; birleştirme dolgu/yazıyı değiştirdi (ölçüldü 2026-10-09: 20px→12px, 13px→14px) */
.btn-sm {
    font-size: var(--font-size-md);
}

/* .btn-primary rengi veraius-base.css'te TEK yerde (ref-34: duz --primary dolgu). */

/* Alanlar: beyaz zemin, gorunur 1px cerceve, 14px metin. */
.vtextfield,
.form-input,
.input-field,
.va-input,
.field-input,
.form-control,
.form-select,
.form-textarea,
.vselect {
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--outline-variant);
    font-size: var(--font-size-base);
}

.vtextfield:hover:not(:disabled):not([readonly]):not(:focus),
.form-input:hover:not(:disabled):not(:focus),
.form-select:hover:not(:disabled):not(:focus),
.form-textarea:hover:not(:disabled):not(:focus) {
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--outline);
}

.vtextfield:focus,
.form-input:focus,
.form-select:focus,
.form-textarea:focus,
.vtextfield:focus-visible,
.form-input:focus-visible {
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 2px var(--primary);
    outline: none;
}

.vtextfield:disabled,
.form-input:disabled,
.form-select:disabled,
.form-textarea:disabled {
    background: var(--surface-container);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

.vtextfield[aria-invalid="true"],
.vtextfield.is-error,
.form-input[aria-invalid="true"] {
    box-shadow: inset 0 0 0 1px var(--state-error, var(--error));
}

/* Bos durum ikonu (ref-36): yuvarlatilmis kare degil, yumusak daire. */
/* stylelint-disable-next-line no-duplicate-selectors -- yeniden tasarım katmanı eski tanımın yalnız bir kısmını ezer; arada aynı özgüllükte kural var */
.empty-state-icon {
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    background: var(--surface-container);
    box-shadow: none;
    opacity: 1;
}

/* ── REF-01 KPI KUTUCUĞU (2026-09-25) ─────────────────────────────────────
   Manus "Executive overview": ikon karesi solda (56px, yumuşak ton),
   etiket cümle düzeninde, değer BÜYÜK ve teal, altında gerekçe satırı.
   Çip SÖZCÜK taşımaya devam eder (WCAG 1.4.1) ama sessiz durur. */

/* stylelint-disable-next-line no-duplicate-selectors -- Manus KPI katmanı eski ikon tanımını kısmen ezer; arada --ok/--warning varyantları var */
.va-kpi__icon.va-kpi__icon {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: var(--btn-radius);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

.va-kpi__icon.va-kpi__icon .material-symbols-outlined { font-size: var(--icon-lg); }

.va-kpi__label {
    font-family: var(--font-label);
    min-width: 0;
    font-size: var(--font-size-base);
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    color: var(--on-surface-variant);
}


.va-kpi__n {
    font-family: var(--font-headline);
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    font-size: var(--font-size-6xl);
    font-weight: 700;
    color: var(--primary);
}

.va-kpi__unit,
.va-kpi__foot {
    font-size: var(--font-size-md);
}

/* Tum icerik 2. sutunda; ikon satir sayisindan bagimsiz tum yuksekligi kaplar.
   OLCULDU 2026-09-25: SLO kutucugu 5 cocuk tasiyor (meter dahil) ve ortuk
   yerlesim fazladan cocugu IKON sutununa itiyordu — etiket harf harf sariyordu. */
/* stylelint-disable-next-line no-duplicate-selectors -- Manus KPI katmanı; ilk tanımın display'i arada ezilir, birleştirme sırayı değiştirir */
.va-kpi:has(.va-kpi__icon) {
    column-gap: var(--space-4, 1rem);
    padding: var(--space-5, 1.25rem);
    min-height: 7.5rem;
    align-items: start;
    grid-template-columns: 3.5rem minmax(0, 1fr);
    grid-template-rows: none;
}
.va-kpi:has(.va-kpi__icon) > :not(.va-kpi__icon) { grid-column: 2; }
/* Etiket satırı İKİ satırlık yer ayırır: bir kutucukta etiket tek satır ("Bekleyen
   onay"), komşusunda iki satır ("Okunmamış bildirim") olunca alttaki sayı satırı
   kayıyordu — ölçüldü 2026-10-19 /today: sayılar kart tepesinden 59/76/73/59 px.
   Kırpmak yerine yer ayırmak: etiket hâlâ kırpılmaz (yukarıdaki kural). */
/* Kart komşusu kadar uzayınca (align-items: stretch) artan yükseklik her satıra
   paylaştırılıyor ve sayı satırı kart başına farklı yere düşüyordu (67/70/74 px).
   İçerik tepeye sabitlenir, boşluk en altta kalır. */
.va-kpi:has(.va-kpi__icon) { align-content: start; }
.va-kpi:has(.va-kpi__icon) .va-kpi__top {
    align-items: flex-start;
    min-height: calc(2lh);
}
.va-kpi:has(.va-kpi__icon) .va-kpi__top .va-kpi__label { line-height: 1.4; }
.va-kpi:has(.va-kpi__icon) .va-kpi__top { line-height: 1.4; font-size: var(--font-size-base); }
.va-kpi:has(.va-kpi__icon) .va-kpi__icon {
    align-self: center;
    grid-column: 1;
    grid-row: 1 / span 4;
}

/* ── REF-35: onay penceresi ─────────────────────────────────────────────────
   ConfirmDialog basligi/govdesi RenderTreeBuilder ile uretilir ve kapsam ozniteligi
   tasimaz; bu yuzden stil PAKETTE. Ortali ikon dairesi, 20px baslik, esit genislikte
   iki dugme (ref-35 "Delete workflow"). :has() ile yalniz onay penceresine uygulanir. */
.vdialog:has(.confirm-dialog__title) .vdialog__header {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-3);
    border-bottom: 0;
}
.vdialog:has(.confirm-dialog__title) .vdialog__body { text-align: center; }
.vdialog:has(.confirm-dialog__title) .vdialog__footer { border-top: 0; justify-content: stretch; }
.vdialog:has(.confirm-dialog__title) .vdialog__footer > * { flex: 1 1 0; }
.confirm-dialog__icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--primary-container);
    color: var(--on-accent-fill);
}
.confirm-dialog__icon--danger { background: var(--state-error-bg); color: var(--state-error-text); }
.confirm-dialog__title { font-size: 20px; font-weight: 700; color: var(--on-surface); }

/* ── VTabs — kanonik sekme seridi (ref-37). WorkspaceShell rayi ile AYNI anatomi:
   etkin sekme teal metin + sonen alt cizgi, sayac cipi. Tek kaynak burasi. */
.vtabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    /* İnce GÖRÜNÜR kaydırma çubuğu: gizliyken taşan sekmeler farede görünmüyor ve
       ulaşılamıyordu (2026-10-19). */
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--on-surface-variant) 35%, transparent) transparent;
    box-shadow: inset 0 -1px 0 var(--ghost-border);
    margin-bottom: var(--space-4);
}
.vtabs__tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 48px;
    padding: 12px 20px;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: var(--font-size-base);
    font-weight: 500;
    /* ref-nav #3: pasif sekme KOYU metin (soluk degil); ayrimi alt cizgi + teal tasir. */
    color: var(--on-surface);
    white-space: nowrap;
    text-decoration: none;   /* rota sekmeleri <a> olarak da yazilir (SentimentNav) */
    cursor: pointer;
    transition: color var(--transition-btn);
}
.vtabs__tab:hover { color: var(--primary); }
.vtabs__tab:focus-visible { outline: none; box-shadow: inset var(--focus-ring); border-radius: var(--btn-radius); }
.vtabs__tab.is-active { color: var(--primary); font-weight: 600; }
/* ref-nav #3: etkin sekmenin altinda DUZ, sekme genisliginde teal cizgi. */
.vtabs__tab.is-active::after {
    content: '';
    position: absolute;
    inset-inline: 8px;
    bottom: 0;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: var(--primary);
}
.vtabs__icon { font-size: var(--icon-sm); }
.vtabs__count {
    font-size: 10px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    padding: 1px 6px;
    border-radius: var(--chip-radius);
    background: var(--surface-container);
    color: var(--on-surface-variant);
}
.vtabs__tab.is-active .vtabs__count { background: var(--accent-fill); color: var(--on-accent-fill); }
.vtabs__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--state-error); }


/* ── ref-33 tablo sistemi: araç şeridi, yoğunluk ve toplu seçim şeridi — DataTable VE VGrid
   (AG Grid) aynı dili kullanır (kullanıcı kararı 2026-09-27: "tüm DataTable ve AG Grid ekranları
   bu şekilde"). Scoped CSS bileşen köküne ulaşamadığı için paylaşılan pakette. ── */
.data-table-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; margin-bottom: var(--space-3); }
.data-table-density { display: inline-flex; gap: 4px; margin-left: auto; }
.data-table-bulkbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-2); border-radius: var(--btn-radius); background: var(--primary-container); color: var(--on-accent-fill); }
.data-table-bulkbar__count { font-weight: 700; font-size: var(--font-size-sm); }
.data-table-bulkbar__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-left: auto; }

/* ref-34 VTextArea sayacı — bileşenin ikinci kök öğesi olduğu için paylaşılan pakette. */
.vtextarea__counter { display: block; margin-top: 4px; text-align: right; font-size: var(--font-size-xs); color: var(--on-surface-variant); font-variant-numeric: tabular-nums; }
.vtextarea__counter.is-near { color: var(--state-warning-text); }
.vtextarea__counter.is-max { color: var(--state-error-text); font-weight: 700; }

/* ref-34 form düzeyi hata kartı (VFormErrorSummary). */
.vform-summary { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4); margin-bottom: var(--space-3); border-radius: var(--card-radius); background: var(--state-error-bg); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--state-error) 30%, transparent); }
.vform-summary__icon { flex: none; font-size: 28px; color: var(--state-error-text); }
.vform-summary__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.vform-summary__title { margin: 0; font-weight: 800; color: var(--state-error-text); }
.vform-summary__text { margin: 0; font-size: var(--font-size-sm); color: var(--on-surface); }
.vform-summary__list { margin: 4px 0 0; padding-left: 1.1rem; font-size: var(--font-size-sm); color: var(--on-surface); }

/* ── ref-nav #9: komut paleti sonuç satırı — teal tonlu kare ikon kutusu,
   kalın başlık, altında açıklama. İkon bir VIcon (bileşen); CommandPalette'in
   scoped `.cmd-result-icon` kuralı onun köküne ULAŞMAZ, bu yüzden pakette. */
.cmd-result-item .cmd-result-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    border-radius: var(--btn-radius);
    background: color-mix(in srgb, var(--primary-container) 40%, var(--surface-container-lowest));
    color: var(--primary);
    font-size: var(--icon-md);
    opacity: 1;
}
.cmd-result-item .cmd-result-label { display: flex; flex-direction: column; gap: 2px; font-weight: 600; }
.cmd-result-item .cmd-result-snippet { font-weight: 400; font-size: var(--font-size-sm); color: var(--on-surface-variant); }

/* ══ FORM ANATOMİSİ — daisyUI'den uyarlandı (2026-10-12) ════════════════════
   daisyUI KURULMADI (Tailwind yok; Bootstrap'la aynı gerekçe — 2026-09-15).
   Alınan şey ANATOMİ: ortak boyut ölçeği (input-sm/md/lg), ghost stili,
   girdi içi ön/son ek ("input" sınıfı ebeveynde) ve fieldset/legend grubu.
   Değerler token'dan gelir; Md (44px) taban kuralda kalır, burada yalnız
   sapmalar yazılır. Bileşen API'si: VFieldSize / VFieldVariant (VFieldStyle.cs). */

/* Boyut — (0,2,0): taban .vtextfield { min-height: 44px } kuralını yener. */
.vtextfield.vfield--sm,
.vfield-adorned.vfield--sm {
    min-height: 36px;               /* .btn-sm ile aynı kademe */
    font-size: var(--font-size-md);
}
.vtextfield.vfield--sm { padding-block: 0.25rem; padding-inline: var(--space-3); }

.vtextfield.vfield--lg,
.vfield-adorned.vfield--lg {
    min-height: 52px;
    font-size: var(--font-size-lg);
}
.vtextfield.vfield--lg { padding-inline: var(--space-4); }

/* Ghost — çerçeve/zemin yok, hover'da hayalet, odakta TAM halka geri gelir.
   Hata durumu ghost'u EZER: aria-invalid hariç tutulur, kırmızı çerçeve kaybolmasın. */
.vtextfield.vfield--ghost:not(:focus):not([aria-invalid="true"]) {
    background: transparent;
    box-shadow: none;
}
.vtextfield.vfield--ghost:hover:not(:disabled):not([readonly]):not(:focus):not([aria-invalid="true"]) {
    background: var(--surface-container-low);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

/* Ön/son ekli alan — çerçeve, zemin ve odak halkası SARMALAYICIDA. */
.vfield-adorned {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 44px;
    padding-inline: var(--space-3);
    box-sizing: border-box;
    border-radius: var(--input-radius);
    background: var(--surface-container-lowest);
    box-shadow: inset 0 0 0 1px var(--outline-variant);
    color: var(--on-surface-variant);
    transition: box-shadow var(--transition-btn, 50ms ease);
}
.vfield-adorned:hover:not(.vfield-adorned--disabled):not(:focus-within) {
    box-shadow: inset 0 0 0 1px var(--outline);
}
.vfield-adorned:focus-within {
    box-shadow: inset 0 0 0 2px var(--primary);
}
.vfield-adorned--error,
.vfield-adorned--error:hover:not(:focus-within) {
    background: var(--state-error-bg);
    box-shadow: inset 0 0 0 1px var(--state-error, var(--error));
}
.vfield-adorned--error:focus-within {
    box-shadow: inset 0 0 0 2px var(--state-error, var(--error));
}
.vfield-adorned--disabled {
    background: var(--surface-container);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}
.vfield-adorned.vfield--ghost:not(:focus-within):not(.vfield-adorned--error) {
    background: transparent;
    box-shadow: none;
}

.vfield-adorned__affix {
    display: inline-flex;
    align-items: center;
    flex: none;
    font-size: var(--font-size-md);
    color: var(--on-surface-variant);
    white-space: nowrap;
}

/* İç girdi şeffaf: çerçeveyi sarmalayıcı taşır. :not(#vfield-none) bilinçli bir
   ÖZGÜLLÜK yükseltmesidir (1,x,0) — taban hover kuralı (0,5,0), scoped
   .vtextfield--error ve VFormField hata yüzeyi aynı elemana yazar; !important
   tavanını (41) büyütmek yerine bu yol seçildi. */
.vfield-adorned > .vtextfield:not(#vfield-none) {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    width: auto;
    padding-inline: 0;
    background: transparent;
    box-shadow: none;
    outline: none;
    font-size: inherit;
}

/* Fieldset — bir KÜMEYİ adlandırır (VFormField tek kontrolü). */
.vfieldset {
    margin: 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.vfieldset__legend {
    padding: 0;
    margin-bottom: var(--space-2);
    font-family: var(--font-label);
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
}
.vfieldset__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.vfieldset--inline .vfieldset__body {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-4);
}
.vfieldset__desc {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--on-surface-variant);
    line-height: 1.45;
}
.vfieldset:disabled { opacity: 0.6; }

/* ══ SHADCN GÖRSEL DİLİ ═══════════════════════════════════════════════════
   Ürün kararı 2026-10-18: uygulama shadcn/ui bileşen anatomisine hizalanır —
   TEKNOLOJİ değil GÖRSEL DİL (Tailwind/React eklenmez, 3 tema ve renkler
   korunur). Kaynak: shadcn MCP registry (@shadcn/button, input, card, badge,
   tabs). Katman dosyanın SONUNDA durur ki aynı özgüllükteki eski kuralları
   kaynak sırasıyla ezsin; RENK burada yazılmaz (varyantın tek kaynağı
   korunur), yalnız anatomi: tipografi, kenarlık, odak halkası, yarıçap.

   Bilinçli sapma: shadcn düğme/girdi yüksekliği h-9 (36px); burada 44px
   KORUNUR — WCAG 2.5.5 hedefi ve FormComponentAdoption guard'ları.
   Kartta shadcn shadow-sm YAZILMAZ — durağan gölge yasağı
   (CardSurfaceContractTests); ayrımı 1px hayalet kenarlık taşır. */

/* Button — text-sm font-medium, düz büyük/küçük harf, kaldırma hareketi yok */
.btn,
.btn-primary,
.btn-secondary,
.btn-tertiary,
.btn-ghost,
.btn-danger,
.btn-outline-secondary {
    font-family: var(--font-body);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
    border-radius: var(--btn-radius);
}
.btn:hover,
.btn-primary:hover,
.btn-primary:active,
.btn-secondary:active,
.btn-danger:active {
    transform: none;
}
.btn-sm { font-size: 0.8125rem; }
.btn:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-tertiary:focus-visible,
.btn-ghost:focus-visible,
.btn-danger:focus-visible,
.btn-outline-secondary:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring-color, var(--primary)) 50%, transparent);
}

/* Input — 1px kenarlık + shadow-xs, odakta ring-[3px] ring/50 */
.vtextfield,
.form-input,
.form-textarea,
.form-select,
.input-field {
    border-radius: var(--input-radius);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--outline-variant) 70%, transparent),
                0 1px 2px 0 rgba(0, 0, 0, 0.05);
    font-size: 0.875rem;
}
.vtextfield:focus,
.vtextfield:focus-visible,
.form-input:focus-visible,
.form-textarea:focus-visible,
.form-select:focus-visible,
.input-field:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 1px var(--primary),
                0 0 0 3px color-mix(in srgb, var(--primary) 30%, transparent);
}

/* Card — rounded-xl, 1px kenarlık, gap-6 / py-6 ritmi */
.section-card,
.card,
.stat-card,
.kpi-card {
    border-radius: var(--card-radius);
    box-shadow: inset 0 0 0 1px var(--ghost-border);
}

/* Badge — rounded-md px-2 py-0.5 text-xs font-medium */
.badge,
.badge-ok,
.badge-pass,
.badge-error,
.badge-fail,
.badge-warn,
.badge-warning,
.badge-info,
.badge-default {
    min-height: 22px;
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-md, 0.375rem);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
}

/* Tabs — muted zeminli liste (p-[3px], rounded-lg), etkin sekme yükselen kart */
.vtabs {
    display: inline-flex;
    align-items: center;
    gap: 0;
    max-width: 100%;
    padding: 3px;
    border-radius: var(--control-radius);
    background: var(--surface-container);
    box-shadow: none;
}
.vtabs__tab {
    min-height: 36px;
    padding: 0.25rem 0.875rem;
    border-radius: calc(var(--control-radius) - 3px);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--on-surface-variant);
}
.vtabs__tab:hover { color: var(--on-surface); }
.vtabs__tab.is-active {
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    font-weight: 500;
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), inset 0 0 0 1px var(--ghost-border);
}
.vtabs__tab.is-active::after { content: none; }
.vtabs__tab:focus-visible {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 30%, transparent);
    border-radius: calc(var(--control-radius) - 3px);
}

/* ── Sidebar menü öğesi — shadcn SidebarMenuButton anatomisi ───────────────
   text-sm, rounded-md, hover ve etkin satır AYNI düz "accent" dolgusu;
   etkin satır font-medium + metin rengiyle ayrılır. Teal→altın omurga ve
   sönen degrade kaldırıldı (ReUI: "current list item = ghost fill +
   aria-current, never a dot"). Yükseklik 40px korunur (dokunma hedefi). */
.sidebar-nav-item {
    font-size: 0.875rem;
    letter-spacing: normal;
    border-radius: var(--btn-radius);
}
.sidebar-nav-item::before,
.sidebar-nav-item:hover::before,
.sidebar-nav-item.active::before { content: none; }
.sidebar-nav-item.active {
    background: var(--sidebar-surface-container-high, var(--surface-container-high));
    color: var(--sidebar-on-surface);
    font-weight: 500;
}

/* ── İşletim yüzeyinde giriş animasyonu YOK ───────────────────────────────
   ReUI compose: "Operational: no page-load motion"; "no stagger on table rows
   or lists of 20+". Kademeli opaklık animasyonu ekran görüntüsünde içeriği
   soluk yakalıyordu ve content-visibility altında hiç başlamıyordu (ölçüldü
   2026-10-12). Öğe doğrudan son hâlinde çizilir. */
.stagger-item,
.page-enter {
    animation: none;
    opacity: 1;
    transform: none;
}
/* .page-enter da kapalı (ölçüldü 2026-10-18 /ai-security): animasyon arka plan
   sekmesinde ara karede takılıp ws-shell'e scale(0.98) translateY(8px)
   bırakıyordu; dönüşüm yapışkan sekme şeridini 12px aşağı itti ve üstünde
   alttan kayan içerik göründü. @keyframes page-enter korunur (motion guard). */

/* Kart/panel başlığı — shadcn CardTitle (leading-none font-semibold, 16px).
   18px/700 bölüm başlığı panel içinde sayfa başlığıyla (24px/600) yarışıyordu. */
.section-title {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.25;
}

/* shadcn Sonner/Toast (2026-10-18): düz kart zemini, rounded-md, border,
   shadow-lg, text-sm; cam bulanıklığı ve sol renk şeridi yok — tonu ikon taşır. */
.toast {
    background: var(--surface-container-lowest);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-radius: var(--btn-radius);
    border: 1px solid var(--ghost-border);
    border-left-width: 1px;
    border-left-color: var(--ghost-border);
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
    font-size: 0.875rem;
}

/* Tür sınıfları (.toast.toast-success …, özgüllük 0,2,0) yukarıdaki kuralı eziyordu:
   zemin %12 şeffaf durum tonu (altındaki içerik görünüyordu) ve yalnız SOL kenar
   renkli. Ölçüldü 2026-10-19. Zemin opak kart kalır; tonu ikon taşır. */
.toast:is(.toast-success, .toast-error, .toast-warning, .toast-critical, .toast-info) {
    background: var(--surface-container-lowest);
    border-left-color: var(--ghost-border);
}

/* shadcn Select tetikleyicisi: girdiyle AYNI anatomi (border-input, shadow-xs,
   rounded-md, text-sm); odakta 3px halka. VSelect'in <select>'i bu sınıfı taşır. */
.form-input-alt {
    border-radius: var(--input-radius);
    font-size: 0.875rem;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--outline-variant) 70%, transparent),
                0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
.form-input-alt:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 1px var(--primary),
                0 0 0 3px color-mix(in srgb, var(--primary) 30%, transparent);
}

/* shadcn Toggle/Badge çipleri (2026-10-19): düz harf, text-xs font-medium. */
.btn-chip {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 500;
}

/* Çıplak <select> (Blazor InputSelect · 41 kullanım, EditForm doğrulamasına bağlı) kanonik
   VSelect ile AYNI görünür: yerel ok yerine tek chevron, text-sm, sağda ok payı.
   VSelect kendi okunu (.vselect-caret) çizdiği için kapsam dışı. Ölçüldü 2026-10-19:
   /ai-assistant-setup, /agents/tasks, /ai-security/access tarayıcı okuyla çiziliyordu. */
.app-content select:not([multiple]):not([size]):not(.vselect-wrapper select) {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23737a7a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 16px 16px;
    padding-inline-end: 2.25rem;
    font-size: 0.875rem;
}
