/* ── assets/css/yg/00-tokens.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 00 — Tokenlar
   --------------------------------------------------------------------------
   PROJEDEKİ TEK `:root` BLOĞU. Kural (docs/tasarim-dili.md · R2):

     • `:root` bildirimi yalnızca bu dosyada bulunabilir.
     • Renk değeri (#hex, rgb(), rgba(), hsl()) yalnızca bu dosyada bulunabilir.
       Diğer tüm yg/ dosyaları token *tüketir*, tanımlamaz.

   Bu iki kural estetik değil, mühendislik: sayede @media print bloğu 20 satırda
   tüm paneli kâğıda uygun hale getiriyor (token'ları yeniden tanımlayarak),
   bileşen başına print kuralı yazmaya gerek kalmıyor.

   Kaynak: Yuto Tasarım Sistemi v2 (Glass) — repo kökündeki
   YUTOMAT-dashboard-yuto-glass.html prototipi bu token'larla çizildi.
   Prototipten iki BİLİNÇLİ SAPMA var, aşağıda gerekçeleriyle işaretli:
     1. --yg-text-3 opaklığı .45 → .58 (WCAG AA kontrastı)
     2. Kartlarda overflow:hidden YOK (bkz. 20-components/card.css)
   ========================================================================== */

:root {
    /* ── Zemin ve marka ışıkları ──────────────────────────────────────────
       Cam, arkasındaki ışığı bulanıklaştırarak taşır. Arkada renk yoksa cam
       da yok: her ekranın altında bu dört ışık kümesi duruyor. */
    --yg-void: #050813;
    --yg-navy: #1B3A8F;
    --yg-shadow-deep: rgba(3, 7, 20, 0.9);

    /* Arka ışık kümeleri — 02-base.css bunları tüketir, kendi rengini bilmez */
    --yg-blob-1: radial-gradient(circle, rgba(27, 58, 143, 0.75), rgba(27, 58, 143, 0) 66%);
    --yg-blob-2: radial-gradient(circle, rgba(53, 168, 240, 0.38), rgba(53, 168, 240, 0) 65%);
    --yg-blob-3: radial-gradient(circle, rgba(245, 166, 35, 0.26), rgba(245, 166, 35, 0) 64%);
    --yg-blob-4: radial-gradient(circle, rgba(45, 212, 191, 0.24), rgba(45, 212, 191, 0) 64%);
    --yg-veil: radial-gradient(120% 90% at 50% 0%, rgba(5, 8, 19, 0.15), rgba(5, 8, 19, 0.84) 78%);

    /* Mürekkep — perde, ipucu balonu, yapışkan tablo başlığı gibi OPAK olmak
       zorunda olan koyu yüzeyler. Cam değil: arkasını göstermemesi gerekiyor. */
    --yg-ink: #030714;
    --yg-ink-raised: #0b1020;

    /* ── Anlamsal renkler ─────────────────────────────────────────────────
       info = bilgi/navigasyon · action = TEK eylem rengi · live = canlı/iyi
       danger = hata · Her birinin "-soft" hali koyu zeminde metin için. */
    --yg-info: #35A8F0;
    --yg-info-soft: #8ACFFF;
    --yg-action: #F5A623;
    --yg-action-hi: #FFBB4A;
    --yg-action-hi2: #FFC873;
    --yg-action-pressed: #E0951C;
    --yg-action-soft: #FFCE7A;
    --yg-on-action: #1A1206;
    /* Amber düğmenin üst parlaklığı ve halka kenarı — koyu metin üstünde
       çalıştığı için beyaz/siyah alfa, marka rengi değil. */
    --yg-on-action-sheen: inset 0 1px 0 rgba(255, 255, 255, 0.45);
    --yg-on-action-ring: rgba(26, 18, 6, 0.28);
    --yg-live: #2DD4BF;
    --yg-live-soft: #7DF0E0;
    --yg-danger: #FF5A52;
    --yg-danger-soft: #FF8B85;
    --yg-ai: #7C6BF5;

    /* rgb üçlüleri — Bootstrap köprüsü ve rgba() hesapları için */
    --yg-info-rgb: 53, 168, 240;
    --yg-action-rgb: 245, 166, 35;
    --yg-live-rgb: 45, 212, 191;
    --yg-danger-rgb: 255, 90, 82;
    --yg-text-rgb: 238, 242, 249;

    /* ── Metin ────────────────────────────────────────────────────────────
       text-3 opaklığı prototipte .45'ti ve tasarım dilinin kendi kuralını
       (metin kontrastı ≥ 4.5) ihlal ediyordu. Bu renk eyebrow, stat etiketi ve
       TÜM tablo başlıklarında kullanılıyor — sistemin en yaygın etiket rengi.

       Ölçüm (WCAG 2.1 kontrast oranı, gerçek kompozit zeminle):
                        void   glass-1  glass-2  glass-3
         .45 (eski)     4.11     4.15     4.12     3.97   ✗ hepsi AA altı
         .58 (şimdi)    6.23     6.10     5.97     5.63   ✓ hepsi AA üstü

       Zeminler cam kademesinin void üstündeki düz karşılığıdır (%5/%7/%11 beyaz). */
    --yg-text: #EEF2F9;
    --yg-text-2: rgba(238, 242, 249, 0.72);
    --yg-text-3: rgba(238, 242, 249, 0.58);
    --yg-text-disabled: rgba(238, 242, 249, 0.32);

    /* ── Yüzeyler ─────────────────────────────────────────────────────────
       Cam üç kademede: 1 satır/çip · 2 kart/panel · 3 yüzen/örtü.
       Her kademe dört katman: bulanıklık + 155° dolgu + kenar + üst parlaklık. */
    --yg-hair: rgba(255, 255, 255, 0.09);
    --yg-well: rgba(3, 7, 20, 0.42);
    --yg-well-inset: inset 0 2px 6px rgba(0, 0, 0, 0.35);

    --yg-g1-fill: linear-gradient(155deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
    --yg-g1-flat: rgba(255, 255, 255, 0.05);
    --yg-g1-blur: blur(16px) saturate(150%);
    --yg-g1-border: rgba(255, 255, 255, 0.1);
    --yg-g1-sheen: inset 0 1px 0 rgba(255, 255, 255, 0.16);
    --yg-g1-shadow: 0 8px 24px -12px rgba(3, 7, 20, 0.6);

    --yg-g2-fill: linear-gradient(155deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.038));
    --yg-g2-flat: rgba(255, 255, 255, 0.07);
    --yg-g2-blur: blur(24px) saturate(165%);
    --yg-g2-border: rgba(255, 255, 255, 0.13);
    --yg-g2-sheen: inset 0 1px 0 rgba(255, 255, 255, 0.24);
    --yg-g2-shadow: 0 16px 40px -14px rgba(3, 7, 20, 0.75);

    --yg-g3-fill: linear-gradient(155deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.055));
    --yg-g3-flat: rgba(255, 255, 255, 0.11);
    --yg-g3-blur: blur(40px) saturate(190%);
    --yg-g3-border: rgba(255, 255, 255, 0.2);
    --yg-g3-sheen: inset 0 1px 0 rgba(255, 255, 255, 0.34);
    --yg-g3-shadow: 0 30px 70px -20px rgba(3, 7, 20, 0.9);

    /* Nötr ışık şeridi — specular kenarın renk almamış hali */
    --yg-strip-neutral: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);

    /* ── Perde ve perde üstü yüzey ────────────────────────────────────────
       Cam, ARKASINDAKİ IŞIĞI bulanıklaştırarak çalışıyor. Modal/onay kutusu
       gibi bir perdenin üstünde duran yüzeylerde arkada ışık kalmıyor: beyaz
       gradyan tek başına koyu-üstüne-koyu bir yüzey veriyor ve metin okunmuyor.
       Çözüm iki parçalı ve ikisi de token:
         • perde yalnızca odağı ayırmaya yetecek kadar koyu (blur yardım eder),
         • perde üstündeki yüzey cam dolgusunun ALTINA opak bir taban alır.
       Yeni bir örtü bileşeni eklendiğinde bu iki token kullanılır. */
    --yg-scrim: rgba(3, 7, 20, 0.48);
    --yg-scrim-blur: blur(6px);
    /* Perdenin GÖRÜNTÜ üstündeki hali. Modal perdesi arkasındaki cam yüzeye
       karşı çalışıyor ve blur ona yardım ediyor; kullanıcının yüklediği bir
       fotoğrafın üstünde blur yok ve fotoğrafın parlaklığı bilinmiyor, o yüzden
       üstündeki ikonun okunabilmesi için daha koyu. */
    --yg-scrim-strong: rgba(3, 7, 20, 0.72);
    /* Yüzen cam yüzeyin (modal, açılır menü, onay kutusu, toast) ALTINDAKİ opak
       taban. Cam token'larının hepsi saydam beyaz katman; tek başına kullanınca
       yüzeyin arkasındaki içerik okunuyor. Perde üstünde ya da başka bir kartın
       üstünde fark etmez — yüzen her yüzey bu tabanı ister. */
    --yg-surface-floating: rgba(11, 16, 32, 0.92);

    /* Proje logosunun altındaki plaka. Marka logoları çoğunlukla koyu mürekkep
       ve şeffaf zeminli; koyu temada doğrudan cama koyunca kayboluyorlar. Bu
       yüzden bilinçli olarak AÇIK bir taban — dilin geri kalanının aksine. */
    --yg-plogo-plate: rgba(255, 255, 255, 0.9);

    /* Telefon bildirim MAKETİ — ikinci bilinçli açık ada. Push bildirimleri
       ekranındaki önizleme bir arayüz parçası değil, cihazda görünecek şeyin
       taklidi: mobil bildirim tepsisi açık zeminli ve onu koyuya çevirmek
       maketi yalan yapardı. O yüzden kendi açık palet üçlüsü var. */
    --yg-notif-sheet: rgba(248, 250, 252, 0.97);
    --yg-notif-ink: #0f172a;
    --yg-notif-ink-2: #475569;
    /* Meta satırı ("YUTOMAT YÖNETİM · ŞİMDİ") maketin en soluk metni ama yine
       METİN: `#64748b` açık kart üstünde 4.28:1 ölçüldü, AA sınırı 4.5.
       Bir ton koyulaştı → 5.13:1. Maket hâlâ inandırıcı, yazı okunuyor. */
    --yg-notif-meta: #56616f;

    /* Vurgu/etkileşim yüzeyleri */
    --yg-hover: rgba(255, 255, 255, 0.07);
    --yg-active: rgba(255, 255, 255, 0.12);
    --yg-row-hover: rgba(255, 255, 255, 0.035);
    --yg-faint: rgba(255, 255, 255, 0.055);
    --yg-hairline-soft: rgba(238, 242, 249, 0.055);

    /* Sol menü camı — kabuk kendi kademesini kullanıyor (g2'den biraz daha
       yoğun): ekranın kenarında duran, hep görünen tek yüzey. */
    --yg-sidebar-fill: linear-gradient(160deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.035));
    --yg-sidebar-blur: blur(30px) saturate(175%);
    --yg-sidebar-border: rgba(255, 255, 255, 0.14);
    --yg-sidebar-sheen: inset 0 1px 0 rgba(255, 255, 255, 0.26);
    --yg-sidebar-shadow: 0 24px 60px -22px rgba(3, 7, 20, 0.85);

    /* İskelet parıltısı — camda iskelet gri blokla değil PARLAKLIKLA çalışır */
    --yg-skeleton-sweep: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.05) 0,
        rgba(255, 255, 255, 0.14) 40%,
        rgba(255, 255, 255, 0.05) 80%
    );
    --yg-skeleton-still: rgba(255, 255, 255, 0.06);

    /* Kaydırma çubuğu */
    --yg-scrollbar: rgba(238, 242, 249, 0.14);
    --yg-scrollbar-hover: rgba(238, 242, 249, 0.24);

    /* ── Durum dolguları (pill, uyarı şeridi, satır vurgusu) ─────────────
       Bileşenler bunları doğrudan değil, --yg-state üzerinden tüketir;
       bkz. 20-components/card.css'teki [data-yg-status] deseni. */
    --yg-fill-info: rgba(53, 168, 240, 0.16);
    --yg-fill-action: rgba(245, 166, 35, 0.16);
    --yg-fill-live: rgba(45, 212, 191, 0.16);
    --yg-fill-danger: rgba(255, 90, 82, 0.15);
    --yg-fill-neutral: rgba(255, 255, 255, 0.07);
    --yg-edge-info: rgba(53, 168, 240, 0.3);
    --yg-edge-action: rgba(245, 166, 35, 0.3);
    --yg-edge-live: rgba(45, 212, 191, 0.28);
    --yg-edge-danger: rgba(255, 90, 82, 0.3);
    --yg-edge-neutral: rgba(255, 255, 255, 0.12);

    /* ── Grafik serileri ─────────────────────────────────────────────────
       Kategorik veri (pasta dilimleri, çoklu seri) anlamsal renklerle
       BOYANMAZ: turkuaz bir dilim "canlı", kırmızı bir dilim "hata" okunur.
       Bu ramp sabit açıklıkta hue döndürerek üretildi; her adım hem --yg-void
       hem komşusuna karşı ayrışıyor. 7 diliminden fazlası "Diğer"e toplanır. */
    --yg-series-1: #35A8F0;
    --yg-series-2: #2DD4BF;
    --yg-series-3: #F5A623;
    --yg-series-4: #A78BFA;
    --yg-series-5: #F472B6;
    --yg-series-6: #4ADE80;
    --yg-series-7: #FB923C;
    --yg-series-8: #94A3B8;

    /* ── Tipografi ───────────────────────────────────────────────────────
       display = başlık · sans = gövde · mono = etiket, kod ve TÜM sayılar
       (sayılar hizalanabilsin diye mono + tabular-nums). */
    --yg-display: 'Familjen Grotesk', 'Public Sans', system-ui, sans-serif;
    --yg-sans: 'Public Sans', system-ui, -apple-system, sans-serif;
    --yg-mono: 'Martian Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    --yg-text-xs: 11px;
    --yg-text-sm: 12.5px;
    --yg-text-base: 15px;
    --yg-text-lg: 17px;
    --yg-text-xl: 19px;
    --yg-text-2xl: 25px;
    --yg-text-3xl: 38px;
    --yg-leading: 1.55;
    --yg-tracking-label: 0.14em;

    /* ── Uzay ────────────────────────────────────────────────────────────
       Boşluk daima ebeveynin `gap`'i ile verilir; blok kendi margin'ini
       tanımlamaz (SRP · R-blok-kendi-dışına-taşmaz). */
    --yg-gap-xs: 6px;
    --yg-gap-sm: 10px;
    --yg-gap: 16px;
    --yg-gap-lg: 26px;
    --yg-gap-xl: 40px;
    --yg-pad-card: 20px 22px;
    --yg-pad-row: 13px 20px;

    /* ── Yarıçap — ölçekle büyür: çip 10 → kart 22 → yüzen 26 → sayfa 30 ── */
    --yg-radius-xs: 8px;
    --yg-radius-sm: 12px;
    --yg-radius: 16px;
    --yg-radius-md: 18px;
    --yg-radius-lg: 22px;
    --yg-radius-xl: 26px;
    --yg-radius-2xl: 30px;
    --yg-radius-pill: 999px;

    /* ── Kontroller ──────────────────────────────────────────────────────── */
    --yg-control-h: 56px;
    --yg-control-h-sm: 42px;
    --yg-focus-ring: 0 0 0 3px rgba(53, 168, 240, 0.35);

    /* ── Hareket ─────────────────────────────────────────────────────────
       Giriş easing'i tasarım dilinden; basma tepkisi daha sert.
       Tüm animasyonlar prefers-reduced-motion ile 02-base.css'te durduruluyor. */
    --yg-ease-in: cubic-bezier(0.22, 0.92, 0.28, 1);
    --yg-ease-sheet: cubic-bezier(0.2, 1, 0.3, 1);
    --yg-ease-press: cubic-bezier(0.2, 0.9, 0.25, 1);
    --yg-dur-press: 0.18s;
    --yg-dur-color: 0.25s;
    --yg-dur-enter: 0.58s;

    /* ── Katman sırası ───────────────────────────────────────────────────── */
    --yg-z-backlight: 0;
    --yg-z-content: 1;
    /* İçinde açılır liste bulunan kap: `backdrop-filter` her cam yüzeyi bir
       stacking context yapıyor, o yüzden menünün z-index'i kendi kartının
       dışına çıkamıyor ve menü SONRAKİ kartın altında kalıyor. Menü açıkken
       kap bu katmana çıkar. */
    --yg-z-raised: 5;
    --yg-z-sidebar: 20;
    --yg-z-backdrop: 1040;
    --yg-z-modal: 1055;
    --yg-z-toast: 1090;
}

/* ==========================================================================
   Yazdırma teması — token'ların açık kâğıt karşılıkları
   --------------------------------------------------------------------------
   Koyu tema kâğıda basılmaz. Her bileşen rengini token'dan okuduğu için
   (R3) TÜM paneli kâğıda uygun hale getirmek bu bloktan ibaret: bileşen
   başına print kuralı yazmak gerekmiyor. Yapısal print kuralları (neyin
   gizleneceği, sayfa bölünmesi) 02-base.css'te.

   Bu blok da bilinçli olarak token dosyasında: renk değeri yalnızca burada
   bulunabilir kuralının istisnası olmasın.
   ========================================================================== */
@media print {
    :root {
        --yg-void: #fff;
        --yg-ink: #000;
        --yg-ink-raised: #fff;
        --yg-text: #111;
        --yg-text-2: #444;
        --yg-text-3: #666;
        --yg-text-disabled: #999;
        --yg-hair: #ddd;
        --yg-hairline-soft: #eee;
        --yg-well: #f6f6f6;
        --yg-well-inset: none;
        --yg-hover: transparent;
        --yg-active: transparent;
        --yg-row-hover: transparent;
        --yg-faint: transparent;

        --yg-g1-fill: #fff;
        --yg-g2-fill: #fff;
        --yg-g3-fill: #fff;
        --yg-g1-flat: #fff;
        --yg-g2-flat: #fff;
        --yg-g3-flat: #fff;
        --yg-g1-blur: none;
        --yg-g2-blur: none;
        --yg-g3-blur: none;
        --yg-g1-border: #ddd;
        --yg-g2-border: #ddd;
        --yg-g3-border: #ddd;
        --yg-g1-sheen: none;
        --yg-g2-sheen: none;
        --yg-g3-sheen: none;
        --yg-g1-shadow: none;
        --yg-g2-shadow: none;
        --yg-g3-shadow: none;

        --yg-sidebar-fill: #fff;
        --yg-sidebar-blur: none;
        --yg-sidebar-sheen: none;
        --yg-sidebar-shadow: none;

        --yg-skeleton-sweep: #f1f1f1;
        --yg-skeleton-still: #f1f1f1;

        /* Kâğıtta anlamsal renkler koyu kalır: ışık şeridi gri bir çizgiye
           döner ama yanındaki metin/ikon durumu söylemeye devam eder. */
        --yg-strip-neutral: #111;
    }
}

/* ── assets/css/yg/01-fonts.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 01 — Tipografi kaynakları
   --------------------------------------------------------------------------
   Kendi sunucumuzdan servis ediliyor: CSP `font-src 'self'` zaten izinli, CDN
   kesintisinden etkilenmiyoruz ve hata sayfaları (self-contained olmak zorunda)
   de aynı dosyaları kullanabiliyor.

   Her aile iki alt küme: `latin` + `latin-ext`. Türkçe için ikisi de ŞART —
   ı (U+0131) latin'de, ama ğ/ş/İ (U+011E-011F, U+015E-015F, U+0130) latin-ext'te.
   Alt kümesiz tek dosya kullanılırsa Türkçe karakterler fallback fonta düşer.

   Ağırlıklar variable font aralığı olarak veriliyor (400 700 gibi); tarayıcı
   aradaki her değeri sentezlemeden üretir.
   ========================================================================== */

/* ── Familjen Grotesk — başlıklar (display) ───────────────────────────────── */
@font-face {
  font-family: 'Familjen Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../../assets/fonts/familjen-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Familjen Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../../assets/fonts/familjen-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Public Sans — gövde metni ─────────────────────────────────────────────── */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('../../assets/fonts/public-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('../../assets/fonts/public-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Martian Mono — etiketler, kodlar ve TÜM sayılar ──────────────────────── */
@font-face {
  font-family: 'Martian Mono';
  font-style: normal;
  font-weight: 300 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('../../assets/fonts/martian-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Martian Mono';
  font-style: normal;
  font-weight: 300 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('../../assets/fonts/martian-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── assets/css/yg/02-base.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 02 — Temel katman
   --------------------------------------------------------------------------
   Reset, gövde, arka ışık, tipografi temeli, odak halkası, erişilebilirlik
   kaçışları ve yazdırma yolu. Bu dosya `*` seçicisini kullanmaya izinli olan
   TEK yg/ dosyasıdır (docs/tasarim-dili.md · R-yıldız-yalnızca-base).

   Renk yok: her değer 00-tokens.css'ten geliyor.
   ========================================================================== */

/* ── Reset ─────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    /* Native tarih/saat seçicileri, kaydırma çubukları ve otomatik doldurma
       kutuları koyu şemayı buradan öğrenir. Olmadığında `type="date"`
       takvim ikonu siyah-üstüne-siyah çıkıyor. */
    color-scheme: dark;
}

body {
    margin: 0;
    background: var(--yg-void);
    color: var(--yg-text);
    font: 400 var(--yg-text-base) / var(--yg-leading) var(--yg-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd {
    margin: 0;
}

ul, ol {
    margin: 0;
    padding: 0;
}

/* Menü/liste rolündeki ul'lar madde işareti taşımaz; içerik listeleri
   (.yg-prose içinde) kendi işaretini geri alır. */
nav ul, [role='menu'] ul, [role='menubar'] ul, [role='list'] {
    list-style: none;
}

img, svg, video, canvas {
    display: block;
    max-width: 100%;
}

button, input, select, textarea {
    font: inherit;
    color: inherit;
}

a {
    color: var(--yg-action);
    text-decoration: none;
    transition: color var(--yg-dur-color) ease;
}

a:hover {
    color: var(--yg-action-hi);
}

hr {
    border: 0;
    border-top: 1px solid var(--yg-hair);
    margin: 0;
}

::selection {
    background: rgba(var(--yg-info-rgb), 0.32);
    color: var(--yg-text);
}

/* Kaydırma çubuğu — cam yüzeyde beyaz sistem çubuğu sırıtıyor. */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

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

::-webkit-scrollbar-thumb {
    background: var(--yg-scrollbar);
    border-radius: var(--yg-radius-pill);
    border: 2px solid transparent;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--yg-scrollbar-hover);
    background-clip: content-box;
}

/* ── Tipografi ─────────────────────────────────────────────────────────── */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--yg-display);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--yg-text);
    text-wrap: balance;
}

/* Sayı taşıyan her yüzey mono + tabular: kolonlar hizalanmadığında tablo
   okunmuyor. Yardımcı sınıf değil, semantik eleman seçicisi. */
code, kbd, samp, pre {
    font-family: var(--yg-mono);
    font-variant-numeric: tabular-nums;
}

/* ── Arka ışık ─────────────────────────────────────────────────────────
   Cam ancak arkasında renk varsa cam. Dört marka ışığı kümesi + vinyet.
   `contain: paint` kümelerin repaint alanını kendi kutusuna kilitler —
   olmadan her blur'lu yüzey sürekli yeniden boyanıyor.
   ---------------------------------------------------------------------- */
.yg-backlight {
    position: fixed;
    inset: 0;
    z-index: var(--yg-z-backlight);
    overflow: hidden;
    background: var(--yg-void);
    pointer-events: none;
    contain: paint;
}

.yg-backlight__blob {
    position: absolute;
    display: block;
    border-radius: 50%;
}

.yg-backlight__blob--1 {
    width: 1100px;
    height: 1100px;
    left: -16%;
    top: -24%;
    background: var(--yg-blob-1);
    filter: blur(30px);
}

.yg-backlight__blob--2 {
    width: 900px;
    height: 900px;
    right: -12%;
    top: 6%;
    background: var(--yg-blob-2);
    filter: blur(40px);
}

.yg-backlight__blob--3 {
    width: 820px;
    height: 820px;
    left: 24%;
    bottom: -20%;
    background: var(--yg-blob-3);
    filter: blur(50px);
}

.yg-backlight__blob--4 {
    width: 700px;
    height: 700px;
    right: 16%;
    bottom: 4%;
    background: var(--yg-blob-4);
    filter: blur(46px);
}

.yg-backlight__veil {
    position: absolute;
    inset: 0;
    background: var(--yg-veil);
}

/* Sürükleme animasyonu YALNIZCA hareketli varyantta. Veri yoğun sayfalarda
   (sipariş, analiz, raf) kapatılıyor: sürekli transform, arkasındaki her cam
   yüzeyin yeniden boyanmasını tetikliyor. Bkz. docs/tasarim-dili.md · perf. */
@keyframes ygDrift {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50% { transform: translate3d(3%, -2%, 0) scale(1.08); }
}

.yg-backlight--animated .yg-backlight__blob--1 { animation: ygDrift 26s ease-in-out infinite; }
.yg-backlight--animated .yg-backlight__blob--2 { animation: ygDrift 34s ease-in-out infinite reverse; }
.yg-backlight--animated .yg-backlight__blob--3 { animation: ygDrift 30s ease-in-out infinite; }
.yg-backlight--animated .yg-backlight__blob--4 { animation: ygDrift 38s ease-in-out infinite reverse; }

/* ── Paylaşılan animasyonlar ───────────────────────────────────────────
   Tasarım dilinin hareket sözlüğü. Bileşenler bunları kendileri tanımlamaz. */
@keyframes ygBreathe {
    0%, 100% { opacity: 0.35; }
    50% { opacity: 1; }
}

@keyframes ygFlow {
    0% { transform: translateX(-110%); }
    100% { transform: translateX(320%); }
}

@keyframes ygSkeleton {
    0% { background-position: -240px 0; }
    100% { background-position: 340px 0; }
}

/* ── Odak ──────────────────────────────────────────────────────────────
   Tek kural, `!important` yok: legacy enhancements.css'teki 3px indigo halka
   `!important` ile yazılmıştı ve token'a bağlanamıyordu. Burada halka
   token'dan geliyor, bileşenler gerekirse offset'i değiştirir. */
:focus-visible {
    outline: 2px solid var(--yg-info);
    outline-offset: 2px;
    border-radius: var(--yg-radius-xs);
}

/* Fare kullanıcısına halka gösterme (tarayıcı zaten :focus-visible ile
   ayırıyor; bu satır eski :focus davranışını kapatıyor). */
:focus:not(:focus-visible) {
    outline: none;
}

/* ── Ana içeriğe atla ──────────────────────────────────────────────────── */
.yg-skip {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: var(--yg-z-toast);
    padding: 12px 18px;
    border-radius: var(--yg-radius-sm);
    background: var(--yg-g3-flat);
    border: 1px solid var(--yg-g3-border);
    color: var(--yg-text);
    font: 500 var(--yg-text-sm) / 1 var(--yg-sans);
    transition: top var(--yg-dur-press) var(--yg-ease-press);
}

.yg-skip:focus {
    top: 12px;
    color: var(--yg-text);
}

/* ── Ekran okuyucuya özel ──────────────────────────────────────────────── */
.yg-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   Erişilebilirlik kaçışları — `!important` yalnızca burada ve print'te
   ========================================================================== */

/* Yüksek kontrast (Windows High Contrast / forced-colors).
   Cam bu modda tamamen kayboluyor: backdrop-filter yok sayılıyor, dolgular
   sistem renkleriyle değiştiriliyor. Üç cam kademesine de görünür kenar ver.
   Işık şeridi de renk taşımaz hale geldiği için durum METİN/İKONLA da
   verilmek zorunda (docs/tasarim-dili.md · R-durum-yalnızca-renkle-verilmez). */
@media (forced-colors: active) {
    .yg-card,
    .yg-panel,
    .yg-stat,
    .yg-row,
    .yg-pill,
    .yg-modal__content {
        border: 1px solid CanvasText !important;
    }

    /* Yüksek kontrastta cam ve renk kayboluyor; şerit anlam taşımaz hale
       geliyor. Kartın kendi CanvasText kenarı yeterli sinyal — durum ayrıca
       metin/ikonla da veriliyor (R9). */
    .yg-card__strip {
        display: none !important;
    }

    .yg-backlight {
        display: none !important;
    }

    :focus-visible {
        outline: 3px solid Highlight !important;
        outline-offset: 2px !important;
    }
}

/* Hareket azaltma — vestibüler güvenlik. Sürüklenen ışıklar, nefes alan
   noktalar, akan şerit ve iskelet parıltısı durur; maskotlar ilk karesinde
   kalır (bunu <picture> media sorgusu hallediyor, CSS animasyonlu webp'yi
   durduramaz). */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   Yazdırma — koyu tema kâğıda basılmaz, token'ları açık temaya çeviriyoruz.
   Tüm bileşenler rengi token'dan okuduğu için (R3) bileşen başına print
   kuralı yazmak gerekmiyor: 20 satır tüm paneli kâğıda uygun hale getiriyor.
   ========================================================================== */
@media print {
    /* .modern-sidebar — sınıf adı components/sidebar.blade.php'den geliyor.
       Legacy layout'ta bu seçici `.sidebar` yazılmıştı ve hiçbir şeyle
       eşleşmediği için menü kâğıda basılıyordu; aynı hatayı tekrarlamıyoruz. */
    .yg-backlight,
    .modern-sidebar,
    .sidebar-backdrop,
    .yg-topbar,
    .yg-to-top,
    .yg-skip,
    .yg-mobile-toggle,
    .no-print,
    .btn,
    button {
        display: none !important;
    }

    * {
        box-shadow: none !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        text-shadow: none !important;
    }

    body {
        background: var(--yg-void) !important;
        font-size: 12pt;
    }

    .yg-shell {
        display: block !important;
    }

    .yg-card,
    .yg-panel {
        border: 1px solid var(--yg-g2-border) !important;
        break-inside: avoid;
    }

    /* Işık şeridi kâğıtta gri bir çizgi olarak kalır — kartın durum taşıdığı
       bilgisi kaybolmasın (yanındaki metin/ikon zaten durumu söylüyor). */
    .yg-card__strip::before {
        background: var(--yg-strip-neutral) !important;
        box-shadow: none !important;
    }

    /* Ekranda kendi kabında kaydırılan içerik (uzun tablo, akordeon gövdesi)
       kâğıtta kırpılmaz: kaydırma diye bir şey yok, kesilen satır kayıp veri.
       `overflow`/`max-height` bileşen ve sayfa katmanında farklı adlarla
       geçtiği için burada niteliğe değil DAVRANIŞA göre sıfırlanıyor. */
    .yg-table-wrap,
    .order-accordion-body,
    .order-card-open .order-accordion-body {
        max-height: none !important;
        overflow: visible !important;
    }
}

/* ── assets/css/yg/03-bootstrap-bridge.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 03 — Bootstrap köprüsü
   --------------------------------------------------------------------------
   Bootstrap 5.3 kalıyor; görünümünü Yuto token'larına bağlıyoruz. Bunun tek
   nedeni kolaylık değil: panelde ~10.000 satır sayfa JS'i `badge bg-*-subtle`,
   `text-muted`, `btn-*`, `table` gibi Bootstrap sınıflarıyla markup üretiyor.
   Değişkenler eşlendiğinde bu markup TEK SATIR JS DEĞİŞMEDEN yeni dile uyuyor.

   Ayrıca Bootstrap'in kendi `[data-bs-theme=dark]` bloğu, değişkenle
   düzeltilemeyen dört gömülü SVG'yi (form-select oku, form-switch topuzu,
   accordion oku, btn-close) koyu hale çeviriyor — o yüzden `<html>` üzerinde
   `data-bs-theme="dark"` ŞART, yalnızca tercih değil.

   ── ÖZGÜLLÜK NOTU (bu dosyanın çalışma mantığı) ──────────────────────────
   Bootstrap bazı değişkenleri `:root`'ta, bazılarını BİLEŞENİN KENDİSİNDE
   tanımlar (`.table { --bs-table-bg: var(--bs-body-bg) }` gibi). Bileşende
   tanımlı bir değişkeni `:root`'tan ezmek İŞE YARAMAZ — bu yüzden aşağıda
   her değişken, Bootstrap'in tanımladığı seçicinin aynısıyla yeniden
   tanımlanıyor. Eşit özgüllükte bizim dosya sonra yüklendiği için kazanır;
   hiçbir yerde `!important` veya derin seçici yok.
   ========================================================================== */

/* ── Kök değişkenler ───────────────────────────────────────────────────── */
[data-bs-theme='dark'] {
    /* Gövde ve tipografi */
    --bs-body-bg: var(--yg-void);
    --bs-body-bg-rgb: 5, 8, 19;
    --bs-body-color: var(--yg-text);
    --bs-body-color-rgb: var(--yg-text-rgb);
    --bs-body-font-family: var(--yg-sans);
    --bs-body-font-size: var(--yg-text-base);
    --bs-body-line-height: var(--yg-leading);
    --bs-font-monospace: var(--yg-mono);
    --bs-heading-color: var(--yg-text);
    --bs-emphasis-color: var(--yg-text);
    --bs-emphasis-color-rgb: var(--yg-text-rgb);

    /* .text-muted ve .text-secondary bu değişkeni okur — JS'in ürettiği
       64 `text-muted` kullanımı buradan düzeliyor. */
    --bs-secondary-color: var(--yg-text-2);
    --bs-secondary-color-rgb: var(--yg-text-rgb);
    --bs-tertiary-color: var(--yg-text-3);
    --bs-secondary-bg: var(--yg-hover);
    --bs-tertiary-bg: var(--yg-well);

    /* Kenarlar ve yarıçaplar */
    --bs-border-color: var(--yg-hair);
    --bs-border-color-translucent: var(--yg-hair);
    --bs-border-radius: var(--yg-radius);
    --bs-border-radius-sm: var(--yg-radius-sm);
    --bs-border-radius-lg: var(--yg-radius-lg);
    --bs-border-radius-xl: var(--yg-radius-xl);
    --bs-border-radius-xxl: var(--yg-radius-2xl);
    --bs-border-radius-pill: var(--yg-radius-pill);

    /* Bağlantılar — tek eylem rengi */
    --bs-link-color: var(--yg-action);
    --bs-link-color-rgb: var(--yg-action-rgb);
    --bs-link-hover-color: var(--yg-action-hi);
    --bs-link-hover-color-rgb: 255, 187, 74;

    --bs-code-color: var(--yg-info-soft);
    --bs-highlight-bg: rgba(var(--yg-action-rgb), 0.22);
    --bs-focus-ring-color: rgba(var(--yg-info-rgb), 0.35);
    --bs-focus-ring-width: 3px;

    /* ── Tema renkleri ────────────────────────────────────────────────────
       Anlamsal eşleme:
         primary → info mavisi   (metin/kenar/odak koyu zeminde okunmalı)
         success → live turkuazı
         warning → action amberi
         danger  → danger kırmızısı
         info    → info-soft (primary'den görsel olarak ayrışsın)
         light   → beyaz DEĞİL: `bg-light text-dark` kombinasyonu JS'te var
                   (orders.js), beyaz kalırsa koyu metin okunmaz hale gelir.
       Her renk için üç aile eşlenir: düz, -rgb (yardımcı sınıflar rgb okur)
       ve subtle üçlüsü (bg-subtle / border-subtle / text-emphasis) — ~180
       `badge bg-*-subtle` kullanımı ve tüm `.alert-*` bu üçlüden besleniyor. */
    --bs-primary: var(--yg-info);
    --bs-primary-rgb: var(--yg-info-rgb);
    --bs-primary-bg-subtle: var(--yg-fill-info);
    --bs-primary-border-subtle: var(--yg-edge-info);
    --bs-primary-text-emphasis: var(--yg-info-soft);

    --bs-success: var(--yg-live);
    --bs-success-rgb: var(--yg-live-rgb);
    --bs-success-bg-subtle: var(--yg-fill-live);
    --bs-success-border-subtle: var(--yg-edge-live);
    --bs-success-text-emphasis: var(--yg-live-soft);

    --bs-warning: var(--yg-action);
    --bs-warning-rgb: var(--yg-action-rgb);
    --bs-warning-bg-subtle: var(--yg-fill-action);
    --bs-warning-border-subtle: var(--yg-edge-action);
    --bs-warning-text-emphasis: var(--yg-action-soft);

    --bs-danger: var(--yg-danger);
    --bs-danger-rgb: var(--yg-danger-rgb);
    --bs-danger-bg-subtle: var(--yg-fill-danger);
    --bs-danger-border-subtle: var(--yg-edge-danger);
    --bs-danger-text-emphasis: var(--yg-danger-soft);

    --bs-info: var(--yg-info-soft);
    --bs-info-rgb: 138, 207, 255;
    --bs-info-bg-subtle: var(--yg-fill-info);
    --bs-info-border-subtle: var(--yg-edge-info);
    --bs-info-text-emphasis: var(--yg-info-soft);

    --bs-secondary: var(--yg-text-2);
    --bs-secondary-rgb: var(--yg-text-rgb);
    --bs-secondary-bg-subtle: var(--yg-fill-neutral);
    --bs-secondary-border-subtle: var(--yg-edge-neutral);
    --bs-secondary-text-emphasis: var(--yg-text-2);

    --bs-light: var(--yg-hover);
    --bs-light-rgb: 255, 255, 255;
    --bs-light-bg-subtle: var(--yg-fill-neutral);
    --bs-light-border-subtle: var(--yg-edge-neutral);
    --bs-light-text-emphasis: var(--yg-text-2);

    --bs-dark: var(--yg-void);
    --bs-dark-rgb: 5, 8, 19;
    --bs-dark-bg-subtle: var(--yg-well);
    --bs-dark-border-subtle: var(--yg-hair);
    --bs-dark-text-emphasis: var(--yg-text-2);
}

/* ── Tablo ─────────────────────────────────────────────────────────────
   KRİTİK: Bootstrap 5.3 hücre zeminini
     box-shadow: inset 0 0 0 9999px var(--bs-table-bg)
   ile boyar. Varsayılan `--bs-table-bg: var(--bs-body-bg)` bırakılırsa cam
   kartın üstüne OPAK bir plaka basılır ve sekiz tablo sınıfı da bozuk görünür.
   Şeffaf yapmak, tablonun camın üstünde durmasını sağlayan tek şey. */
.table {
    --bs-table-bg: transparent;
    --bs-table-accent-bg: transparent;
    --bs-table-color: var(--yg-text);
    --bs-table-border-color: var(--yg-hair);
    --bs-table-striped-bg: var(--yg-row-hover);
    --bs-table-striped-color: var(--yg-text);
    --bs-table-hover-bg: var(--yg-row-hover);
    --bs-table-hover-color: var(--yg-text);
    --bs-table-active-bg: var(--yg-active);
    --bs-table-active-color: var(--yg-text);
}

/* `.table-light` başlıkları açık temadan kalma; koyu zeminde beyaz şerit
   oluşturuyor. Nötr cam dolguya çevir. */
.table-light,
.table > thead.table-light {
    --bs-table-bg: var(--yg-fill-neutral);
    --bs-table-color: var(--yg-text);
    --bs-table-border-color: var(--yg-hair);
}

/* Tablo başlığı — tasarım dilinin etiket tipografisi */
/* Satır yüksekliği 1 DEĞİL: Türkçe büyük harf işaretleri (Ö/Ü/İ) kırpılıyor.
   Ayrıntı: 20-components/table.css */
.table > thead th {
    font: 500 10.5px / 1.5 var(--yg-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--yg-text-3);
    border-bottom: 1px solid var(--yg-hair);
    white-space: nowrap;
}

/* Sayı taşıyan hücreler hizalanmalı */
.table td,
.table th {
    font-variant-numeric: tabular-nums;
}

/* ── Kart ──────────────────────────────────────────────────────────────── */
.card {
    --bs-card-bg: transparent;
    --bs-card-color: var(--yg-text);
    --bs-card-border-color: var(--yg-g2-border);
    --bs-card-border-radius: var(--yg-radius-lg);
    --bs-card-inner-border-radius: var(--yg-radius);
    --bs-card-cap-bg: transparent;
    --bs-card-cap-color: var(--yg-text);
    /* Yüzen yüzey → glass 3 + opak taban. Dilin kuralı yüzen çubuk/menüyü
       glass 3'e koyuyor; taban olmadan menü başka bir kartın üstüne düştüğünde
       altındaki ışık şeridi ve sayılar menünün içinden okunuyordu. */
    background: var(--yg-g3-fill), var(--yg-surface-floating);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    box-shadow: var(--yg-g2-shadow), var(--yg-g2-sheen);
}

/* ── Modal ─────────────────────────────────────────────────────────────── */
.modal {
    --bs-modal-bg: transparent;
    --bs-modal-color: var(--yg-text);
    --bs-modal-border-color: var(--yg-g3-border);
    --bs-modal-border-radius: var(--yg-radius-xl);
    --bs-modal-inner-border-radius: var(--yg-radius-lg);
    --bs-modal-header-border-color: var(--yg-hair);
    --bs-modal-footer-border-color: var(--yg-hair);
}

/* Perde ve perde üstü yüzey kuralı 00-tokens.css'te açıklanıyor
   (--yg-scrim / --yg-surface-floating). Bootstrap perdeyi opaklık ile
   çizdiği için burada renk + opaklık ayrı veriliyor. */
.modal-backdrop {
    --bs-backdrop-bg: var(--yg-ink);
    --bs-backdrop-opacity: 0.48;
    backdrop-filter: var(--yg-scrim-blur);
    -webkit-backdrop-filter: var(--yg-scrim-blur);
}

/* Perde üstü yüzey: cam dolgusu + altında opak taban. Bkz. 00-tokens.css

   `backdrop-filter` BURADA YOK, bilinçli. İki gerekçe:

   1. Görünmüyor. Taban `--yg-surface-floating` = %92 opak; blur yalnızca kalan
      %8'lik pencereden sızıyor ve arkada zaten perdenin kendi bulanıklığı var
      (`.modal-backdrop`). Yani 40px blur + %190 doygunluk pratikte hiçbir şey
      göstermiyor, sadece büyük bir yüzeyi compositor katmanına çeviriyordu.
   2. Native `<select>` açılır menüsünü yerinden ediyordu. Filtre uygulanan bir
      ata öğe yeni bir kuşatma bloğu (containing block) kuruyor; Chrome modal
      içindeki bir seçim listesini tıklayınca menüyü kontrolün yanında değil
      modalın üst tarafında çiziyordu. Menü tarayıcının kendi arayüzü olduğu
      için CSS ile konumlandırılamıyor — tek kol, ata öğedeki filtreyi
      kaldırmak. */
.modal-content {
    /* Taban OPAK (`--yg-ink-raised`, `--yg-surface-floating` ile aynı renk ama
       %100). Filtre kalkınca %8'lik saydamlık artık bulanmıyordu: arkadaki tablo
       satırları modalın içinden okunur hâle geliyordu. Camın okuması dolgu
       gradyanı, saç teli kenar ve gölgeyle zaten kuruluyor. */
    background: var(--yg-g3-fill), var(--yg-ink-raised);
    box-shadow: var(--yg-g3-shadow), var(--yg-g3-sheen);
}

/* ── Modal kaydırma zinciri ─────────────────────────────────────────────
   BURADA BİR HATA VARDI ve panelin BÜTÜN modallarını etkiliyordu: uzun
   modallarda alt kısımlar kırpılıyor, hiçbir yere kaydırılamıyordu.

   Sebep iki şeyin birleşmesi:
     1. `.modal-content`'a genel bir `overflow: hidden` verilmişti (ışık şeridi
        için — oysa şeridin kendi kırpma kabı var, gerek yoktu),
     2. Panelin modallarında gövde ile alt bilgi bir `<form>` içinde: yani
        Bootstrap'in `modal-dialog-scrollable` kurgusunun beklediği
        `.modal-content > .modal-body` komşuluğu YOK. Araya giren form sıradan
        bir blok olduğu için zincir orada kopuyor, form içeriği kadar uzuyor ve
        kırpılıyor.

   Legacy'de sorun görünmüyordu çünkü `user-management.css` gövdeye sabit bir
   `max-height: 65vh` veriyordu; o dosya silinince eksik zincir açığa çıktı.

   KARAR: panelde modal SAYFAYI kaydırmaz. Gövdesi kayar, başlık ve alt bilgi
   sabit kalır. Bootstrap'in varsayılanı (uzun modalda `.modal`'ın kendisi
   kayar) burada yanlış: formun "Kaydet" düğmesi ekrandan çıkıyor ve kullanıcı
   kaydedemiyor. Bu yüzden kural `modal-dialog-scrollable` varyantına değil
   TÜM modallara uygulanıyor — sınıfı unutmak bir hataya dönüşmesin.

   `min-height: 0` her halkada şart: flex öğesinin varsayılan `min-height: auto`
   değeri içeriğinden küçülmesini engelliyor ve zincir yine kopuyor (aynı tuzak
   pages/price-templates.css'te de yorumlu).

   Yükseklik tavanı `dvh` ile: mobil tarayıcı çubuğu açılıp kapandığında `vh`
   sabit kalıyor ve modalın altı ekran dışına taşıyor. `vh` satırı eski
   tarayıcılar için yedek. */
.modal-content {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--bs-modal-margin, 1.75rem) * 2);
    max-height: calc(100dvh - var(--bs-modal-margin, 1.75rem) * 2);
}

.modal-content > form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.modal-body {
    overflow-y: auto;
    min-height: 0;
}

/* Modal kendi ışık şeridini taşıyorsa kırpma kabı modal yarıçapını kullanır.
   (Kabın neden 2px değil de yarıçap kadar yüksek olduğu card.css'te anlatılıyor.) */
.modal-content > .yg-card__strip {
    --yg-strip-clip: var(--yg-radius-xl);
}

/* İkon + metin: kart başlığıyla aynı gerekçe — boşluk karakterine güvenilmez,
   boşluk bloğun kuralı. */
.modal-title {
    display: flex;
    align-items: baseline;
    gap: 9px;
    font-family: var(--yg-display);
    font-weight: 600;
    letter-spacing: -0.015em;
}

/* Başlık ikonu modalın durum rengini alır. Metin rengini devralınca dolu bir
   beyaz leke oluyor ve başlığın kendisinden daha baskın duruyordu. Nötr modalda
   `--yg-state-text` kartın varsayılanına (metin rengi) düşmesin diye burada
   ikincil ton yedeği var. */
.modal-title i {
    color: var(--yg-state-text, var(--yg-text-2));
    font-size: 0.86em;
}

.modal-content[data-yg-status='neutral'] .modal-title i,
.modal-content:not([data-yg-status]) .modal-title i {
    color: var(--yg-text-3);
}

/* ── Açılır menü ───────────────────────────────────────────────────────── */
/* İkon + metin: legacy markup her öğede `me-2` yazıyordu; boşluk artık bloğun
   kendi işi (çoklu seçim listesi de aynı kuralı kullanıyor). */
.dropdown-item {
    display: flex;
    align-items: center;
    gap: 9px;
}

.dropdown-menu {
    --bs-dropdown-bg: transparent;
    --bs-dropdown-color: var(--yg-text);
    --bs-dropdown-border-color: var(--yg-g2-border);
    --bs-dropdown-border-radius: var(--yg-radius);
    --bs-dropdown-link-color: var(--yg-text-2);
    --bs-dropdown-link-hover-color: var(--yg-text);
    --bs-dropdown-link-hover-bg: var(--yg-hover);
    --bs-dropdown-link-active-bg: var(--yg-active);
    --bs-dropdown-link-active-color: var(--yg-text);
    --bs-dropdown-divider-bg: var(--yg-hair);
    --bs-dropdown-header-color: var(--yg-text-3);
    /* Yüzen yüzey → glass 3 + opak taban. Dilin kuralı yüzen çubuk/menüyü
       glass 3'e koyuyor; taban olmadan menü başka bir kartın üstüne düştüğünde
       altındaki ışık şeridi ve sayılar menünün içinden okunuyordu. */
    background: var(--yg-g3-fill), var(--yg-surface-floating);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    box-shadow: var(--yg-g2-shadow), var(--yg-g2-sheen);
}

/* ── Sayfalama ─────────────────────────────────────────────────────────── */
.pagination {
    --bs-pagination-bg: transparent;
    --bs-pagination-color: var(--yg-text-2);
    --bs-pagination-border-color: var(--yg-hair);
    --bs-pagination-border-radius: var(--yg-radius-sm);
    --bs-pagination-hover-bg: var(--yg-hover);
    --bs-pagination-hover-color: var(--yg-text);
    --bs-pagination-hover-border-color: var(--yg-g2-border);
    --bs-pagination-focus-bg: var(--yg-hover);
    --bs-pagination-focus-color: var(--yg-text);
    --bs-pagination-active-bg: var(--yg-fill-info);
    --bs-pagination-active-border-color: var(--yg-edge-info);
    --bs-pagination-active-color: var(--yg-info-soft);
    --bs-pagination-disabled-bg: transparent;
    --bs-pagination-disabled-color: var(--yg-text-disabled);
    --bs-pagination-disabled-border-color: var(--yg-hair);
}

/* ── Sekmeler ──────────────────────────────────────────────────────────── */
.nav-tabs {
    --bs-nav-tabs-border-color: var(--yg-hair);
    --bs-nav-tabs-border-radius: 0;
    --bs-nav-tabs-link-hover-border-color: transparent transparent var(--yg-g2-border);
    --bs-nav-tabs-link-active-color: var(--yg-text);
    --bs-nav-tabs-link-active-bg: transparent;
    --bs-nav-tabs-link-active-border-color: transparent transparent var(--yg-info);
    --bs-nav-link-color: var(--yg-text-2);
    --bs-nav-link-hover-color: var(--yg-text);
    --bs-nav-link-font-size: var(--yg-text-sm);
}

/* Aktif sekme altı çizgi + hafif ışıma: cam üstünde "kutu" görünümü yerine
   ışık şeridi dilini takip ediyor. */
.nav-tabs .nav-link.active {
    border-bottom-width: 2px;
    box-shadow: 0 2px 12px -4px var(--yg-info);
}

.nav-pills {
    --bs-nav-pills-border-radius: var(--yg-radius-sm);
    --bs-nav-pills-link-active-bg: var(--yg-fill-info);
    --bs-nav-pills-link-active-color: var(--yg-info-soft);
    --bs-nav-link-color: var(--yg-text-2);
    --bs-nav-link-hover-color: var(--yg-text);
}

/* ── Rozet ─────────────────────────────────────────────────────────────── */
.badge {
    --bs-badge-border-radius: var(--yg-radius-xs);
    --bs-badge-font-weight: 500;
    --bs-badge-padding-x: 8px;
    --bs-badge-padding-y: 5px;
    font-family: var(--yg-mono);
    font-size: 10.5px;
    letter-spacing: 0.06em;
}

/* ── İlerleme ──────────────────────────────────────────────────────────── */
.progress,
.progress-stacked {
    --bs-progress-bg: var(--yg-well);
    --bs-progress-border-radius: var(--yg-radius-pill);
    --bs-progress-bar-bg: var(--yg-info);
    --bs-progress-box-shadow: var(--yg-well-inset);
}

/* ── Uyarı ─────────────────────────────────────────────────────────────
   Renkler subtle üçlüsünden geliyor; burada yalnızca yüzey dili. */
.alert {
    --bs-alert-border-radius: var(--yg-radius);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

/* ── Formlar: cam DEĞİL, koyu oyuk ─────────────────────────────────────
   Tasarım dilinin sert kuralı: giriş alanı camdan yapılmaz — yazı okunmaz,
   imleç kaybolur. Cam yüzeyin İÇİNE koyu bir oyuk açıyoruz.
   Bu bloklarda asla backdrop-filter kullanılmaz. */
.form-control,
.form-select,
.form-control:disabled,
.input-group-text {
    background-color: var(--yg-well);
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius);
    box-shadow: var(--yg-well-inset);
    color: var(--yg-text);
    transition: border-color var(--yg-dur-color) ease, box-shadow var(--yg-dur-color) ease;
}

.form-control::placeholder {
    color: var(--yg-text-3);
    opacity: 1;
}

.form-control:focus,
.form-select:focus {
    background-color: var(--yg-well);
    border-color: var(--yg-info);
    box-shadow: var(--yg-well-inset), var(--yg-focus-ring);
    color: var(--yg-text);
}

.form-control:disabled,
.form-select:disabled {
    color: var(--yg-text-disabled);
    border-style: dashed;
    box-shadow: none;
}

.form-label {
    color: var(--yg-text-2);
    font-size: var(--yg-text-sm);
    font-weight: 500;
}

.form-text {
    color: var(--yg-text-3);
}

.form-check-input {
    background-color: var(--yg-well);
    border-color: var(--yg-g2-border);
    box-shadow: var(--yg-well-inset);
}

.form-check-input:checked {
    background-color: var(--yg-info);
    border-color: var(--yg-info);
}

.form-check-input:focus {
    border-color: var(--yg-info);
    box-shadow: var(--yg-focus-ring);
}

.form-check-label {
    color: var(--yg-text-2);
}

/* ── Native tarih/saat seçicileri ────────────────────────────────────────
   Açılan takvim/saat PANELİ tarayıcının kendi arayüzü: CSS ile giydirilemiyor,
   `::-webkit-datetime-*` yalnızca girdinin İÇİNİ verir. Elimizde iki gerçek
   kol var ve ikisini de kullanıyoruz:

     • `color-scheme: dark` → panel koyu gelir (aksi hâlde beyaz bir kutu),
     • `accent-color`      → panelde SEÇİLİ günün/saatin dolgusu. Chromium
       varsayılanı soluk bir sistem mavisi (#a8c7fa gibi) ve panelde marka
       rengiyle çakışıyordu; artık kendi info mavimiz.

   `accent-color` ayrıca onay kutusu, radyo ve `range` için de geçerli — o
   yüzden aşağıda tek yerden veriliyor.

   Takvim ikonu (`::-webkit-calendar-picker-indicator`) varsayılan olarak beyaz
   bir SVG maskesi: koyu oyukta kontrastı çok yüksek ve alanın en baskın öğesi
   oluyordu. Opaklıkla ikincil tona indiriliyor, üzerine gelince netleşiyor —
   tıklanabilir olduğu böyle anlaşılıyor. */
input[type='date'],
input[type='time'],
input[type='datetime-local'],
input[type='month'],
input[type='week'],
input[type='color'] {
    color-scheme: dark;
    accent-color: var(--yg-info);
}

input[type='checkbox'],
input[type='radio'],
input[type='range'] {
    accent-color: var(--yg-info);
}

input[type='date']::-webkit-calendar-picker-indicator,
input[type='time']::-webkit-calendar-picker-indicator,
input[type='datetime-local']::-webkit-calendar-picker-indicator,
input[type='month']::-webkit-calendar-picker-indicator {
    opacity: 0.45;
    cursor: pointer;
    padding: 2px;
    border-radius: var(--yg-radius-xs);
    transition: opacity var(--yg-dur-color) ease, background var(--yg-dur-color) ease;
}

input[type='date']:hover::-webkit-calendar-picker-indicator,
input[type='time']:hover::-webkit-calendar-picker-indicator,
input[type='datetime-local']:hover::-webkit-calendar-picker-indicator,
input[type='month']:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
    background: var(--yg-hover);
}

/* Boş tarih/saat alanının yer tutucusu ("gg.aa.yyyy") normal metinle aynı
   tonda geliyor ve DOLU bir alanla karıştırılıyordu; ipucu tonuna iniyor. */
input[type='date']::-webkit-datetime-edit,
input[type='time']::-webkit-datetime-edit,
input[type='datetime-local']::-webkit-datetime-edit {
    font-variant-numeric: tabular-nums;
}

input[type='date']:not(:focus)::-webkit-datetime-edit-text,
input[type='date']:not(:focus)::-webkit-datetime-edit-day-field:not([aria-valuenow]),
input[type='date']:not(:focus)::-webkit-datetime-edit-month-field:not([aria-valuenow]),
input[type='date']:not(:focus)::-webkit-datetime-edit-year-field:not([aria-valuenow]),
input[type='time']:not(:focus)::-webkit-datetime-edit-hour-field:not([aria-valuenow]),
input[type='time']:not(:focus)::-webkit-datetime-edit-minute-field:not([aria-valuenow]) {
    color: var(--yg-text-3);
}

/* Odaklanılan alt alan (gün/ay/yıl) seçili görünür — klavyeyle tarih girerken
   nerede olduğun belli olsun. */
input[type='date']::-webkit-datetime-edit-day-field:focus,
input[type='date']::-webkit-datetime-edit-month-field:focus,
input[type='date']::-webkit-datetime-edit-year-field:focus,
input[type='time']::-webkit-datetime-edit-hour-field:focus,
input[type='time']::-webkit-datetime-edit-minute-field:focus,
input[type='datetime-local']::-webkit-datetime-edit-day-field:focus,
input[type='datetime-local']::-webkit-datetime-edit-month-field:focus,
input[type='datetime-local']::-webkit-datetime-edit-year-field:focus,
input[type='datetime-local']::-webkit-datetime-edit-hour-field:focus,
input[type='datetime-local']::-webkit-datetime-edit-minute-field:focus {
    background: var(--yg-fill-info);
    color: var(--yg-info-soft);
    border-radius: 3px;
}

/* ── Düğmeler ─────────────────────────────────────────────────────────
   Birincil düğme AMBER, `--bs-primary` ise MAVİ — bu bilinçli bir
   tutarsızlık. Gerekçe: amber tasarım dilinde "tek eylem rengi" ama koyu
   zeminde metin/kenar/odak rengi olarak mavi daha okunur. Bootstrap 5.3
   düğmeleri varyant başına değişken okuduğu için ikisini ayırabiliyoruz.
   BU BLOK MAVİYE "DÜZELTİLMEMELİ". */
.btn-primary {
    --bs-btn-bg: var(--yg-action);
    --bs-btn-border-color: transparent;
    --bs-btn-color: var(--yg-on-action);
    --bs-btn-hover-bg: var(--yg-action-hi);
    --bs-btn-hover-border-color: transparent;
    --bs-btn-hover-color: var(--yg-on-action);
    --bs-btn-active-bg: var(--yg-action-pressed);
    --bs-btn-active-border-color: transparent;
    --bs-btn-active-color: var(--yg-on-action);
    --bs-btn-disabled-bg: rgba(var(--yg-action-rgb), 0.35);
    --bs-btn-disabled-border-color: transparent;
    --bs-btn-disabled-color: var(--yg-on-action-ring);
    box-shadow: 0 10px 26px -8px rgba(var(--yg-action-rgb), 0.5), var(--yg-on-action-sheen);
}

/* İkincil düğme = cam */
.btn-secondary,
.btn-light,
.btn-outline-secondary {
    --bs-btn-bg: var(--yg-g2-flat);
    --bs-btn-border-color: var(--yg-g2-border);
    --bs-btn-color: var(--yg-text);
    --bs-btn-hover-bg: var(--yg-active);
    --bs-btn-hover-border-color: var(--yg-g3-border);
    --bs-btn-hover-color: var(--yg-text);
    --bs-btn-active-bg: var(--yg-active);
    --bs-btn-active-border-color: var(--yg-g3-border);
    --bs-btn-active-color: var(--yg-text);
    --bs-btn-disabled-bg: var(--yg-fill-neutral);
    --bs-btn-disabled-border-color: var(--yg-hair);
    --bs-btn-disabled-color: var(--yg-text-disabled);
    backdrop-filter: var(--yg-g1-blur);
    -webkit-backdrop-filter: var(--yg-g1-blur);
    box-shadow: var(--yg-g2-sheen);
}

/* Outline varyantları koyu zeminde hayalet gibi kalıyor — okunur hale getir. */
.btn-outline-primary {
    --bs-btn-color: var(--yg-info-soft);
    --bs-btn-border-color: var(--yg-edge-info);
    --bs-btn-hover-bg: var(--yg-fill-info);
    --bs-btn-hover-border-color: var(--yg-info);
    --bs-btn-hover-color: var(--yg-text);
    --bs-btn-active-bg: var(--yg-fill-info);
    --bs-btn-active-border-color: var(--yg-info);
    --bs-btn-active-color: var(--yg-text);
}

.btn-outline-danger {
    --bs-btn-color: var(--yg-danger-soft);
    --bs-btn-border-color: var(--yg-edge-danger);
    --bs-btn-hover-bg: var(--yg-fill-danger);
    --bs-btn-hover-border-color: var(--yg-danger);
    --bs-btn-hover-color: var(--yg-text);
    --bs-btn-active-bg: var(--yg-fill-danger);
    --bs-btn-active-border-color: var(--yg-danger);
    --bs-btn-active-color: var(--yg-text);
}

.btn-outline-success {
    --bs-btn-color: var(--yg-live-soft);
    --bs-btn-border-color: var(--yg-edge-live);
    --bs-btn-hover-bg: var(--yg-fill-live);
    --bs-btn-hover-border-color: var(--yg-live);
    --bs-btn-hover-color: var(--yg-text);
    --bs-btn-active-bg: var(--yg-fill-live);
    --bs-btn-active-border-color: var(--yg-live);
    --bs-btn-active-color: var(--yg-text);
}

.btn {
    --bs-btn-border-radius: var(--yg-radius-sm);
    --bs-btn-font-weight: 500;
    transition: background-color var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        transform var(--yg-dur-press) var(--yg-ease-press), box-shadow var(--yg-dur-color) ease;
}

.btn:active {
    transform: scale(0.975);
}

/* ── Ayırıcı, kapatma, ipucu ───────────────────────────────────────────── */
.dropdown-divider,
.modal-header,
.modal-footer {
    border-color: var(--yg-hair);
}

.btn-close {
    --bs-btn-close-white-filter: 1;
    filter: var(--bs-btn-close-white-filter);
    opacity: 0.6;
}

.btn-close:hover {
    opacity: 1;
}

.tooltip {
    --bs-tooltip-bg: var(--yg-ink);
    --bs-tooltip-color: var(--yg-text);
    --bs-tooltip-border-radius: var(--yg-radius-sm);
    --bs-tooltip-opacity: 1;
}

.popover {
    --bs-popover-bg: var(--yg-g3-flat);
    --bs-popover-border-color: var(--yg-g3-border);
    --bs-popover-header-bg: transparent;
    --bs-popover-body-color: var(--yg-text-2);
}

/* ── Liste grubu (bugün kullanılmıyor ama bedava) ───────────────────────── */
.list-group {
    --bs-list-group-bg: transparent;
    --bs-list-group-color: var(--yg-text);
    --bs-list-group-border-color: var(--yg-hair);
    --bs-list-group-action-hover-bg: var(--yg-hover);
    --bs-list-group-action-hover-color: var(--yg-text);
    --bs-list-group-active-bg: var(--yg-fill-info);
    --bs-list-group-active-border-color: var(--yg-edge-info);
    --bs-list-group-active-color: var(--yg-info-soft);
}

/* ── Breadcrumb ────────────────────────────────────────────────────────── */
.breadcrumb {
    --bs-breadcrumb-divider-color: var(--yg-text-3);
    --bs-breadcrumb-item-active-color: var(--yg-text);
    --bs-breadcrumb-font-size: var(--yg-text-sm);
    margin: 0;
}

/* ── assets/css/yg/10-shell.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 10 — Kabuk
   --------------------------------------------------------------------------
   Sol menü, üst çubuk, ana içerik, alt bilgi, başa dön düğmesi.

   ÖNEMLİ: Sol menünün MARKUP'I DEĞİŞMİYOR. components/sidebar.blade.php
   `.modern-sidebar / .nav-link / .nav-submenu / .nav-group / .submenu-link`
   üretiyor ve bu sınıflar renk taşımıyor — kabuk yalnızca stylesheet
   değiştirilerek yeni dile geçiyor. public/js/shell.js de aynı sınıf
   sözleşmesine bağlı olduğu için hiçbir JS değişikliği gerekmiyor.
   ========================================================================== */

/* ── Izgara ────────────────────────────────────────────────────────────
   DİKKAT — burada `z-index` YOK ve olmamalı. Verilirse kabuk kendi yığın
   bağlamını (stacking context) açar; içindeki sidebar'ın z-index'i o bağlama
   HAPSOLUR ve kabuğun dışındaki mobil perde (z-index 19) sidebar'ın üstüne
   çıkar. Sonuç: çekmece açıldığında menü perdenin backdrop-filter'ı altında
   bulanık ve okunmaz kalıyor.

   `position: relative` + z-index auto yeterli: arka ışık (z-index 0) DOM'da
   önce geldiği için kabuk zaten onun üstüne boyanıyor, sidebar (20) ile perde
   (19) de aynı kök bağlamda doğru sırayla karşılaşıyor. */
.yg-shell {
    position: relative;
    display: grid;
    grid-template-columns: 266px minmax(0, 1fr);
    min-height: 100vh;
}

body.sidebar-collapsed .yg-shell {
    grid-template-columns: 96px minmax(0, 1fr);
}

.yg-main {
    min-width: 0;
    padding: 22px 30px 40px 18px;
    display: flex;
    flex-direction: column;
    gap: var(--yg-gap-lg);
}

/* ── Sol menü ──────────────────────────────────────────────────────────── */
.modern-sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    padding: 18px 12px 18px 18px;
    /* flex-direction ŞART: markup'ta başlık, nav ve gizli logout formu kardeş.
       Yön verilmezse yan yana dizilip nav 10px'e sıkışıyor ve menü kayboluyor. */
    display: flex;
    flex-direction: column;
    z-index: var(--yg-z-sidebar);
}

/* Cam panel sidebar'ın kendisinde değil, içindeki sarmalayıcıda: dış kutu
   yapışkan konumlanma için, iç kutu görünüm için. Sidebar markup'ında ek bir
   sarmalayıcı olmadığından ::before ile cam yüzeyi çiziyoruz. */
.modern-sidebar::before {
    content: '';
    position: absolute;
    inset: 18px 12px 18px 18px;
    border-radius: var(--yg-radius-2xl);
    background: var(--yg-sidebar-fill);
    backdrop-filter: var(--yg-sidebar-blur);
    -webkit-backdrop-filter: var(--yg-sidebar-blur);
    border: 1px solid var(--yg-sidebar-border);
    box-shadow: var(--yg-sidebar-shadow), var(--yg-sidebar-sheen);
    pointer-events: none;
}

/* `justify-content: space-between` ŞART: wordmark `flex: none` olduğu için
   satırın sonunda 48px ölü boşluk kalıyor, küçültme düğmesi de sağ kenara
   değil wordmark'ın hemen yanına — yani satırın ortasına — yapışıyordu.
   Sol boşluk 12px: wordmark böylece menü ikonlarıyla aynı çizgiden başlıyor. */
.sidebar-header {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 11px;
    padding: 8px 14px 16px 12px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--yg-hair);
}

.sidebar-logo {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
    color: var(--yg-text);
}

.sidebar-logo:hover {
    color: var(--yg-text);
}

/* ── Marka kilidi ──────────────────────────────────────────────────────
   GENİŞ durumda yalnızca yutomat kelime-işareti (wordmark) görünür; "Yutomat
   Yönetim" metni basılmaz. Metin görsel olarak yerini logoya bırakıyor:
   `font-size: 0` ile küçülüyor ama DOM'da ve erişilebilirlik ağacında KALIYOR
   — ekran okuyucu hâlâ "Yutomat Yönetim" okuyor, görsel olarak logo görünüyor.

   KÜÇÜLTÜLMÜŞ durumda wordmark okunmaz (96px'e sığmaz) ve marka satırı tamamen
   kalkıyor (aşağıya bakın); maskot kafası hiçbir durumda basılmıyor. */
.sidebar-logo .logo-text {
    position: relative;
    flex: none;
    /* Kutu logonun kendi oranında (1105×379 ≈ 2.92:1). Oran tutmazsa `contain`
       logoyu kısa kenara sıkıştırıp yanında ölü boşluk bırakıyor. */
    height: 40px;
    width: 117px;
    font-size: 0;
}

.sidebar-logo .logo-text::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('../../assets/image/yutomat-wordmark-white.png') left center / contain no-repeat;
}

.sidebar-toggle {
    flex: none;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius-xs);
    background: var(--yg-g1-flat);
    color: var(--yg-text-2);
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, color var(--yg-dur-color) ease;
}

.sidebar-toggle:hover {
    background: var(--yg-hover);
    color: var(--yg-text);
}

.sidebar-nav {
    position: relative;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0 4px 0 0;
}

.nav-menu {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.nav-item {
    position: relative;
}

/* Profil/Çıkış grubunu yukarıdaki modüllerden ayıran boşluk. Sidebar iki
   layout tarafından paylaşıldığı için aynı modifier legacy modern-sidebar.css
   içinde de tanımlı. */
.nav-item--spaced {
    margin-top: 2rem;
}

.nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: var(--yg-radius-sm);
    background: transparent;
    color: var(--yg-text-2);
    font: 400 13.5px / 1.2 var(--yg-sans);
    text-align: left;
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, color var(--yg-dur-color) ease;
}

.nav-link:hover {
    background: var(--yg-hover);
    color: var(--yg-text);
}

.nav-link .nav-icon {
    flex: none;
    width: 17px;
    text-align: center;
    opacity: 0.85;
}

.nav-link .nav-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Aktif satır: cam + sol kenarda ışık şeridi (bilgi rengi = navigasyon) */
.nav-link.active {
    color: var(--yg-text);
    background: var(--yg-g2-fill);
    box-shadow: var(--yg-g2-sheen);
}

.nav-link.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 9px;
    bottom: 9px;
    width: 2px;
    border-radius: 2px;
    background: var(--yg-info);
    box-shadow: 0 0 10px 1px rgba(var(--yg-info-rgb), 0.7);
}

.nav-arrow {
    margin-left: auto;
    font-size: 11px;
    opacity: 0.5;
    transition: transform var(--yg-dur-color) ease;
}

.nav-group.open > .nav-group-toggle .nav-arrow {
    transform: rotate(180deg);
}

.nav-submenu {
    display: none;
    flex-direction: column;
    gap: 2px;
    margin: 2px 0 6px 15px;
    padding-left: 12px;
    border-left: 1px solid var(--yg-hair);
}

.nav-group.open > .nav-submenu {
    display: flex;
}

.submenu-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--yg-radius-xs);
    color: var(--yg-text-2);
    font: 400 12.5px / 1.25 var(--yg-sans);
    transition: background var(--yg-dur-color) ease, color var(--yg-dur-color) ease;
}

.submenu-link:hover {
    background: var(--yg-hover);
    color: var(--yg-text);
}

.submenu-link .nav-icon {
    flex: none;
    width: 15px;
    text-align: center;
    opacity: 0.7;
}

.submenu-link.active {
    background: var(--yg-g1-flat);
    color: var(--yg-text);
    box-shadow: inset 0 0 0 1px var(--yg-hair);
}

/* Küçültülmüş durum — metinler gizlenir, ipucu balonu görünür */
.modern-sidebar.collapsed .nav-text,
.modern-sidebar.collapsed .nav-arrow {
    display: none;
}

.modern-sidebar.collapsed .nav-link,
.modern-sidebar.collapsed .submenu-link {
    justify-content: center;
    padding: 12px 8px;
}

.modern-sidebar.collapsed .nav-submenu {
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
}

/* Küçültülmüş başlık: 96px'lik panele wordmark sığmıyor, marka satırı tamamen
   kalkıyor ve yalnızca küçültme düğmesi ortada kalıyor.

   Önce maskot kafası wordmark'ın yerine geçiyor, başlık da dikey yığılıyordu:
   düğmenin üstünde tek başına duran kafa menünün parçası gibi değil, panele
   yapıştırılmış bir çıkartma gibi okunuyordu. Dashboard bağlantısı menünün ilk
   maddesinde zaten var, marka satırı burada bilgi taşımıyor. */
.modern-sidebar.collapsed .sidebar-logo {
    display: none;
}

.modern-sidebar.collapsed .sidebar-header {
    justify-content: center;
    padding: 8px 0 16px;
}

/* Küçültülmüş menü ipucu balonu — konumu public/js/shell.js veriyor.
   CSS-only `::after` çözümü kullanılamıyor: .sidebar-nav'ın overflow-y:auto
   değeri yatayda da kırpıyor ve balon hiç görünmüyor (legacy panelde de öyle).
   Balon body'nin altında yaşadığı için burada `position: fixed`. */
.yg-nav-tip {
    position: fixed;
    z-index: var(--yg-z-toast);
    transform: translateY(-50%);
    padding: 8px 12px;
    border-radius: var(--yg-radius-xs);
    background: var(--yg-ink);
    border: 1px solid var(--yg-hair);
    color: var(--yg-text);
    font: 400 12px / 1 var(--yg-sans);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--yg-dur-press) ease, visibility var(--yg-dur-press) ease;
}

.yg-nav-tip.is-visible {
    opacity: 1;
    visibility: visible;
}

/* ── Üst çubuk ─────────────────────────────────────────────────────────── */
.yg-topbar {
    display: flex;
    align-items: center;
    gap: var(--yg-gap);
    flex-wrap: wrap;
}

.yg-topbar__right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
}

.breadcrumb-nav {
    display: flex;
    align-items: center;
    font-size: var(--yg-text-sm);
}

.breadcrumb-nav .breadcrumb {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    color: var(--yg-text-3);
}

.breadcrumb-nav .breadcrumb-item a {
    color: var(--yg-text-2);
}

.breadcrumb-nav .breadcrumb-item a:hover {
    color: var(--yg-text);
}

.breadcrumb-nav .breadcrumb-item.active {
    color: var(--yg-text);
    font-weight: 500;
}

.yg-avatar {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: var(--yg-radius-sm);
    display: grid;
    place-items: center;
    background: var(--yg-g3-fill);
    border: 1px solid var(--yg-g3-border);
    box-shadow: var(--yg-g3-sheen);
    font: 600 13px / 1 var(--yg-display);
    color: var(--yg-text);
}

/* ── Mobil ─────────────────────────────────────────────────────────────── */
.yg-mobile-toggle {
    display: none;
    position: fixed;
    top: 14px;
    left: 14px;
    z-index: calc(var(--yg-z-sidebar) + 2);
    width: 44px;
    height: 44px;
    border-radius: var(--yg-radius-sm);
    border: 1px solid var(--yg-g2-border);
    background: var(--yg-g3-flat);
    backdrop-filter: var(--yg-g2-blur);
    -webkit-backdrop-filter: var(--yg-g2-blur);
    color: var(--yg-text);
    cursor: pointer;
}

.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: calc(var(--yg-z-sidebar) - 1);
    background: var(--yg-scrim);
    backdrop-filter: var(--yg-scrim-blur);
    -webkit-backdrop-filter: var(--yg-scrim-blur);
}

.sidebar-backdrop.show {
    display: block;
}

/* ── Alt bilgi ─────────────────────────────────────────────────────────
   Markup components/app-footer.blade.php'de ve DEĞİŞMİYOR — sınıf adları
   aynı kaldığı için o dosyaya dokunmadan yalnızca deri değişiyor. */
.app-footer {
    margin-top: auto;
    padding-top: 20px;
    border-top: 1px solid var(--yg-hair);
}

.app-footer-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px;
    font: 400 11.5px / 1.5 var(--yg-mono);
    color: var(--yg-text-3);
}

.app-footer-sep {
    opacity: 0.5;
}

.app-footer-brand {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.app-footer-powered {
    font-size: 10.5px;
    letter-spacing: 0.04em;
}

/* STN logosu koyu zeminde: gri tonlanıp aydınlatılıyor, yoksa lacivert
   wordmark void üstünde kayboluyor. */
.app-footer-logo {
    height: 14px;
    width: auto;
    opacity: 0.6;
    filter: grayscale(1) brightness(2.4);
    transition: opacity var(--yg-dur-color) ease;
}

.app-footer-logo:hover {
    opacity: 1;
}

.app-footer-logo-fallback {
    letter-spacing: 0.08em;
    color: var(--yg-text-3);
}

/* ── Başa dön ──────────────────────────────────────────────────────────── */
.yg-to-top {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: var(--yg-z-sidebar);
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: var(--yg-radius-sm);
    border: 1px solid var(--yg-g2-border);
    background: var(--yg-g2-fill);
    backdrop-filter: var(--yg-g2-blur);
    -webkit-backdrop-filter: var(--yg-g2-blur);
    box-shadow: var(--yg-g2-shadow), var(--yg-g2-sheen);
    color: var(--yg-text);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity var(--yg-dur-color) ease, transform var(--yg-dur-color) ease,
        visibility var(--yg-dur-color) ease;
}

.yg-to-top.visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* ── Duyarlı ───────────────────────────────────────────────────────────── */
@media (max-width: 992px) {
    .yg-main {
        padding: 22px 20px 40px;
    }
}

@media (max-width: 768px) {
    .yg-shell,
    body.sidebar-collapsed .yg-shell {
        grid-template-columns: minmax(0, 1fr);
    }

    .yg-mobile-toggle {
        display: grid;
        place-items: center;
    }

    .modern-sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        width: 280px;
        height: 100vh;
        transform: translateX(-100%);
        transition: transform var(--yg-dur-color) var(--yg-ease-sheet);
    }

    .modern-sidebar.mobile-open {
        transform: translateX(0);
    }

    /* Çekmece açıkken arkadaki sayfa kaymasın. Sınıfı public/js/shell.js
       body'ye ekliyor. Legacy'de `position: fixed` de vardı; onunla birlikte
       çekmece kapanınca sayfa en başa dönüyordu, bu yüzden yalnızca taşma
       kilitleniyor. */
    body.sidebar-open {
        overflow: hidden;
    }

    .yg-main {
        padding: 70px 16px 36px;
    }

    /* Küçültme düğmesi mobilde ANLAMSIZ: çekmece tam genişlikte açılıyor ve
       aşağıda tüm küçültme etkileri geri alınıyor, yani düğme hiçbir şey
       yapmıyordu. Kapatma işini sol üstteki çekmece düğmesi görüyor. */
    .sidebar-toggle {
        display: none;
    }

    /* Çekmece açıkken mobil düğme logonun üstüne binmesin. */
    .sidebar-header {
        padding-left: 62px;
    }

    /* Mobilde küçültme durumu anlamsız — çekmece tam genişlikte açılır.
       Masaüstünde bırakılmış `collapsed` durumu localStorage'dan geldiği için
       burada TÜM küçültme etkileri geri alınıyor; yoksa çekmece ikon-only
       açılıyor ya da alt menü girintisi kaybolup hiyerarşi düzleşiyor. */
    .modern-sidebar.collapsed .nav-text {
        display: initial;
    }

    .modern-sidebar.collapsed .sidebar-logo {
        display: flex;
    }

    .modern-sidebar.collapsed .nav-arrow {
        display: block;
    }

    .modern-sidebar.collapsed .nav-link,
    .modern-sidebar.collapsed .submenu-link {
        justify-content: flex-start;
        padding: 10px 12px;
    }

    .modern-sidebar.collapsed .nav-submenu {
        margin-left: 15px;
        padding-left: 12px;
        border-left: 1px solid var(--yg-hair);
    }

    .modern-sidebar.collapsed .sidebar-header {
        justify-content: space-between;
        padding: 8px 14px 16px 62px;
    }
}

/* ── assets/css/yg/20-components/card.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — kart ve ışık şeridi
   --------------------------------------------------------------------------
   Cam üç kademede (tier 1/2/3), dört katmanda: bulanıklık + 155° dolgu +
   1px kenar + inset üst parlaklık. Üst kenardaki 2px ışık şeridi DURUM taşır,
   süs değil.

   ── DURUM DESENİ (OCP) ────────────────────────────────────────────────────
   Kart iki değişken set eder, alt bileşenler onları tüketir:
     --yg-state       dolgu/şerit/halka rengi
     --yg-state-text  METİN rengi (AA geçen "-soft" tonu)
   Yeni bir durum eklemek = iki satır. Bileşenler renk adı bilmez.

   ── PROTOTİPTEN BİLİNÇLİ SAPMA: overflow ─────────────────────────────────
   Prototip `.g1/.g2/.g3` üzerinde `overflow:hidden` kullanıyordu (şeridin
   köşeleri yuvarlansın diye). Panelde bu KIRICI: 236 modal kullanımı, kart
   içinde açılır menüler var; `overflow:hidden` menüleri kırpar ve
   `position:fixed` alt öğeler için yeni bir containing block yaratır.
   Bunun yerine şerit kırpma kabı kullanıyor (aşağıda anlatılıyor); gerçekten
   kart düzeyinde kırpma gerektiren yerler `.yg-card--clip` ile işaretlenir.
   ========================================================================== */

.yg-card {
    --yg-state: var(--yg-text);
    --yg-state-glow: rgba(var(--yg-text-rgb), 0.5);
    /* --yg-state DOLGU/ŞERİT rengi; METİN için ayrı token gerekiyor.
       Nedeni: `idle` durumunda --yg-state saç-teli beyazı (%9 opak) ve o rengi
       metne vermek yazıyı okunmaz yapıyor (503 sayfasında kod kayboluyordu).
       -text varyantları AA geçen "-soft" tonları. */
    --yg-state-text: var(--yg-text);

    position: relative;
    overflow: visible;
    border-radius: var(--yg-radius-lg);
    background: var(--yg-g2-fill);
    backdrop-filter: var(--yg-g2-blur);
    -webkit-backdrop-filter: var(--yg-g2-blur);
    border: 1px solid var(--yg-g2-border);
    box-shadow: var(--yg-g2-shadow), var(--yg-g2-sheen);
}

/* Kademeler */
.yg-card--1 {
    border-radius: var(--yg-radius);
    background: var(--yg-g1-fill);
    backdrop-filter: var(--yg-g1-blur);
    -webkit-backdrop-filter: var(--yg-g1-blur);
    border-color: var(--yg-g1-border);
    box-shadow: var(--yg-g1-shadow), var(--yg-g1-sheen);
}

.yg-card--3 {
    border-radius: var(--yg-radius-xl);
    background: var(--yg-g3-fill);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    border-color: var(--yg-g3-border);
    box-shadow: var(--yg-g3-shadow), var(--yg-g3-sheen);
}

/* Cam üstüne cam üstüne cam yasak: üçüncü katmanda hiyerarşi ölüyor ve her
   blur katmanı ayrı bir compositor katmanı + backdrop okuması demek.
   Bu kural bir "guard rail" — bağlama bağlı olduğu için OCP'den muaf. */
.yg-card .yg-card .yg-card {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--yg-g1-flat);
}

.yg-card--clip {
    overflow: hidden;
}

.yg-card--flat {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--yg-g2-flat);
}

/* ── Işık şeridi ───────────────────────────────────────────────────────
   Şerit, KENDİSİ 2px olan bir çizgi değil; 2px'lik çizgiyi barındıran bir
   KIRPMA KABI. Nedeni tarayıcı davranışı: `border-radius` bir kutunun
   yüksekliğini aşarsa oransal olarak kırpılıyor, yani 2px yüksekliğinde bir
   öğede 22px yarıçap ~2px'e düşüyor ve şerit düz bir çubuk olarak kartın
   kıvrımlı köşelerinin DIŞINA taşıyor (22px yarıçapta her iki yanda ~15px).

   Kabın yüksekliğini yarıçap kadar verip `overflow: hidden` uygulayınca
   yarıçap kırpılmıyor ve içindeki çizgi kartın kıvrımına uyuyor. Kap
   `position: absolute` olduğu için akışta yer kaplamıyor; kartın kendisine
   `overflow: hidden` vermek gerekmiyor (o çözüm kart içindeki açılır menüleri
   ve modal'ları kırpardı — bkz. dosya başlığı). */
.yg-card__strip {
    --yg-strip-clip: var(--yg-radius-lg);

    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--yg-strip-clip);
    border-radius: var(--yg-strip-clip) var(--yg-strip-clip) 0 0;
    overflow: hidden;
    pointer-events: none;
}

.yg-card__strip::before {
    content: '';
    display: block;
    height: 2px;
    background: var(--yg-strip-neutral);
}

.yg-card--1 > .yg-card__strip {
    --yg-strip-clip: var(--yg-radius);
}

.yg-card--3 > .yg-card__strip {
    --yg-strip-clip: var(--yg-radius-xl);
}

/* ── Durum sözleşmesi ───────────────────────────────────────────────────
   Işık şeridini taşıyan tek yüzey kart değil: modal da taşıyor ve modal
   markup'ını Bootstrap basıyor (kendi `.yg-*` bloğu yok, bkz.
   03-bootstrap-bridge.css). Beş durumu orada tekrar yazmak yerine host listesi
   `:where()` ile veriliyor — `:where()` özgüllüğü sıfırladığı için toplam yine
   (0,1,0) kalıyor, yani `.yg-pill[data-yg-status='live']` gibi kendi durumunu
   tanımlayan bileşenler bunu ezmeye devam ediyor. */
:where(.yg-card, .modal-content)[data-yg-status='live'] {
    --yg-state: var(--yg-live);
    --yg-state-text: var(--yg-live-soft);
    --yg-state-glow: rgba(var(--yg-live-rgb), 0.6);
}

:where(.yg-card, .modal-content)[data-yg-status='warn'] {
    --yg-state: var(--yg-action);
    --yg-state-text: var(--yg-action-soft);
    --yg-state-glow: rgba(var(--yg-action-rgb), 0.6);
}

:where(.yg-card, .modal-content)[data-yg-status='danger'] {
    --yg-state: var(--yg-danger);
    --yg-state-text: var(--yg-danger-soft);
    --yg-state-glow: rgba(var(--yg-danger-rgb), 0.6);
}

:where(.yg-card, .modal-content)[data-yg-status='info'] {
    --yg-state: var(--yg-info);
    --yg-state-text: var(--yg-info-soft);
    --yg-state-glow: rgba(var(--yg-info-rgb), 0.55);
}

:where(.yg-card, .modal-content)[data-yg-status='idle'] {
    --yg-state: var(--yg-hair);
    --yg-state-text: var(--yg-text-3);
    --yg-state-glow: transparent;
}

/* Durumlu şerit: renk + ışıma. Nötr şerit beyaz gradyan kalır. */
:where(.yg-card, .modal-content):not([data-yg-status='neutral']) > .yg-card__strip::before {
    background: var(--yg-state);
    box-shadow: 0 0 14px 1px var(--yg-state-glow);
}

/* Yükleniyor: akan ışık. Dönen çark yok — sayfanın canlı olduğunu söyleyen
   tek işaret bu şerit. */
:where(.yg-card, .modal-content)[data-yg-status='flow'] > .yg-card__strip::before {
    background: var(--yg-hair);
    box-shadow: none;
}

:where(.yg-card, .modal-content)[data-yg-status='flow'] > .yg-card__strip::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    height: 2px;
    width: 32%;
    background: linear-gradient(90deg, transparent, var(--yg-info), transparent);
    animation: ygFlow 1.5s linear infinite;
}

/* ── Gövde ─────────────────────────────────────────────────────────────── */
.yg-card__body {
    padding: var(--yg-pad-card);
    display: flex;
    flex-direction: column;
    gap: var(--yg-gap);
}

.yg-card__body--tight {
    padding: 14px 16px;
    gap: var(--yg-gap-sm);
}

.yg-card__body--flush {
    padding: 0;
    gap: 0;
}

.yg-card__head {
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
    flex-wrap: wrap;
    padding: 16px 22px;
    border-bottom: 1px solid var(--yg-hair);
}

/* İkon + metin: `.yg-card__head` bir flex kap olduğu için başlığın içindeki
   boşluk karakteri güvenilir değil (flex, yalnızca-boşluk metin düğümlerini
   atıyor ve başlık kırıldığında ikon metne yapışıyor). Boşluk bloğun kuralı. */
.yg-card__title {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin: 0;
    font: 600 var(--yg-text-lg) / 1.25 var(--yg-display);
    letter-spacing: -0.015em;
}

.yg-card__title i {
    font-size: 0.82em;
    color: var(--yg-text-3);
}

/* Başlık + altına bir cümle. Kart başlığının yanında sağa yaslı bir kontrol
   (anahtar, düğme) varken bu sarmalayıcı gerekiyor: `.yg-card__head` bir flex
   satırı, başlık ile açıklama onun iki ayrı çocuğu olsa kontrol araya girer.
   `min-width: 0` + `flex: 1 1 240px`: uzun açıklama sararak büyür, dar ekranda
   kontrolü alt satıra iter (kırpmaz). */
.yg-card__heading {
    flex: 1 1 240px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.yg-card__subtitle {
    font: 300 var(--yg-text-sm) / 1.5 var(--yg-sans);
    color: var(--yg-text-3);
    max-width: 76ch;
    text-wrap: pretty;
}

.yg-card__foot {
    padding: 14px 22px;
    border-top: 1px solid var(--yg-hair);
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
    flex-wrap: wrap;
}

/* ── assets/css/yg/20-components/stat.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — ölçü kartı (KPI)
   --------------------------------------------------------------------------
   Panelde bugün AYNI görsel iş için beş ayrı sınıf var:
     .stat-card-modern · .stat-card-dash · .analytics-stat-card
     .order-stat-card  · .stat-card
   Hepsinin yerini bu blok alıyor. Kart yüzeyini .yg-card sağlar (ISP: küçük
   bileşenler kompoze edilir, mega bileşen yok) — burada yalnızca içerik dizilimi.
   ========================================================================== */

.yg-stat {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 18px 20px 20px;
}

.yg-stat__top {
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
}

.yg-stat__icon {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: var(--yg-radius-sm);
    display: grid;
    place-items: center;
    background: var(--yg-fill-neutral);
    border: 1px solid var(--yg-edge-neutral);
    color: var(--yg-text-2);
    font-size: 14px;
}

/* Durumlu kartta ikon da durumu taşır — renk kartın --yg-state'inden gelir,
   ikon kendi rengini bilmez. */
.yg-card:not([data-yg-status='neutral']) .yg-stat__icon {
    background: color-mix(in srgb, var(--yg-state) 16%, transparent);
    border-color: color-mix(in srgb, var(--yg-state) 30%, transparent);
    color: var(--yg-state);
}

.yg-stat__label {
    /* 1.2 Türkçe büyük harf işaretleri için sınırda; 1.45 pay bırakıyor. */
    font: 500 11.5px / 1.45 var(--yg-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--yg-text-3);
}

/* Dönem/kapsam etiketi (ör. "17.08.2026", "Ağustos 2026") — üst satırın SAĞ
   ucunda. Kartın altına konursa flex kolonda tam genişliğe yayılıyor ve
   ölçünün kendisinden daha baskın görünüyor; oysa bu bir alt bilgi: sayının
   HANGİ ARALIĞA ait olduğunu söylüyor. */
.yg-stat__meta {
    margin-left: auto;
    flex: none;
}

.yg-stat__value {
    display: flex;
    align-items: baseline;
    gap: 7px;
    flex-wrap: wrap;
    font: 600 30px / 1 var(--yg-display);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.yg-card:not([data-yg-status='neutral']) .yg-stat__value {
    color: var(--yg-state-text);
}

/* "7/482" gibi paylı gösterimde payda ikincil kalır */
.yg-stat__of {
    font: 500 13px / 1 var(--yg-mono);
    color: var(--yg-text-3);
}

.yg-stat__pct {
    font: 500 11px / 1 var(--yg-mono);
    padding: 4px 7px;
    border-radius: var(--yg-radius-xs);
    background: color-mix(in srgb, var(--yg-state) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--yg-state) 30%, transparent);
}

.yg-stat__sub {
    font: 300 var(--yg-text-sm) / 1.4 var(--yg-sans);
    color: var(--yg-text-3);
}

/* Trend göstergesi — yön ok ile de verilir, yalnızca renkle değil
   (renk körlüğü ve forced-colors için). */
.yg-stat__trend {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font: 500 11.5px / 1 var(--yg-mono);
}

.yg-stat__trend--up {
    color: var(--yg-live-soft);
}

.yg-stat__trend--down {
    color: var(--yg-danger-soft);
}

/* Tıklanabilir ölçü kartı — etkileşimli olan etkileşimli görünür */
a.yg-stat,
.yg-stat--link {
    text-decoration: none;
    color: inherit;
    transition: transform var(--yg-dur-press) var(--yg-ease-press);
}

a.yg-stat:hover,
.yg-stat--link:hover {
    transform: translateY(-2px);
}

/* ── assets/css/yg/20-components/pill.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — durum etiketi, nokta, çip
   --------------------------------------------------------------------------
   Panelde ~180 `badge bg-*-subtle text-*` kullanımı var; Bootstrap köprüsü
   onları otomatik uyarlıyor. Bu blok, YENİ yazılan markup'ın kullandığı
   yerli etiket: mono tipografi, durum noktası ve tek `data-yg-status` girişi.

   Durum yalnızca renkle verilmez — nokta + metin birlikte taşır. forced-colors
   modunda ve renk körlüğünde renk kaybolduğunda etiket yine okunur.
   ========================================================================== */

.yg-pill {
    --yg-state: var(--yg-text);
    --yg-state-fill: var(--yg-fill-neutral);
    --yg-state-edge: var(--yg-edge-neutral);

    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 10px;
    border-radius: var(--yg-radius-xs);
    background: var(--yg-state-fill);
    border: 1px solid var(--yg-state-edge);
    color: var(--yg-state);
    font: 500 10.5px / 1.35 var(--yg-mono);
    letter-spacing: 0.07em;
    white-space: nowrap;
    max-width: 100%;
}

.yg-pill[data-yg-status='live'] {
    --yg-state: var(--yg-live-soft);
    --yg-state-fill: var(--yg-fill-live);
    --yg-state-edge: var(--yg-edge-live);
}

.yg-pill[data-yg-status='warn'] {
    --yg-state: var(--yg-action-soft);
    --yg-state-fill: var(--yg-fill-action);
    --yg-state-edge: var(--yg-edge-action);
}

.yg-pill[data-yg-status='danger'] {
    --yg-state: var(--yg-danger-soft);
    --yg-state-fill: var(--yg-fill-danger);
    --yg-state-edge: var(--yg-edge-danger);
}

.yg-pill[data-yg-status='info'] {
    --yg-state: var(--yg-info-soft);
    --yg-state-fill: var(--yg-fill-info);
    --yg-state-edge: var(--yg-edge-info);
}

.yg-pill[data-yg-status='idle'] {
    --yg-state: var(--yg-text-3);
    --yg-state-fill: var(--yg-faint);
    --yg-state-edge: var(--yg-hair);
}

/* Opak (solid) varyant — yalnızca dikkat çekmesi zorunlu tek etikette */
.yg-pill--solid {
    background: var(--yg-state);
    border-color: transparent;
    color: var(--yg-void);
}

.yg-pill--dashed {
    background: transparent;
    border-style: dashed;
}

/* ── Durum noktası ─────────────────────────────────────────────────────── */
.yg-dot {
    flex: none;
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.yg-dot--lg {
    width: 8px;
    height: 8px;
}

/* Nefes alan nokta = canlı durum. Yalnızca gerçekten canlı veride kullanılır. */
.yg-dot--pulse {
    animation: ygBreathe 1.8s ease-in-out infinite;
}

/* ── Çip ───────────────────────────────────────────────────────────────
   Filtre/meta bilgisi taşıyan küçük cam yüzey. Etiketten farkı: durum
   taşımaz, bilgi taşır. */
/* R8: `backdrop-filter` YOK. Çip tablo hücresinde tekrarlanan bir öğe (26
   kullanıcı × rol/organizasyon çipi = 30+ ayrı compositor katmanı) ve dilin
   kuralı tekrarlanan öğeye blur vermiyor: kap bulanıklaştırır, satır değil.
   Düz dolgu (`--yg-g1-flat`) aynı görünümü katman maliyeti olmadan veriyor. */
.yg-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--yg-radius-sm);
    background: var(--yg-g1-flat);
    border: 1px solid var(--yg-g1-border);
    color: var(--yg-text-2);
    font: 400 12px / 1.3 var(--yg-sans);
    white-space: nowrap;
}

.yg-chip--mono {
    font: 500 11px / 1 var(--yg-mono);
    letter-spacing: 0.06em;
}

.yg-chip--active {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

/* Kaldırılabilir çip — düğme gerçekten düğme olur, etiket düğme yapılmaz */
.yg-chip__remove {
    display: grid;
    place-items: center;
    width: 16px;
    height: 16px;
    border: 0;
    border-radius: 50%;
    background: rgba(var(--yg-text-rgb), 0.12);
    color: inherit;
    font-size: 9px;
    cursor: pointer;
}

.yg-chip__remove:hover {
    background: rgba(var(--yg-danger-rgb), 0.28);
    color: var(--yg-danger-soft);
}

/* Tıklanabilir çip: bir sayıyı gösterip ilgili ekrana götürüyor (reklam atama
   sayısı gibi). Düğme olduğu belli olsun diye imleç ve hover durumu var —
   `.yg-chip` tek başına statik bir etikettir. */
.yg-chip--action {
    border: 1px solid var(--yg-g1-border);
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        color var(--yg-dur-color) ease;
}

.yg-chip--action:hover {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

/* ── assets/css/yg/20-components/table.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — tablo
   --------------------------------------------------------------------------
   Panelde sekiz ayrı tablo sınıfı var (.um-table, .log-table, .sr-table,
   .notif-table, .filo-table, .products-table, .analytics-table,
   .top-products-table). Hepsinin yerini bu blok alıyor.

   Kaydırma: geniş tablo KENDİ kabında yatay kayar, sayfa gövdesi asla yana
   kaymaz. Satırlar DÜZ yüzey — blur'lu satır yasak (200 satırlık tabloda her
   satır ayrı compositor katmanı olur, kaydırma çöker).
   ========================================================================== */

.yg-table-wrap {
    overflow-x: auto;
    /* iOS'ta momentum kaydırma cam kenarını kırpmasın */
    -webkit-overflow-scrolling: touch;
}

/* `min-width` bir TABAN, hedef değil: geniş veri tablolarında sütunların
   sıkışıp metni beş satıra bölmesi yerine kabın yatay kaydırmasını tercih
   ediyoruz. Ama taban knob — dar bir kartta duran 4 sütunlu liste 560px'i
   istemiyor ve o taban yüzünden son sütunu ekran dışına atıyordu. */
.yg-table {
    width: 100%;
    min-width: var(--yg-table-min, 560px);
    border-collapse: collapse;
    font-size: 13.5px;
}

/* Türkçe büyük harf: satır yüksekliği 1 verilirse Ö/Ü/İ işaretleri cap-height'ın
   üstüne taştığı için kırpan bir kapta (tablo sarmalayıcısının overflow'u gibi)
   kesiliyor ve "DÖNEM" ekranda "DONEM" görünüyordu. Büyük harfli etiketlerde
   satır yüksekliği asla 1 olmaz. */
.yg-table th {
    padding: 3px 14px 11px;
    border-bottom: 1px solid var(--yg-hair);
    font: 500 10.5px / 1.5 var(--yg-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--yg-text-3);
    text-align: left;
    white-space: nowrap;
}

.yg-table td {
    padding: 13px 14px;
    border-bottom: 1px solid rgba(var(--yg-text-rgb), 0.055);
    font: 400 13.5px / 1.35 var(--yg-sans);
    vertical-align: middle;
}

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

.yg-table tbody tr:hover td {
    background: var(--yg-row-hover);
}

/* Klavye kullanıcısı için satır vurgusu */
.yg-table tbody tr:focus-within td {
    background: rgba(var(--yg-info-rgb), 0.08);
}

/* Hizalama ve sayı biçimi — sayı taşıyan kolon mono + tabular olmak zorunda,
   yoksa kolonlar hizalanmıyor. */
.yg-table th[data-align='right'],
.yg-table td[data-align='right'],
.yg-table .yg-table__num {
    text-align: right;
}

.yg-table th[data-align='center'],
.yg-table td[data-align='center'] {
    text-align: center;
}

.yg-table__num,
.yg-table__mono {
    font-family: var(--yg-mono);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.yg-table__num--strong {
    font-weight: 700;
    color: var(--yg-text);
}

.yg-table__muted td,
.yg-table tr.yg-table__muted td {
    color: var(--yg-text-3);
}

/* Sıralanabilir başlık — etkileşimli olan etkileşimli görünür */
.yg-table th.yg-table__sortable {
    cursor: pointer;
    user-select: none;
    transition: color var(--yg-dur-color) ease;
}

.yg-table th.yg-table__sortable:hover {
    color: var(--yg-text);
}

.yg-table th.yg-table__sortable[aria-sort='ascending'],
.yg-table th.yg-table__sortable[aria-sort='descending'] {
    color: var(--yg-info-soft);
}

.yg-table__sort-ind {
    display: inline-block;
    margin-left: 5px;
    opacity: 0.5;
}

th[aria-sort='ascending'] .yg-table__sort-ind,
th[aria-sort='descending'] .yg-table__sort-ind {
    opacity: 1;
}

/* Yapışkan başlık — uzun tablolarda başlık kaybolmasın */
.yg-table--sticky thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    /* Cam kartın içinde yapışkan başlık: düz koyu dolgu gerekiyor, yoksa
       kayan satırlar başlığın arkasından görünüyor. */
    background: var(--yg-ink-raised);
}

/* Boş durum satırı */
.yg-table__empty td {
    padding: 0;
    border-bottom: 0;
}

/* ── Yığılan varyant ────────────────────────────────────────────────────
   `--stack`: dar ekranda tablo başlığı kalkar ve her satır kendi kartına
   dönüşür; hücre etiketi `data-label` niteliğinden okunur. Sütun düşürmeye
   (`display: none`) tercih edilir çünkü BİLGİ KAYBI YOK — beş CRUD sayfasında
   her hücre bir alan ve hiçbiri atılabilir değil.

   Legacy `um-table` bu deseni zaten kullanıyordu; markup'taki `data-label`
   nitelikleri korunduğu için sayfa geçince davranış birebir aynı kalıyor. */
@media (max-width: 820px) {
    .yg-table--stack thead {
        display: none;
    }

    .yg-table--stack tbody tr {
        display: block;
        margin-bottom: 10px;
        padding: 6px;
        border: 1px solid var(--yg-g1-border);
        border-radius: var(--yg-radius-sm);
        background: var(--yg-g1-flat);
    }

    .yg-table--stack tbody tr:last-child {
        margin-bottom: 0;
    }

    .yg-table--stack tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--yg-gap-sm);
        padding: 6px 8px;
        border-bottom: 0;
        text-align: left;
    }

    /* Etiket mono ve büyük harf: satır kartı içinde alan adı ile değeri
       ayırmanın tek işareti bu. Satır yüksekliği 1 DEĞİL — Türkçe büyük harfte
       Ö/Ü/İ işaretleri kap tarafından kırpılıyor (bkz. R10 notu). */
    .yg-table--stack tbody td::before {
        content: attr(data-label);
        font: 500 10px / 1.5 var(--yg-mono);
        letter-spacing: var(--yg-tracking-label);
        text-transform: uppercase;
        color: var(--yg-text-3);
        flex-shrink: 0;
    }

    /* Etiketi olmayan hücre (eylem düğmeleri) sağa yapışır. */
    .yg-table--stack tbody td:not([data-label]) {
        justify-content: flex-end;
    }
}

/* ── Sıkı varyant ───────────────────────────────────────────────────────
   Modal içindeki düzenleme tabloları: satır yüksekliği düşer, tipografi
   küçülür. Kutu modeli aynı kalır (LSP) — yalnızca dolgu ve punto değişir. */
/* Sıkı tablo tanımı gereği dar kaplarda yaşıyor (modal, yan kart): tabanı
   düşüyor. Sütunlar hâlâ içeriklerinin altına sıkışamıyor, yalnızca yapay
   taban kalkıyor. */
.yg-table--compact {
    --yg-table-min: 380px;
}

.yg-table--compact th,
.yg-table--compact td {
    padding: 8px 10px;
}

.yg-table--compact td {
    font-size: 12.5px;
}

/* Başlığın harf aralığı da kısılır ve sarmasına izin verilir. Gerekçe ölçüldü:
   mono + `uppercase` + 0.12em ile "ORGANİZASYON" TEK KELİME olarak 251px
   istiyor ve dar bir kartta (grafik yanındaki liste) sütunu şişirip son
   sütunu ekran dışına atıyor. Sarmaya izin verince sütun içeriğin gerçek
   genişliğine düşüyor; iki satırlık başlık okunurluğu bozmuyor çünkü satır
   yüksekliği 1 değil (üstteki Türkçe büyük harf notu). */
.yg-table--compact th {
    letter-spacing: 0.06em;
    white-space: normal;
}

/* ── R8 uygulaması: satır içeriği blur ALMAZ ────────────────────────────
   Tablo satırı tekrarlanan öğedir. İçine düşen cam yüzeyler (düğme, çip)
   kendi başlarına doğru tasarlanmış olsa da 20 satırda 40 ayrı compositor
   katmanı demek ve kaydırma düşer. Kap (kart) zaten bulanıklaştırıyor;
   satırdaki öğelere düz dolgu yeter.

   Bileşenlerin kendi dosyasında değil BURADA: ihtiyacı doğuran şey bileşen
   değil, tekrarlanan bağlam. `.yg-btn` bir başlıkta blur'unu korur. */
.yg-table .yg-btn,
.yg-table .yg-chip,
.yg-table .yg-pill {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* ── assets/css/yg/20-components/form.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — form doğrulama geri bildirimi
   --------------------------------------------------------------------------
   Bootstrap form kontrollerinin yüzeyi (koyu oyuk) 03-bootstrap-bridge.css'te.
   Bu dosya yalnızca HATA DURUMUNU giydiriyor.

   Neden ayrı bir mekanizma: tarayıcının kendi doğrulama balonu CSS ile
   giydirilemiyor (Chrome `::-webkit-validation-bubble`'ı kaldırdı), koyu panelde
   açık gri bir sistem balonu olarak çıkıyordu. public/js/yg/forms.js balonu
   bastırıp mesajı buraya basıyor; metni tarayıcıdan alıyor, yani Türkçe
   çevirisi kullanıcının dil ayarından geliyor.
   ========================================================================== */

/* ── Alan: etiket + kontrol + yardım metni ─────────────────────────────
   Her formda tekrarlanan dikey dizilim. Auth sayfasında başlamıştı ama modal
   formları da aynı şeyi istiyor; sayfa CSS'inde kalsa ikinci sayfa onu
   kullanamazdı (o dosya yüklenmiyor). Bileşen katmanının doğru yeri burası. */
.yg-field {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.yg-field__label {
    display: flex;
    align-items: center;
    gap: 8px;
    font: 500 var(--yg-text-sm) / 1 var(--yg-sans);
    color: var(--yg-text-2);
}

/* İpucu bir CÜMLE: gövde yazısı ailesinde. Mono yalnızca etiket, kod ve sayı
   için — tam cümleyi mono 11px'te okumak yorucu. `tabular-nums` kalıyor çünkü
   ipuçlarının bir kısmı sayaç ("152 karakter") ve rakamlar zıplamamalı. */
.yg-field__hint {
    display: flex;
    align-items: baseline;
    gap: 7px;
    font: 400 12px / 1.5 var(--yg-sans);
    color: var(--yg-text-3);
    font-variant-numeric: tabular-nums;
}

/* İki ölçü sınıfı, ikisi de aynı gerekçeyle: bir kontrolün genişliği İÇERİĞİNİN
   ölçüsü. Yüzde alanı üç haneli (`--narrow`), bir seçim listesi bir isim kadar
   (`--medium`). Izgara hücresi tek başına buna karar veremiyor — filtre çubuğu
   `1fr` dağıtıyor ve tek alan kalınca yüzde kutusu 1100px oluyor.

   Sınır KONTROLDE, alanda değil: etiket ve ipucu tam genişlikte kalıyor —
   ipucu bir cümle ve 140px'e sıkışsa sekiz satıra bölünür. */
.yg-field--narrow .form-control,
.yg-field--narrow .form-select {
    max-width: 140px;
}

.yg-field--medium .form-control,
.yg-field--medium .form-select {
    max-width: 460px;
}

/* Zorunlu alan işareti. Yıldız TEK sinyal değil: alan `required` niteliği
   taşıyor ve boş gönderilirse kendi doğrulama mesajımız çıkıyor. */
.yg-field__req {
    color: var(--yg-danger-soft);
}

/* Dikkat isteyen ipucu ("süper operatör tüm mağazaları görür"). Legacy'de
   `.um-hint` adıyla ayrı bir blok ve açık amber zeminliydi. */
.yg-field__hint--warn {
    align-items: center;
    padding: 5px 9px;
    border-radius: var(--yg-radius-xs);
    background: var(--yg-fill-action);
    border: 1px solid var(--yg-edge-action);
    color: var(--yg-action-soft);
}

.yg-field__label i {
    color: var(--yg-text-3);
    font-size: 12px;
}

.yg-field-error {
    display: none;
    margin-top: 6px;
    font: 400 var(--yg-text-xs) / 1.45 var(--yg-sans);
    color: var(--yg-danger-soft);
}

.yg-field-error.is-visible {
    display: flex;
    align-items: flex-start;
    gap: 6px;
}

/* Konumlandırma CSS'te DEĞİL: mesajı hangi kabın içine koyacağını
   public/js/yg/forms.js belirliyor (yatay satır dizilimlerini aşıp bloğa
   çıkıyor). Burada `flex-wrap` ya da `position: absolute` ile uğraşmak
   gerekmiyor — ikisi de ya satırı bozuyor ya alttaki satırın üstüne biniyordu. */

/* Uyarı üçgeni: mesaj yalnızca renkle değil ikonla da işaretlenir — renk
   körlüğünde ve yüksek kontrast modunda anlam kaybolmasın. */
.yg-field-error.is-visible::before {
    content: '';
    flex: none;
    width: 6px;
    height: 6px;
    margin-top: 5px;
    border-radius: 50%;
    background: var(--yg-danger);
}

/* Geçersiz alan — oyuk aynı, kenar ve odak halkası durumu söylüyor.
   Bootstrap'in kendi `.is-invalid` ikonu (gömülü kırmızı SVG) koyu oyukta
   sırıttığı için kapatılıyor; sinyali kenar + alt mesaj taşıyor. */
.form-control.is-invalid,
.form-select.is-invalid,
.was-validated .form-control:invalid,
.was-validated .form-select:invalid {
    border-color: var(--yg-danger);
    background-image: none;
    padding-right: 16px;
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus,
.was-validated .form-control:invalid:focus {
    border-color: var(--yg-danger);
    box-shadow: var(--yg-well-inset), 0 0 0 3px rgba(var(--yg-danger-rgb), 0.28);
}

/* input-group içindeki geçersiz alanda ön ek kutusu da durumu taşır. */
.input-group:has(.is-invalid) .input-group-text {
    border-color: var(--yg-danger);
    color: var(--yg-danger-soft);
}

.form-check-input.is-invalid {
    border-color: var(--yg-danger);
}

.form-check-input.is-invalid ~ .form-check-label {
    color: var(--yg-danger-soft);
}

/* Başarılı doğrulama için de aynı sadelik: Bootstrap'in yeşil onay SVG'si
   koyu oyukta gürültü yapıyor. */
.form-control.is-valid,
.form-select.is-valid,
.was-validated .form-control:valid {
    border-color: var(--yg-live);
    background-image: none;
    padding-right: 16px;
}

/* Sunucudan gelen alan hatası (Blade `@error`) aynı sınıfı kullanabilir. */
.invalid-feedback {
    display: block;
    margin-top: 6px;
    font: 400 var(--yg-text-xs) / 1.45 var(--yg-sans);
    color: var(--yg-danger-soft);
}

/* ── assets/css/yg/20-components/filter-bar.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — filtre çubuğu
   --------------------------------------------------------------------------
   Panelde beş sayfada kopyalanmış `.filter-card` deseni: tarih/saat aralığı,
   seçiciler, arama. Hepsi bu bloğa iniyor.

   Alanlar `.yg-field` (form bileşeni) kullanır; buradaki tek iş ızgara.
   ========================================================================== */

/* Kolon sayısı SABİT ve ÇİFT. Önceden `repeat(auto-fit, minmax(180px, 1fr))`
   vardı; kap genişliğine göre 5 ya da 7 gibi TEK sayıda iz üretiyordu ve iki iz
   kaplayan her alan (tarih kısayolu, çift, arama) satır sonuna denk geldiğinde
   bir alt satıra atlayıp arkasında BOŞ HÜCRE bırakıyordu — çubuk kırık bir
   merdiven gibi görünüyordu. Çift kolon sayısıyla iki-iz kaplayan alanlar her
   zaman düzgün döşeniyor.

   Sayıyı `--yg-filter-cols` ile tek alanlı çubuklar (bkz. report-settings)
   satır içi geçersiz kılabilir. */
.yg-filter {
    --yg-filter-cols: 4;

    display: grid;
    grid-template-columns: repeat(var(--yg-filter-cols), minmax(0, 1fr));
    gap: var(--yg-gap-sm) var(--yg-gap);
    align-items: start;
    padding: 18px 20px;
}

/* Arama gibi geniş alan iki kolon kaplayabilir. */
.yg-filter__wide {
    grid-column: span 2;
}

/* ── Eşleşen alan çifti ─────────────────────────────────────────────────
   "Başlangıç / Bitiş" gibi BİRLİKTE OKUNAN iki alan. Neden ayrı bir sarmalayıcı:
   ızgara alanları okuma sırasına göre yerleştirdiği için çiftin ilk yarısı bir
   satırın sonunda, ikinci yarısı ALT SATIRIN BAŞINDA kalabiliyordu — "Başlangıç
   Saati" sağ uçta, "Bitiş Saati" bir alt satırın solunda. Çift artık tek bir
   ızgara öğesi: ya birlikte kırılıyorlar ya hiç kırılmıyorlar. */
.yg-filter__pair {
    grid-column: span 2;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--yg-gap-sm) var(--yg-gap);
    align-items: start;
}

/* Dar ekran: iki kolon. `--yg-filter-cols` çift kalmalı, yoksa yukarıdaki
   döşeme garantisi bozulur. */
@media (max-width: 1200px) {
    .yg-filter {
        --yg-filter-cols: 2;
    }
}

@media (max-width: 640px) {
    .yg-filter {
        --yg-filter-cols: 1;
    }

    .yg-filter__wide,
    .yg-filter__pair {
        grid-column: span 1;
    }

    /* Tek kolonda çift de alt alta iner — iki tarih alanı 150px'e sıkışmasın. */
    .yg-filter__pair {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Filtre eylemleri (temizle/yenile) satırın sonunda, alanlarla aynı hizada.
   `align-self: end` gerekli: çubuk artık üstten hizalı (etiketler aynı çizgide)
   ama düğmeler ETİKETLE değil KONTROLLE hizalanmalı — aynı satırda bir alanla
   yan yana durduklarında (bkz. admin/stores) aksi hâlde yukarıda kalıyorlar. */
.yg-filter__actions {
    display: flex;
    align-items: center;
    align-self: end;
    gap: var(--yg-gap-sm);
    flex-wrap: wrap;
}

/* Kartın içinde altında başka bir bölüm olan filtre çubuğu (bkz.
   admin/advertisements reklam atama) ayırıcı çizgi taşır. */
.yg-filter--divided {
    border-bottom: 1px solid var(--yg-hair);
}

/* ── assets/css/yg/20-components/detail.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — detay satırları (etiket + değer)
   --------------------------------------------------------------------------
   Modal içindeki "Tarih / Kullanıcı / IP …" listeleri. Markup'ı sayfa JS'i
   üretiyor (`.detail-label` + `.detail-value`) ve aynı adlar iki sayfada
   kullanılıyor (aktivite logları, servis talepleri) — o yüzden sayfa CSS'i
   değil, bileşen katmanı.

   Sınıf adları legacy ile AYNI tutuldu: markup üreten JS'e dokunmadan yalnızca
   deri değişiyor (bkz. docs/tasarim-dili.md · R6 — geçiş PR'ı yeniden
   adlandırmaz).
   ========================================================================== */

.detail-label {
    font: 500 var(--yg-text-xs) / 1.45 var(--yg-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--yg-text-3);
}

.detail-value {
    font: 400 var(--yg-text-sm) / 1.5 var(--yg-sans);
    color: var(--yg-text);
    word-break: break-word;
}

.detail-row {
    gap: var(--yg-gap-sm);
    align-items: baseline;
    padding: 8px 0;
    border-bottom: 1px solid var(--yg-hairline-soft);
}

.detail-row:last-child {
    border-bottom: 0;
}

/* Yan yana dizilen satırlarda etiket sütunu hizalı kalır. Legacy'de bu ölçü
   her satırda satır içi `style="min-width:140px"` olarak tekrarlanıyordu ve
   `min-width` olduğu için uzun etiket ("SATIN ALMA TUTARI") sütunu büyütüp
   değerleri hizadan çıkarıyordu. Sabit temel + sarma ile değerler tek çizgide
   kalıyor. */
.detail-row .detail-label {
    flex: 0 0 160px;
    overflow-wrap: break-word;
}

/* Ham veri bloğu (metadata JSON): kritik metin cam üstünde değil oyukta. */
.metadata-pre {
    margin: 0;
    padding: 12px 14px;
    border-radius: var(--yg-radius-sm);
    background: var(--yg-well);
    border: 1px solid var(--yg-hair);
    box-shadow: var(--yg-well-inset);
    font: 400 11.5px / 1.6 var(--yg-mono);
    color: var(--yg-text-2);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 320px;
    overflow: auto;
}

/* ── assets/css/yg/20-components/multiselect.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — çoklu seçim (onay kutulu açılır liste)
   --------------------------------------------------------------------------
   Panelde dört yerde aynı kalıp var: makine, proje, teslimat durumu ve kahve
   makinesi seçimi. Hepsi Bootstrap dropdown'ı + içinde onay kutulu etiketler.
   Sınıf adı legacy ile aynı (`.machine-multiselect`) tutuldu: seçili sayıyı
   düğme metnine yazan JS bu adla sorguluyor (R6).

   Düğme bir GİRİŞ ALANI gibi görünür (koyu oyuk, camdan değil) çünkü işlevi
   `<select>`; açılan liste ise yüzen bir yüzey (glass 2, köprüden geliyor).
   ========================================================================== */

/* Menü açıkken kabı yukarı al: cam yüzeyler stacking context yarattığı için
   menü, DOM'da sonra gelen kartın ALTINDA kalıyordu. Kural bileşenin kendi
   dosyasında çünkü ihtiyacı doğuran şey bu bileşen; `.yg-card` bunu bilmez. */
.yg-card:has(.machine-multiselect .dropdown-menu.show) {
    position: relative;
    z-index: var(--yg-z-raised);
}

.machine-multiselect .dropdown-toggle {
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding-right: 34px;

    /* Bootstrap'in caret'i yerine kendi oku: `form-select` görünümüyle aynı
       kalsın diye. Ok rengi token değil çünkü SVG data-URI içinde renk
       yazılamıyor (R3 istisnası) — bunun yerine maske + currentColor. */
    background-image: none;
    position: relative;
}

.machine-multiselect .dropdown-toggle::after {
    content: '';
    display: block;
    position: absolute;
    top: 50%;
    right: 12px;
    width: 9px;
    height: 9px;
    margin: -6px 0 0;
    border: 0;
    border-right: 1.5px solid var(--yg-text-3);
    border-bottom: 1.5px solid var(--yg-text-3);
    transform: rotate(45deg);
    transition: transform var(--yg-dur-color) ease;
}

.machine-multiselect.show .dropdown-toggle::after {
    transform: rotate(225deg);
    margin-top: -2px;
}

.machine-multiselect .dropdown-menu {
    max-height: 280px;
    overflow-y: auto;
    min-width: 100%;
    padding: 6px 0;
}

/* R8: liste elemanı `backdrop-filter` ALMAZ — kap bulanıklaştırır, satır değil. */
.machine-multiselect .dropdown-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 12px;
    font: 400 var(--yg-text-sm) / 1.4 var(--yg-sans);
    cursor: pointer;
    white-space: normal;
}

.machine-multiselect .dropdown-item:active {
    background: var(--yg-active);
    color: var(--yg-text);
}

.machine-multiselect .dropdown-item input[type='checkbox'] {
    margin: 0;
    flex-shrink: 0;
}

.machine-multiselect .dropdown-divider {
    margin: 5px 0;
    border-top-color: var(--yg-hair);
}

/* Seçenek yoksa: menü boş bir şerit olarak açılmasın, nedenini söylesin. */
.machine-multiselect__empty {
    margin: 0;
    padding: 12px 14px;
    font: 400 var(--yg-text-sm) / 1.45 var(--yg-sans);
    color: var(--yg-text-3);
    max-width: 32ch;
}

/* ── assets/css/yg/20-components/combobox.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — yazarak arama + çoklu seçim (combobox)
   --------------------------------------------------------------------------
   `.machine-multiselect` (onay kutulu açılır liste) sabit ve KISA listeler
   için doğru bileşen: makine, proje, teslimat durumu. Ürün kataloğu öyle
   değil — yüzlerce satır — ve orada okunacak liste değil ARANACAK liste var.
   Bu bileşen o boşluğu dolduruyor: kullanıcı yazar, liste daralır, seçilen
   her ürün alanın içinde bir çipe döner.

   Yapı üç parçadan ibaret ve üçü de mevcut dile yaslanıyor:
     • `__field`   → `form-control` ile AYNI oyuk (bkz. 03-bootstrap-bridge)
     • `__chip`    → `.yg-chip` bileşeni, kaldırma düğmesiyle (bkz. pill.css)
     • `__list`    → yüzen yüzey: glass 3 + opak taban (dropdown ile aynı reçete)

   R8: liste ÖĞESİ `backdrop-filter` almaz — kap bulanıklaştırır, satır değil.
   Yüzlerce seçenekte satır başına bir compositor katmanı demek olurdu.
   ========================================================================== */

/* Menü açıkken kabı yukarı al. Cam yüzeyler stacking context yarattığı için
   yüzen liste, DOM'da sonra gelen kartın ALTINDA kalıyor; multiselect'te de
   aynı kural var, gerekçesi orada uzun uzun yazılı. */
.yg-card:has(.yg-combo__list:not([hidden])) {
    position: relative;
    z-index: var(--yg-z-raised);
}

.yg-combo {
    position: relative;
    min-width: 0;
}

/* Alanın kendisi bir GİRİŞ ALANI gibi görünür: `.form-control` ile aynı oyuk,
   aynı yarıçap, aynı odak halkası. Tek fark sarabilmesi — içinde çipler var.
   `cursor: text` bilinçli: kutunun boş herhangi bir yerine tıklamak yazmaya
   başlatır, kullanıcı 90px'lik metin kutusunu nişan almak zorunda kalmaz. */
.yg-combo__field {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--yg-gap-xs);
    min-height: var(--yg-control-h-sm);
    padding: 5px 10px;
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius);
    background: var(--yg-well);
    box-shadow: var(--yg-well-inset);
    cursor: text;
    transition: border-color var(--yg-dur-color) ease, box-shadow var(--yg-dur-color) ease;
}

/* Odak halkası ALANIN üstünde, metin kutusunun değil: kullanıcı için odaklanan
   şey kutunun tamamı. Metin kutusu kendi halkasını göstermez (aşağıda). */
.yg-combo__field:focus-within {
    border-color: var(--yg-info);
    box-shadow: var(--yg-well-inset), var(--yg-focus-ring);
}

.yg-combo__input {
    flex: 1 1 8ch;
    min-width: 8ch;
    padding: 5px 2px;
    border: 0;
    background: none;
    color: var(--yg-text);
    font: 400 var(--yg-text-base) / 1.35 var(--yg-sans);
    outline: none;
}

.yg-combo__input::placeholder {
    color: var(--yg-text-3);
    opacity: 1;
}

/* Çip kabı `display: contents`: çipler alanın KENDİ flex akışına katılır.
   Ayrı bir kutu olsaydı çipler kendi içinde sarar, alan tek satırda kalır ve
   üçüncü çipten sonra taşardı. Kap yine de gerekli — JS tek bir yeri temizleyip
   yeniden basıyor, metin kutusuna dokunmadan. */
.yg-combo__tokens {
    display: contents;
}

/* Seçili ürün çipi. `.yg-chip` görünümü aynen geçerli; buradaki tek iş
   uzun ürün adının alanı yırtmasını engellemek. */
.yg-combo__chip {
    max-width: 100%;
    min-width: 0;
}

.yg-combo__chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Yüzen liste ───────────────────────────────────────────────────────── */
.yg-combo__list {
    position: absolute;
    z-index: var(--yg-z-content);
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: 264px;
    margin: 0;
    padding: 6px 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    list-style: none;
    border: 1px solid var(--yg-g2-border);
    border-radius: var(--yg-radius);
    background: var(--yg-g3-fill), var(--yg-surface-floating);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    box-shadow: var(--yg-g2-shadow), var(--yg-g2-sheen);
}

.yg-combo__option {
    display: flex;
    align-items: baseline;
    gap: var(--yg-gap-sm);
    padding: 7px 12px;
    color: var(--yg-text-2);
    font: 400 var(--yg-text-sm) / 1.4 var(--yg-sans);
    cursor: pointer;
}

/* Klavye ve fare AYNI vurguyu paylaşır: iki ayrı "seçili görünüm" olsa
   kullanıcı Enter'ın hangisini alacağını bilemez. Vurguyu tek doğru kaynak
   olarak JS yönetiyor (`aria-selected`), hover onu taklit ediyor. */
.yg-combo__option:hover,
.yg-combo__option[aria-selected='true'] {
    background: var(--yg-hover);
    color: var(--yg-text);
}

/* Eşleşen harfler — aramanın neden bu satırı getirdiğini gösterir. */
.yg-combo__option mark {
    padding: 0;
    background: none;
    color: var(--yg-info-soft);
    font-weight: 600;
}

/* İkincil bilgi (kategori) sağa yaslanır ve daralma hakkını isme bırakır. */
.yg-combo__option-meta {
    margin-left: auto;
    flex: none;
    color: var(--yg-text-3);
    font: 500 var(--yg-text-xs) / 1 var(--yg-mono);
    letter-spacing: 0.06em;
}

/* Liste durumu: yükleniyor / sonuç yok / "+N sonuç daha". Seçenek DEĞİL,
   o yüzden imleç ve hover yok — tıklanacak bir şey olduğunu ima etmesin. */
.yg-combo__note {
    padding: 10px 12px;
    color: var(--yg-text-3);
    font: 400 var(--yg-text-sm) / 1.45 var(--yg-sans);
}

/* Kutunun altındaki sayaç ("3 ürün seçili") ve temizleme düğmesi. */
.yg-combo__summary {
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
}

.yg-combo__clear {
    padding: 0;
    border: 0;
    background: none;
    color: var(--yg-info-soft);
    font: 400 12px / 1.5 var(--yg-sans);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.yg-combo__clear:hover {
    color: var(--yg-info);
}

/* Yüksek kontrast modunda cam ve dolgu kaybolur; vurgulanan satırın kenarı
   kalır ki klavyeyle gezinen kullanıcı nerede olduğunu görsün. */
@media (forced-colors: active) {
    .yg-combo__option[aria-selected='true'] {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }
}

/* ── assets/css/yg/20-components/segment.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — parçalı seçici (tarih kısayolları)
   --------------------------------------------------------------------------
   "Dün · Bugün · Bu Hafta · Bu Ay". Siparişler ve kahve satışlarında aynı
   markup var ve seçili olanı JS `.btn-primary` ↔ `.btn-outline-primary`
   takasıyla işaretliyor. Sınıf adlarına dokunmuyoruz (R6); burada yalnızca
   `.btn-group` içindeki bu iki Bootstrap sınıfını dile çekiyoruz.

   Seçili parça AMBER değil bilgi mavisi: amber bu dilde "dikkat/eylem" demek
   ve bir tarih kısayolu bir eylem değil, mevcut görünümün adı.
   ========================================================================== */

.btn-group .date-preset {
    border-color: var(--yg-hair);
    background: var(--yg-g1-flat);
    color: var(--yg-text-2);
    font: 500 11.5px / 1 var(--yg-mono);
    letter-spacing: 0.03em;
    padding: 0 12px;
    height: var(--yg-control-h-sm);
    box-shadow: none;
}

.btn-group .date-preset:hover {
    background: var(--yg-hover);
    border-color: var(--yg-g2-border);
    color: var(--yg-text);
}

.btn-group .date-preset.btn-primary,
.btn-group .date-preset.active {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

/* Bootstrap parçaları negatif margin ile bindiriyor; seçili parçanın kenarı
   komşunun altında kalmasın. */
.btn-group .date-preset.active {
    position: relative;
    z-index: 1;
}

/* ── assets/css/yg/20-components/chooser.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — kapı ekranı (organizasyon seçimi)
   --------------------------------------------------------------------------
   Ekranı tek başına sahiplenen bir yüzey: glass 3, ortalanmış, maskotlu.
   Altı sayfadaki kopyanın yerine geçiyor.
   ========================================================================== */

/* Kapı ekranı bir SAYFA yüzeyi (giriş kartı gibi): kendi genişliğini ve
   ortalanmasını taşır. R5'in "blok kendi dışına taşmaz" kuralının bilinçli
   istisnası — altı sayfada aynı sarmalayıcıyı tekrar etmek daha kötü.
   `width: 100%` şart: `.yg-main` bir flex kolon, flex öğesi içeriğine göre
   büzülüyor ve `max-width` hiç devreye girmiyordu (ızgara tek kolona düşüyordu). */
/* Genişlik 880px'ken kapı ekranı, aynı kabuğun içindeki DİĞER sayfalardan
   belirgin biçimde daha dardı: yanlarda ~150px boşluk kalıyor ve ekran
   yarım kullanılmış görünüyordu. 1240px hem o boşluğu kapatıyor hem de çok
   geniş monitörde kartların cılız bir şeride dizilmesini engelliyor. */
.yg-chooser {
    width: 100%;
    max-width: 1240px;
    margin-inline: auto;
}

.yg-chooser__head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center;
    padding-bottom: var(--yg-gap-lg);
}

.yg-chooser__title {
    margin: 0;
    font: 600 var(--yg-text-2xl) / 1.15 var(--yg-display);
    letter-spacing: -0.02em;
    color: var(--yg-text);
}

.yg-chooser__subtitle {
    margin: 0;
    font: 400 var(--yg-text-base) / 1.55 var(--yg-sans);
    color: var(--yg-text-3);
    max-width: 46ch;
    text-wrap: pretty;
}

/* ── Kartlar ─────────────────────────────────────────────────────────────
   Tekrarlanan öğe: `backdrop-filter` YOK (R8). Kap zaten bulanıklaştırıyor. */

.yg-chooser__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--yg-gap);
    list-style: none;
    margin: 0;
    padding: 0;
}

.yg-chooser__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    height: 100%;
    padding: 22px 18px;
    border: 1px solid var(--yg-g1-border);
    border-radius: var(--yg-radius);
    background: var(--yg-g1-flat);
    text-align: center;
    text-decoration: none;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        transform var(--yg-dur-press) var(--yg-ease-press);
}

.yg-chooser__item:hover {
    background: var(--yg-hover);
    border-color: var(--yg-edge-info);
}

.yg-chooser__item:active {
    transform: translateY(1px);
}

.yg-chooser__icon {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border-radius: var(--yg-radius-sm);
    background: var(--yg-fill-info);
    border: 1px solid var(--yg-edge-info);
    color: var(--yg-info-soft);
    font-size: 16px;
}

.yg-chooser__name {
    font: 500 var(--yg-text-base) / 1.35 var(--yg-sans);
    color: var(--yg-text);
    overflow-wrap: anywhere;
}

/* İkon tonu. Proje kapısındaki iki ek kart gerçek proje değil birer filtre
   kararı: "Atanmamış" bir eksiklik, "Tüm Makineler" bir kapsam. Renk tek sinyal
   değil — ikisinin de adı ve alt satırı durumu yazıyor (R9). */
.yg-chooser__icon[data-yg-status='warn'] {
    background: var(--yg-fill-action);
    border-color: var(--yg-edge-action);
    color: var(--yg-action-soft);
}

.yg-chooser__icon[data-yg-status='neutral'] {
    background: var(--yg-fill-neutral);
    border-color: var(--yg-edge-neutral);
    color: var(--yg-text-2);
}

/* Kimlik: mono ve tabular — yan yana duran kartlarda rakamlar hizalı okunur. */
.yg-chooser__id {
    font: 400 11px / 1.4 var(--yg-mono);
    color: var(--yg-text-3);
    font-variant-numeric: tabular-nums;
}

/* ── assets/css/yg/20-components/tabs.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — sekmeler
   --------------------------------------------------------------------------
   Panelde iki kalıp var: `.um-tabs` (kullanıcılar, reklamlar) ve analizdeki
   `.a-tab`. İkisi de "tarayıcı sekmesi" taklidi yapıyordu: üst köşeleri yuvarlak,
   alt kenarı olmayan kutular ve altındaki panelin sol üst köşesini düzleştiren
   `border-radius: 0 16px 16px 16px`. Cam yüzeyde bu numara çalışmıyor — sahte
   kenarlar camın kendi kenarıyla çakışıyor.

   Yeni yaklaşım: sekme satırı bağımsız bir çip şeridi, altındaki panel sıradan
   bir kart. Seçili sekmeyi ALT KENARINDAKİ 2px ışık şeridi söylüyor — dilin
   kendi durum dili, sekme için de aynı.

   Sınıf adları legacy ile aynı (`.um-tabs .nav-link`): sekme davranışını
   Bootstrap yürütüyor ve `.active` sınıfını o basıyor (R6).
   ========================================================================== */

.yg-tabs,
.um-tabs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0;
    margin: 0;
    border: 0;
    list-style: none;
}

.um-tabs .nav-item {
    margin: 0;
}

.yg-tabs__link,
.um-tabs .nav-link {
    display: flex;
    align-items: center;
    gap: 7px;
    position: relative;
    padding: 9px 15px;
    border: 1px solid var(--yg-g1-border);
    border-radius: var(--yg-radius-sm);
    background: var(--yg-g1-flat);
    color: var(--yg-text-2);
    font: 500 var(--yg-text-sm) / 1.3 var(--yg-sans);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, color var(--yg-dur-color) ease,
        border-color var(--yg-dur-color) ease;
}

.yg-tabs__link:hover,
.um-tabs .nav-link:hover {
    background: var(--yg-hover);
    border-color: var(--yg-g2-border);
    color: var(--yg-text);
}

.yg-tabs__link.active,
.um-tabs .nav-link.active {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

/* Seçili sekmenin alt kenarındaki ışık şeridi. Kartın üst şeridiyle aynı dil:
   2px, durum taşır. `overflow: hidden` gerekmiyor çünkü şerit çipin içinde. */
.yg-tabs__link.active::after,
.um-tabs .nav-link.active::after {
    content: '';
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: -1px;
    height: 2px;
    border-radius: 2px;
    background: var(--yg-info);
    box-shadow: 0 0 12px 1px rgba(var(--yg-info-rgb), 0.55);
}

/* Sekme içindeki sayaç ("12") — ikincil, mono */
.yg-tabs__count {
    font: 500 10.5px / 1 var(--yg-mono);
    color: var(--yg-text-3);
    font-variant-numeric: tabular-nums;
}

.yg-tabs__link.active .yg-tabs__count,
.um-tabs .nav-link.active .yg-tabs__count {
    color: var(--yg-info-soft);
}

@media (max-width: 700px) {
    .yg-tabs__link,
    .um-tabs .nav-link {
        padding: 8px 11px;
        font-size: 12.5px;
    }
}

/* ── assets/css/yg/20-components/check-grid.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — onay kutusu ızgarası
   --------------------------------------------------------------------------
   Modal içindeki "hangi roller / hangi modüller / hangi mağazalar" seçimleri.
   Legacy'de üç ayrı sınıf vardı (`um-checkbox-grid`, `um-permission-grid`,
   `um-stores-grid`), üçü de aynı ızgara + açık gri kutu. Adlar korundu (R6),
   ölçü farkı modifier'a indi.

   Kutu CAMDAN DEĞİL oyuktan yapılır: içinde giriş öğeleri var ve dilin kuralı
   giriş alanını cam üstüne koymuyor. R8: satırlar `backdrop-filter` almaz.
   ========================================================================== */

.yg-check-grid,
.um-checkbox-grid,
.um-permission-grid,
.um-stores-grid,
.ad-store-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 2px;
    padding: 10px;
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius-sm);
    background: var(--yg-well);
    box-shadow: var(--yg-well-inset);
}

/* Uzun listeler kap içinde kaydırılır; kısa olanlar akar. */
.um-checkbox-grid,
.um-stores-grid,
.yg-check-grid--scroll {
    max-height: 210px;
    overflow-y: auto;
}

/* Atama ekranı gibi tek kolonu dolduran uzun listeler */
.yg-check-grid--tall,
.ad-store-grid {
    max-height: 420px;
    overflow-y: auto;
}

/* Mağaza adları uzun: daha geniş kolon */
.ad-store-grid {
    grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}

/* ── Satır ──────────────────────────────────────────────────────────────
   IZGARA, flex DEĞİL. `minmax(0, 1fr)` ikinci kolon, etiketin kendi kolonunu
   aşmasını engelliyor: flex'te etiket `min-width: auto` ile içeriği kadar
   genişleyip satırdan taşıyordu (uzun ürün adları 60+ karakter).

   Etiket tek satıra kırpıldığı için kutucuk ile metin ortada hizalı. */
.yg-check-grid__item,
.um-perm-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 8px;
    padding: 7px 9px;
    border-radius: var(--yg-radius-xs);
    transition: background var(--yg-dur-color) ease;
}

.ad-store-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 9px;
    border-radius: var(--yg-radius-xs);
    transition: background var(--yg-dur-color) ease;
}

/* Bootstrap `.form-check` sıfırlaması. Markup'ı sayfa JS'i üretiyor ve
   `form-check` + `form-check-input` sınıflarını taşıyor (R6: adlar korunuyor).
   Bootstrap kutucuğu `float: left; margin-left: -1.5em` ile yerleştiriyor —
   yani satırın DIŞINA çıkarıyor; ölçümde kutucuk kutunun 13px soluna taşmış ve
   flex içinde ezilip 11.7px'e düşmüştü (kardeşi 15px iken). Özgüllük eşleşsin
   diye seçici iki sınıflı. */
.yg-check-grid__item .form-check-input,
.um-perm-item .form-check-input {
    float: none;
    flex: none;
    width: 15px;
    height: 15px;
    margin: 0;
}

.yg-check-grid__item:hover,
.um-perm-item:hover,
.ad-store-item:hover {
    background: var(--yg-hover);
}

.yg-check-grid__label,
.um-perm-label,
.ad-store-item label {
    font: 400 var(--yg-text-sm) / 1.35 var(--yg-sans);
    color: var(--yg-text-2);
    cursor: pointer;
    margin: 0;
}

/* TEK SATIR + üç nokta. İki gerekçe:

   1. Okunurluk: 743 kalemlik listede satır yüksekliği değişkense göz hizayı
      kaybediyor — kullanıcının şikâyeti tam olarak buydu ("çok karmaşık
      duruyor"). Eşit satırlar taranabilir bir liste veriyor.
   2. Kararlılık: satır yüksekliği sarmaya bağlı olduğunda ızgara satırını
      Chrome sarma ÖNCESİ genişlikle ölçüyor; kutu 24px'te kalıp metin alttaki
      satırın üstüne biniyordu. Sarma yoksa ölçüm belirsizliği de yok.

   Tam ad kayıp değil: `title` niteliğinde (markup'ı üreten JS koyuyor) ve
   listenin üstünde arama kutusu var. */
.yg-check-grid__label,
.um-perm-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Kutucuk ve metni etiketin İÇİNDE olan varyant (reklam atama): boşluk
   markup'taki yardımcı sınıflardan değil bloktan gelir. */
.ad-store-item label {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
}

.ad-store-item label input {
    flex-shrink: 0;
    margin: 0;
}

/* Izgara boşken: kullanıcı tıklayacak bir şey bulamıyor, nedenini söyle. */
.yg-check-grid__empty {
    margin: 0;
    padding: 10px;
    font: 400 var(--yg-text-sm) / 1.45 var(--yg-sans);
    color: var(--yg-text-3);
}

@media (max-width: 700px) {
    .yg-check-grid,
    .um-checkbox-grid,
    .um-permission-grid,
    .um-stores-grid,
    .ad-store-grid {
        grid-template-columns: 1fr;
    }
}

/* ── assets/css/yg/20-components/toggle.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — anahtar (aç/kapa)
   --------------------------------------------------------------------------
   Panelde tek kopyası vardı (rapor e-posta ayarları, `.toggle-switch` +
   `.toggle-slider`, sayfa içi <style> bloğunda). Bileşene çıkarılmasının nedeni
   sayı değil KATMAN: bir anahtar iki durumlu bir kontrol, yani her formun
   ihtiyacı — sayfa CSS'inde kaldığı sürece ikinci sayfa onu kullanamaz (o dosya
   yüklenmiyor).

   Bootstrap'in `.form-switch`'i yerine kendi bloğu: `form-switch` durumu
   YALNIZCA renkle söylüyor (mavi/gri ray), yanına metin koymak için ayrı bir
   `.form-check-label` gerekiyor ve etiket float ile hizalanıyor. Burada durum
   üç sinyal taşıyor (R9): topuzun yeri, rayın rengi ve yanındaki Türkçe metin.

   Ray CAM DEĞİL: bir kontrolün yüzeyi koyu oyuk (bkz. 03-bootstrap-bridge.css'te
   .form-control). Cam ray, arkasındaki ışığa göre açık/koyu göründüğü için
   "kapalı" hali kartın neresinde durduğuna bağlı olarak değişiyordu.
   ========================================================================== */

.yg-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
}

/* Girdi görünmez ama ODAKLANABİLİR kalır: `display: none` klavyeyi kırar,
   `opacity: 0` + sıfır boyut tarayıcının odak sırasını korur. Odak halkasını
   ray taşıyor (aşağıda `:focus-visible + .yg-toggle__track`). */
.yg-toggle__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.yg-toggle__track {
    position: relative;
    flex: none;
    width: 46px;
    height: 26px;
    border-radius: var(--yg-radius-pill);
    background: var(--yg-well);
    border: 1px solid var(--yg-hair);
    box-shadow: var(--yg-well-inset);
    transition: background var(--yg-dur-color) var(--yg-ease-in),
                border-color var(--yg-dur-color) var(--yg-ease-in);
}

.yg-toggle__knob {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--yg-text-2);
    transition: transform var(--yg-dur-press) var(--yg-ease-press),
                background var(--yg-dur-color) var(--yg-ease-in);
}

.yg-toggle__state {
    font: 500 var(--yg-text-sm) / 1 var(--yg-sans);
    color: var(--yg-text-3);
    min-width: 44px;
}

/* İki metin de markup'ta duruyor, durum hangisinin görüneceğine karar veriyor.
   `display: none` bilinçli: erişilebilirlik ağacından da çıkıyor, yani ekran
   okuyucu iki kelimeyi birden okumuyor. */
.yg-toggle__state--on {
    display: none;
}

.yg-toggle__input:checked ~ .yg-toggle__state .yg-toggle__state--on {
    display: inline;
}

.yg-toggle__input:checked ~ .yg-toggle__state .yg-toggle__state--off {
    display: none;
}

/* ── Açık ──────────────────────────────────────────────────────────────
   Anahtar bir EYLEM değil bir durum: açık hali `live`, amber değil. Amber
   panelde tek eylem rengi ve onu düğmeler taşıyor. */
.yg-toggle__input:checked + .yg-toggle__track {
    background: rgba(var(--yg-live-rgb), 0.22);
    border-color: var(--yg-edge-live);
}

.yg-toggle__input:checked + .yg-toggle__track .yg-toggle__knob {
    transform: translateX(20px);
    background: var(--yg-live);
}

.yg-toggle__input:checked ~ .yg-toggle__state {
    color: var(--yg-live-soft);
}

/* ── Odak ve devre dışı ────────────────────────────────────────────────── */
.yg-toggle__input:focus-visible + .yg-toggle__track {
    box-shadow: var(--yg-well-inset), var(--yg-focus-ring);
}

.yg-toggle__input:disabled ~ * {
    opacity: 0.45;
}

.yg-toggle:has(.yg-toggle__input:disabled) {
    cursor: not-allowed;
}

/* Yüksek kontrast modunda cam ve alfa dolgular kayboluyor; durum topuzun
   yerinden okunmaya devam ediyor ama rayın sınırı görünür kalmalı. */
@media (forced-colors: active) {
    .yg-toggle__track {
        border: 1px solid CanvasText !important;
    }

    .yg-toggle__knob {
        background: CanvasText !important;
    }
}

/* ── assets/css/yg/20-components/project-logo.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — proje logosu
   --------------------------------------------------------------------------
   `resources/views/components/project-logo.blade.php` çıktısı. Beş sayfada
   kullanılıyor (mağazalar, projeler, dashboard, makineler, raf yönetimi).

   Öncesinde bileşen tüm görünümünü satır içi `style` ile basıyordu — sekiz
   özellik, içinde `#fff` ve `rgba(0,0,0,.06)` gibi sabit renkler. Satır içi stil
   hiçbir stylesheet ile ezilemediği için koyu temada logo kutusu beyaz kalıyor
   ve yazdırma temasını da baypas ediyordu (R4).

   Satır içinde YALNIZCA iki custom property kaldı: boyut ve projenin rengi.
   İkisi de çalışma zamanı verisi — R4'ün izin verdiği tam durum.

   Aynı sınıflar `machines-modern.css` içinde de tanımlı: bileşen henüz geçmemiş
   sayfalar tarafından da kullanılıyor ve orada açık tema karşılığı gerekiyor.
   ========================================================================== */

.yg-plogo,
.yg-plogo__fallback {
    width: var(--yg-plogo-size, 40px);
    height: var(--yg-plogo-size, 40px);
    border-radius: var(--yg-plogo-radius, 9px);
    flex-shrink: 0;
}

/* Yüklenen logo kullanıcı içeriği: şeffaf PNG'ler için açık bir taban gerekiyor
   (marka logoları çoğunlukla koyu mürekkep), o yüzden burada zemin bilinçli
   olarak açık kalıyor — `--yg-plogo-plate` token'ı üzerinden. */
.yg-plogo {
    object-fit: contain;
    background: var(--yg-plogo-plate);
    border: 1px solid var(--yg-hair);
}

/* Logo yoksa projenin renginde baş harf. Renk projeye ait bir VERİ, token değil
   — bu yüzden custom property olarak geliyor. Üstündeki metin her zaman koyu
   mürekkep: proje renkleri kullanıcı seçimi ve açık tonlar da geliyor. */
.yg-plogo__fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--yg-plogo-color, var(--yg-info));
    color: var(--yg-on-action);
    font: 700 var(--yg-plogo-font, 17px) / 1 var(--yg-display);
}

/* ── assets/css/yg/20-components/row.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — liste satırı
   --------------------------------------------------------------------------
   Makine listesi, düşük stok uyarıları, son siparişler, servis talepleri gibi
   "ikon + başlık + meta + sağ uç" desenli listeler.

   PERFORMANS KURALI (R8): satır DÜZ yüzeydir, `backdrop-filter` almaz.
   Tekrarlanan her blur'lu öğe ayrı bir compositor katmanı + backdrop okuması
   demek; 200 satırlık listede kaydırma çöker. Kap bulanıklaştırır, satır değil.
   ========================================================================== */

.yg-rows {
    display: flex;
    flex-direction: column;
}

/* Sözleşme (docs/tasarim-dili.md): `--yg-state` DOLGU/ŞERİT rengi,
   `--yg-state-text` koyu zeminde AA geçen METİN rengi. Bu blok ikincisini hiç
   kurmuyordu; `.yg-row__icon` ve `.yg-row__value` onu okuduğu için renk KAPTAN
   miras alınıyordu ve satırlar nötr kartların içinde durumsuz görünüyordu —
   yani satır durumu ikonda ve değerde HİÇ görünmemiş. */
.yg-row {
    --yg-state: var(--yg-text-2);
    --yg-state-text: var(--yg-text-2);
    --yg-state-fill: var(--yg-fill-neutral);
    --yg-state-edge: var(--yg-edge-neutral);

    display: flex;
    align-items: center;
    gap: 13px;
    padding: var(--yg-pad-row);
    border-bottom: 1px solid rgba(var(--yg-text-rgb), 0.055);
    transition: background var(--yg-dur-color) ease;
}

.yg-row:last-child {
    border-bottom: 0;
}

.yg-row:hover {
    background: var(--yg-row-hover);
}

.yg-row[data-yg-status='live'] {
    --yg-state: var(--yg-live);
    --yg-state-text: var(--yg-live-soft);
    --yg-state-fill: var(--yg-fill-live);
    --yg-state-edge: var(--yg-edge-live);
}

.yg-row[data-yg-status='warn'] {
    --yg-state: var(--yg-action);
    --yg-state-text: var(--yg-action-soft);
    --yg-state-fill: var(--yg-fill-action);
    --yg-state-edge: var(--yg-edge-action);
}

.yg-row[data-yg-status='danger'] {
    --yg-state: var(--yg-danger);
    --yg-state-text: var(--yg-danger-soft);
    --yg-state-fill: var(--yg-fill-danger);
    --yg-state-edge: var(--yg-edge-danger);
}

.yg-row[data-yg-status='info'] {
    --yg-state: var(--yg-info);
    --yg-state-text: var(--yg-info-soft);
    --yg-state-fill: var(--yg-fill-info);
    --yg-state-edge: var(--yg-edge-info);
}

.yg-row[data-yg-status='idle'] {
    --yg-state: var(--yg-text-3);
    --yg-state-text: var(--yg-text-3);
    --yg-state-fill: var(--yg-faint);
    --yg-state-edge: var(--yg-hair);
}

.yg-row__icon {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: var(--yg-radius-sm);
    display: grid;
    place-items: center;
    background: var(--yg-state-fill);
    border: 1px solid var(--yg-state-edge);
    color: var(--yg-state-text);
    font-size: 14px;
}

.yg-row__main {
    flex: 1;
    min-width: 0;
}

.yg-row__title {
    font: 500 14px / 1.3 var(--yg-sans);
    color: var(--yg-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.yg-row__meta {
    margin-top: 3px;
    font: 400 11.5px / 1.4 var(--yg-mono);
    color: var(--yg-text-3);
}

.yg-row__end {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    text-align: right;
}

.yg-row__value {
    font: 500 13px / 1.2 var(--yg-mono);
    font-variant-numeric: tabular-nums;
    color: var(--yg-state-text);
}

.yg-row__hint {
    font: 400 11px / 1.2 var(--yg-sans);
    color: var(--yg-text-3);
}

/* Doluluk çubuğu (`.yg-bar`) buradan `20-components/bar.css`'e taşındı: makine
   kartı ve raf kutusu da tüketiyor, yani satırın parçası değil kendi bloğu. */

/* ── assets/css/yg/20-components/bar.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — doluluk çubuğu
   --------------------------------------------------------------------------
   Önce `row.css` içinde yaşıyordu; liste satırının parçası sanılmıştı. Artık
   makine kartı ve raf kutusu da tüketiyor, yani satırın parçası değil kendi
   bloğu — o yüzden kendi dosyasında (R6: bir dosya = bir blok).

   Çalışma zamanı değeri satır içi CUSTOM PROPERTY ile geliyor
   (`style="--yg-fill:42%"`), satır içi renk/stil ile DEĞİL (R4). Rengi ise
   kabın `data-yg-status`'undan miras alınan `--yg-state` taşıyor: doluluk
   yüzdesi bir DURUM ve o durumu tek yerde tanımlıyoruz.

   Doluluk yalnızca renkle verilmez (R9): çubuğun yanında daima sayı ya da
   yüzde etiketi durur — bunu tüketen blok garanti eder.
   ========================================================================== */

.yg-bar {
    width: var(--yg-bar-width, 96px);
    height: 5px;
    border-radius: 3px;
    background: var(--yg-well);
    box-shadow: var(--yg-well-inset);
    overflow: hidden;
}

.yg-bar--block {
    width: 100%;
}

.yg-bar__fill {
    display: block;
    height: 100%;
    width: var(--yg-fill, 0%);
    border-radius: 3px;
    background: var(--yg-state, var(--yg-text-2));
    transition: width var(--yg-dur-color) var(--yg-ease-in);
}

/* ── assets/css/yg/20-components/chart.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — grafik kabı
   --------------------------------------------------------------------------
   Panelde 11 `<canvas>` var (dashboard 3, analiz 8) ve her biri kendi
   sarmalayıcısını kuruyordu: `style="max-height:180px"`, `.chart-card`,
   `.a-chart-box`… Kabın işi tek: canvas'a KESİN bir yükseklik vermek.

   Neden kesin yükseklik: Chart.js `maintainAspectRatio: false` ile kabın
   yüksekliğini okuyor. Kap `height: auto` ise canvas 0px'e çöküyor ya da her
   yeniden çizimde birkaç piksel büyüyerek sonsuz döngüye giriyor (Chart.js'in
   bilinen "growing chart" sorunu). Yükseklik knob: `--yg-chart-h`.

   Canvas CAM DEĞİL, kabın kendisi de değil: grafik zaten bir kartın içinde
   duruyor ve ikinci bir cam katman R8'e takılıyor. Burada yalnızca ölçü var.
   ========================================================================== */

.yg-chart {
    position: relative;
    width: 100%;
    height: var(--yg-chart-h, 280px);
}

/* Chart.js canvas'a satır içi width/height yazıyor; `!important` gerekmiyor
   çünkü `max-*` sınırları satır içi ölçüyü değil hesaplanan boyutu bağlıyor. */
.yg-chart > canvas {
    display: block;
    max-width: 100%;
    max-height: 100%;
}

/* ── Efsane / açıklama satırı ───────────────────────────────────────────
   Chart.js'in kendi efsanesi kullanılmadığında (pasta grafiklerde dilim
   sayısı fazla olunca okunmaz oluyor) kap altına elle yazılan liste. */
.yg-chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px var(--yg-gap);
    margin-top: var(--yg-gap-sm);
}

.yg-chart-legend__item {
    display: flex;
    align-items: center;
    gap: 7px;
    font: 400 var(--yg-text-xs) / 1.45 var(--yg-sans);
    color: var(--yg-text-2);
}

/* Seri rengi çalışma zamanında geliyor (`--yg-swatch`), çünkü hangi serinin
   hangi rampa adımını aldığı veriye bağlı (R4). */
.yg-chart-legend__dot {
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--yg-swatch, var(--yg-text-3));
}

.yg-chart-legend__value {
    font-family: var(--yg-mono);
    font-variant-numeric: tabular-nums;
    color: var(--yg-text-3);
}

/* ── Veri yokken ────────────────────────────────────────────────────────
   Boş bir canvas boş bir dikdörtgen: kullanıcı "yükleniyor mu, bozuk mu?"
   diye bakıyor. Grafik yerine metin basılır ve kap yüksekliği korunur ki
   sayfa düzeni veri geldiğinde zıplamasın. */
.yg-chart--empty {
    display: grid;
    place-items: center;
    border-radius: var(--yg-radius-sm);
    background: var(--yg-faint);
    border: 1px dashed var(--yg-hair);
    color: var(--yg-text-3);
    font: 400 var(--yg-text-sm) / 1.5 var(--yg-sans);
    text-align: center;
    padding: var(--yg-gap);
}

@media (max-width: 700px) {
    .yg-chart {
        height: var(--yg-chart-h-sm, var(--yg-chart-h, 280px));
    }
}

/* Yazdırma: grafik canvas'ı raster olarak basılıyor; kabın yüksekliği
   küçültülüyor ki tek sayfaya sığsın. */
@media print {
    .yg-chart {
        height: 200px !important;
    }
}

/* ── assets/css/yg/20-components/machine-card.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — makine kartı ızgarası ve arama çubuğu
   --------------------------------------------------------------------------
   İKİ SAYFANIN ORTAK BLOĞU ve ikisi markup'ı farklı yerden üretiyor: Stok
   Yönetimi sunucuda Blade ile, Raf Yönetimi istemcide `shelf_management.js`
   ile. Bu yüzden Blade bileşeni olamaz — sözleşme SINIF ADI.

   Sınıf adları legacy ile AYNI (`.machines-grid`, `.sm-machine-card`,
   `.machine-search-bar`, `.machine-search-empty`): markup üreten JS'e
   dokunmadan yalnızca deri değişiyor (R6 — geçiş PR'ı yeniden adlandırmaz).

   PERFORMANS (R8): kart DÜZ yüzey, `backdrop-filter` YOK. Bir organizasyonda
   yüzlerce makine var; her kart ayrı bir blur katmanı olsa kaydırma çöker.
   Kabuk bulanıklaştırıyor, kart değil.

   DURUM: kartın alt kenarındaki doluluk çubuğu ve yüzde etiketi stok seviyesini
   `data-yg-status` üzerinden taşıyor. Renk tek sinyal değil — yanında daima
   "42 / 100" ve "%42" yazıyor (R9).
   ========================================================================== */

/* ── Arama çubuğu ──────────────────────────────────────────────────────
   İkon alanın İÇİNDE: `.form-control` bir koyu oyuk ve ikonu dışına koymak
   oyuğun kenarını ikiye bölüyordu. */
.machine-search-bar {
    position: relative;
    max-width: 420px;
}

.machine-search-bar i {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--yg-text-3);
    font-size: 13px;
    pointer-events: none;
}

.machine-search-bar input {
    padding-left: 38px;
}

.machine-search-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 40px 16px;
    color: var(--yg-text-3);
    font: 400 var(--yg-text-sm) / 1.5 var(--yg-sans);
}

@media (max-width: 768px) {
    .machine-search-bar {
        max-width: none;
    }
}

/* ── Izgara ─────────────────────────────────────────────────────────────── */
.machines-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
    gap: var(--yg-gap);
}

/* ── Kart ───────────────────────────────────────────────────────────────
   Her iki sayfada da <button>: kart tıklanabilir bir hedef ve klavyeyle
   erişilebilir olmak zorunda. Tarayıcı varsayılanları burada sıfırlanıyor. */
.sm-machine-card {
    --yg-state: var(--yg-text-2);

    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 0;
    text-align: left;
    font-family: inherit;
    color: inherit;
    appearance: none;
    -webkit-appearance: none;
    border: 1px solid var(--yg-g1-border);
    border-radius: var(--yg-radius);
    background: var(--yg-g1-flat);
    cursor: pointer;
    overflow: hidden;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        transform var(--yg-dur-press) var(--yg-ease-press);
}

.sm-machine-card:hover {
    background: var(--yg-hover);
    border-color: var(--yg-edge-info);
}

.sm-machine-card:active {
    transform: translateY(1px);
}

.sm-machine-card--button:focus-visible {
    outline: 3px solid var(--yg-info);
    outline-offset: 2px;
}

.sm-machine-card-header {
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
    padding: 13px 15px;
}

/* Gövde varsa başlıkla arasına saç teli girer. Raf Yönetimi'nde kart yalnızca
   başlıktan oluşuyor (stok göstergesi yok) — `:has()` ile çizgi orada basılmaz,
   yoksa kartın altında sahibi olmayan bir çizgi kalıyordu. */
.sm-machine-card:has(.sm-machine-card-body) .sm-machine-card-header {
    border-bottom: 1px solid var(--yg-hairline-soft);
}

.sm-machine-card-body {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 12px 15px 14px;
}

/* ── Kart içeriği ───────────────────────────────────────────────────────── */
.sm-machine-icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: var(--yg-radius-xs);
    background: var(--yg-fill-info);
    border: 1px solid var(--yg-edge-info);
    color: var(--yg-info-soft);
    font-size: 12px;
}

.sm-machine-id {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sm-machine-store {
    font: 500 var(--yg-text-sm) / 1.3 var(--yg-sans);
    color: var(--yg-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Makine numarası ve proje adı: mono, çünkü numara bir kimlik. */
.sm-machine-meta {
    font: 400 11px / 1.4 var(--yg-mono);
    color: var(--yg-text-3);
    font-variant-numeric: tabular-nums;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sm-machine-stock {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--yg-gap-sm);
}

.sm-machine-qty {
    font: 400 var(--yg-text-sm) / 1.2 var(--yg-mono);
    font-variant-numeric: tabular-nums;
    color: var(--yg-text-3);
}

/* Mevcut miktar durumu taşır, payda taşımaz: "12 / 100" okunduğunda gözün
   gitmesi gereken sayı ilki. */
.sm-machine-qty b {
    font-weight: 700;
    color: var(--yg-state-text, var(--yg-text));
}

.sm-machine-pct {
    flex: none;
    padding: 2px 8px;
    border-radius: var(--yg-radius-pill);
    background: var(--yg-state-fill, var(--yg-fill-neutral));
    border: 1px solid var(--yg-state-edge, var(--yg-edge-neutral));
    color: var(--yg-state-text, var(--yg-text-2));
    font: 500 11px / 1.5 var(--yg-mono);
    font-variant-numeric: tabular-nums;
}

.sm-machine-where {
    display: flex;
    align-items: center;
    gap: 7px;
    font: 400 var(--yg-text-xs) / 1.45 var(--yg-sans);
    color: var(--yg-text-3);
}

.sm-machine-where i {
    color: var(--yg-text-disabled);
    font-size: 10px;
}

/* ── Stok durumu ────────────────────────────────────────────────────────
   Eşikler legacy ile aynı (%70 üstü iyi, %30 altı kritik) — bu iş kuralı
   değişmiyor, yalnızca renkler token'a bağlanıyor. `-text` ayrı bir token
   çünkü dolgu rengi koyu zeminde metin olarak AA'yı geçmiyor. */
.sm-machine-card[data-yg-status='live'] {
    --yg-state: var(--yg-live);
    --yg-state-text: var(--yg-live-soft);
    --yg-state-fill: var(--yg-fill-live);
    --yg-state-edge: var(--yg-edge-live);
}

.sm-machine-card[data-yg-status='warn'] {
    --yg-state: var(--yg-action);
    --yg-state-text: var(--yg-action-soft);
    --yg-state-fill: var(--yg-fill-action);
    --yg-state-edge: var(--yg-edge-action);
}

.sm-machine-card[data-yg-status='danger'] {
    --yg-state: var(--yg-danger);
    --yg-state-text: var(--yg-danger-soft);
    --yg-state-fill: var(--yg-fill-danger);
    --yg-state-edge: var(--yg-edge-danger);
}

@media (max-width: 560px) {
    .machines-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ── assets/css/yg/20-components/section.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — sayfa başlığı, bölüm başlığı, karşılama
   --------------------------------------------------------------------------
   `.dashboard-header` + `<h1 class="dashboard-title">` deseni 20 sayfada
   kopyalanmış durumda; bu blok onun yerine geçiyor.
   ========================================================================== */

/* ── Sayfa başlığı ─────────────────────────────────────────────────────── */
/* Eylemler BAŞLIK SATIRIYLA hizalı, metin bloğunun altıyla değil. Önceden
   `align-items: flex-end` vardı: alt satırda organizasyon rozeti ya da iki
   satırlık bir açıklama olan sayfalarda düğmeler aşağıya kayıyor, başlıkla
   düğmeler arasında sebepsiz bir kademe oluşuyordu. Üstten hizalamada düğme
   (34px) başlığın satır kutusuyla (~31px) neredeyse birebir örtüşüyor. */
.yg-page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--yg-gap);
    flex-wrap: wrap;
}

.yg-page-head__text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.yg-page-head__title {
    display: flex;
    align-items: center;
    gap: 12px;
    font: 600 var(--yg-text-2xl) / 1.1 var(--yg-display);
    letter-spacing: -0.02em;
}

.yg-page-head__subtitle {
    font: 300 var(--yg-text-sm) / 1.5 var(--yg-sans);
    color: var(--yg-text-3);
    max-width: 70ch;
    text-wrap: pretty;
}

.yg-page-head__actions {
    display: flex;
    align-items: center;
    gap: var(--yg-gap-sm);
    flex-wrap: wrap;
}

/* ── Bölüm başlığı ─────────────────────────────────────────────────────── */
.yg-section {
    display: flex;
    flex-direction: column;
    gap: var(--yg-gap);
}

.yg-section__head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--yg-hair);
}

.yg-section__badge {
    --yg-state: var(--yg-info);

    flex: none;
    width: 30px;
    height: 30px;
    border-radius: var(--yg-radius-sm);
    display: grid;
    place-items: center;
    background: color-mix(in srgb, var(--yg-state) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--yg-state) 26%, transparent);
    color: var(--yg-state);
    font-size: 13px;
}

.yg-section__badge[data-yg-status='warn'] {
    --yg-state: var(--yg-action-soft);
}

.yg-section__badge[data-yg-status='danger'] {
    --yg-state: var(--yg-danger-soft);
}

.yg-section__badge[data-yg-status='live'] {
    --yg-state: var(--yg-live-soft);
}

.yg-section__title {
    font: 600 var(--yg-text-xl) / 1.15 var(--yg-display);
    letter-spacing: -0.015em;
}

.yg-section__note {
    margin-left: auto;
    font: 300 13px / 1.4 var(--yg-sans);
    color: var(--yg-text-3);
}

/* ── Eyebrow etiketi ───────────────────────────────────────────────────
   Türkçe büyük harf: `text-transform:uppercase` YALNIZCA sabit etiketlerde
   kullanılır, `{{ $degisken }}` içeriğinde ASLA — lang="tr" altında İngilizce
   bir ürün adı "internet" → "İNTERNET" olur. */
/* Satır yüksekliği 1 DEĞİL: Türkçe büyük harf işaretleri kırpılıyor.
   Ayrıntı: 20-components/table.css */
.yg-eyebrow {
    font: 500 var(--yg-text-xs) / 1.45 var(--yg-mono);
    letter-spacing: var(--yg-tracking-label);
    text-transform: uppercase;
    color: var(--yg-text-3);
}

/* ── Karşılama ─────────────────────────────────────────────────────────── */
.yg-hero {
    display: flex;
    gap: 28px;
    align-items: stretch;
}

.yg-hero__body {
    flex: 1;
    min-width: 0;
    padding: 30px 32px;
    display: flex;
    flex-direction: column;
    gap: var(--yg-gap);
}

.yg-hero__title {
    font: 600 var(--yg-text-3xl) / 1.05 var(--yg-display);
    letter-spacing: -0.03em;
}

.yg-hero__lead {
    font: 300 var(--yg-text-base) / 1.6 var(--yg-sans);
    color: var(--yg-text-2);
    max-width: 62ch;
    text-wrap: pretty;
}

.yg-hero__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
}

.yg-hero__aside {
    flex: none;
    width: 190px;
    display: grid;
    place-items: center;
    border-left: 1px solid var(--yg-hair);
    background: radial-gradient(70% 70% at 50% 40%, rgba(var(--yg-info-rgb), 0.16), transparent 70%);
}

@media (max-width: 900px) {
    .yg-hero {
        flex-direction: column;
    }

    .yg-hero__aside {
        width: 100%;
        border-left: 0;
        border-top: 1px solid var(--yg-hair);
        padding: 20px 0;
    }

    .yg-hero__title {
        font-size: 28px;
    }
}

/* ── assets/css/yg/20-components/button.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — düğmeler
   --------------------------------------------------------------------------
   `.btn-modern` panelde 242 yerde kullanılıyor ve ZATEN tek bir paylaşılan
   sınıf. Yeni bir `x-yuto.btn` bileşeni yapıp 242 çağrı yerini değiştirmek
   görsel olarak hiçbir şey kazandırmazdı — sınıfın derisi değişiyor, adı
   kalıyor (reuse over invention).

   Bootstrap `.btn-*` varyantları 03-bootstrap-bridge.css'te eşlendi; burada
   panelin kendi düğme dili var.

   Birincil düğme OPAK amber, ikincil CAM: cam üstüne cam bir düğme koymak
   hiyerarşiyi öldürüyor.
   ========================================================================== */

.btn-modern,
.yg-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    height: var(--yg-control-h-sm);
    padding: 0 16px;
    border: 1px solid var(--yg-g2-border);
    border-radius: var(--yg-radius-sm);
    background: var(--yg-g2-flat);
    backdrop-filter: var(--yg-g1-blur);
    -webkit-backdrop-filter: var(--yg-g1-blur);
    box-shadow: var(--yg-g2-sheen);
    color: var(--yg-text);
    font: 500 13.5px / 1 var(--yg-sans);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        transform var(--yg-dur-press) var(--yg-ease-press), box-shadow var(--yg-dur-color) ease;
}

.btn-modern:hover,
.yg-btn:hover {
    background: var(--yg-active);
    border-color: var(--yg-g3-border);
    color: var(--yg-text);
}

.btn-modern:active,
.yg-btn:active {
    transform: scale(0.975);
}

.btn-modern:disabled,
.yg-btn:disabled,
.btn-modern.disabled,
.yg-btn.disabled {
    background: var(--yg-fill-neutral);
    border-color: var(--yg-hair);
    color: var(--yg-text-disabled);
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
}

/* ── Birincil: tek eylem rengi, opak ───────────────────────────────────── */
.btn-modern--action,
.yg-btn--action {
    border-color: transparent;
    background: linear-gradient(180deg, var(--yg-action-hi), var(--yg-action));
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    color: var(--yg-on-action);
    font-weight: 600;
    box-shadow: 0 10px 26px -8px rgba(var(--yg-action-rgb), 0.5), var(--yg-on-action-sheen);
}

.btn-modern--action:hover,
.yg-btn--action:hover {
    background: linear-gradient(180deg, var(--yg-action-hi2), var(--yg-action-hi));
    border-color: transparent;
    color: var(--yg-on-action);
}

/* ── Yıkıcı ────────────────────────────────────────────────────────────── */
.btn-modern--danger,
.yg-btn--danger {
    background: var(--yg-fill-danger);
    border-color: rgba(var(--yg-danger-rgb), 0.42);
    color: var(--yg-danger-soft);
}

.btn-modern--danger:hover,
.yg-btn--danger:hover {
    background: rgba(var(--yg-danger-rgb), 0.2);
    border-color: var(--yg-danger);
    color: var(--yg-danger-soft);
}

/* ── Sessiz (ghost) ────────────────────────────────────────────────────── */
.btn-modern--quiet,
.yg-btn--quiet {
    background: transparent;
    border-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    color: var(--yg-text-2);
}

.btn-modern--quiet:hover,
.yg-btn--quiet:hover {
    background: var(--yg-hover);
    border-color: transparent;
    color: var(--yg-text);
}

/* ── Boyutlar — LSP: varyant değişince satır yüksekliği kaymaz ─────────── */
.btn-modern--sm,
.yg-btn--sm {
    height: 34px;
    padding: 0 12px;
    font-size: 12.5px;
}

.btn-modern--lg,
.yg-btn--lg {
    height: var(--yg-control-h);
    padding: 0 22px;
    font-size: var(--yg-text-lg);
    border-radius: var(--yg-radius);
}

.btn-modern--block,
.yg-btn--block {
    width: 100%;
}

/* ── Yalnızca ikon ─────────────────────────────────────────────────────── */
.yg-btn--icon {
    width: var(--yg-control-h-sm);
    padding: 0;
}

.yg-btn--icon.yg-btn--sm {
    width: 34px;
}

/* ── Meşgul durumu ─────────────────────────────────────────────────────
   Sayfa yüklenmesi iskeletle anlatılır; DÜĞME içindeki meşguliyet küçük bir
   halka ile — tasarım dilinin düğme örneğinde bu halka var. */
@keyframes ygSpin {
    to { transform: rotate(360deg); }
}

.yg-btn__ring {
    flex: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid var(--yg-on-action-ring);
    border-top-color: currentColor;
    animation: ygSpin 0.7s linear infinite;
}

.yg-btn--action .yg-btn__ring {
    border-color: var(--yg-on-action-ring);
    border-top-color: var(--yg-on-action);
}

.yg-btn[aria-busy='true'] {
    cursor: progress;
}

/* ── İkon eylem düğmesi ─────────────────────────────────────────────────
   Tablo satırındaki düzenle/sil düğmeleri. `.product-action-btn` legacy adı
   beş sayfada geçiyor (kullanıcılar, mağazalar, reklamlar, promosyonlar,
   ürünler) ve bir kısmını sayfa JS'i basıyor — ad korundu (R6).

   Durum yalnızca renkle verilmiyor: ikon şekli (kalem / çöp kutusu) zaten
   eylemi söylüyor, renk onu pekiştiriyor. */
.yg-btn--icon,
.product-action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--yg-g1-border);
    border-radius: var(--yg-radius-xs);
    background: var(--yg-g1-flat);
    color: var(--yg-text-2);
    font-size: 12px;
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease,
        color var(--yg-dur-color) ease;
}

.yg-btn--icon:hover,
.product-action-btn:hover {
    background: var(--yg-hover);
    border-color: var(--yg-g2-border);
    color: var(--yg-text);
}

.product-action-btn.edit-btn {
    color: var(--yg-info-soft);
}

.product-action-btn.edit-btn:hover {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
}

.product-action-btn.delete-btn {
    color: var(--yg-danger-soft);
}

.product-action-btn.delete-btn:hover {
    background: var(--yg-fill-danger);
    border-color: var(--yg-edge-danger);
}

.product-action-btn:disabled {
    color: var(--yg-text-disabled);
    cursor: not-allowed;
}

/* ── Düğme içindeki sayaç çipi ──────────────────────────────────────────
   "Kaydet 12" gibi düğmeler sayacı bir çip olarak taşıyor. `.yg-chip`'in
   varsayılan derisi cam üstü için: nötr dolgu + `--yg-text-3`. Amber düğmenin
   üstünde bu kombinasyon 1.31:1 kontrastla okunmuyordu (ölçüldü). Düğmenin
   kendi mürekkebini devralıyor. */
.yg-btn--action .yg-chip {
    background: var(--yg-on-action-ring);
    border-color: transparent;
    color: var(--yg-on-action);
}

.yg-btn--danger .yg-chip {
    background: rgba(var(--yg-text-rgb), 0.22);
    border-color: transparent;
    color: var(--yg-text);
}

/* ── assets/css/yg/20-components/pagination.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — sayfalama
   --------------------------------------------------------------------------
   Panelde ÜÇ ayrı kopyası var, üçü de aynı sınıf adlarını ve neredeyse aynı
   CSS'i taşıyor:
     admin/activity-logs.blade.php:358   (CSS :83-121)
     service-requests/index.blade.php:296 (CSS :102-137)
     filo/sales.blade.php:175            (CSS :22-34)
   Bu blok üçünün yerine geçiyor. Sınıf adları legacy `.pagination-*` ile aynı
   tutuldu: bu üç sayfanın JS'i düğmeleri bu adlarla üretiyor ve sorguluyor,
   yani markup üreten JS değişmeden çalışmaya devam ediyor.
   ========================================================================== */

.pagination-wrap,
.yg-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--yg-gap);
    flex-wrap: wrap;
    padding: 14px 20px;
    border-top: 1px solid var(--yg-hair);
}

/* Sayfalama tek sayfalık sonuçta hiç gösterilmiyor. Görünürlüğü sayfa JS'i
   `hidden` niteliğiyle çeviriyor; `display: flex` onu ezmesin diye burada
   nitelik seçicisi var (özgüllük 0,2,0 → !important gerekmiyor). */
.pagination-wrap[hidden],
.yg-pagination[hidden] {
    display: none;
}

.pagination-info,
.yg-pagination__info {
    font: 400 11.5px / 1.4 var(--yg-mono);
    color: var(--yg-text-3);
    font-variant-numeric: tabular-nums;
}

.pagination-btns,
.pagination-controls,
.yg-pagination__controls {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.pagination-btns button,
.pagination-controls button,
.yg-pagination__controls button {
    min-width: 34px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius-xs);
    background: var(--yg-g1-flat);
    color: var(--yg-text-2);
    font: 500 12px / 1 var(--yg-mono);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, color var(--yg-dur-color) ease,
        border-color var(--yg-dur-color) ease;
}

.pagination-btns button:hover:not(:disabled),
.pagination-controls button:hover:not(:disabled),
.yg-pagination__controls button:hover:not(:disabled) {
    background: var(--yg-hover);
    border-color: var(--yg-g2-border);
    color: var(--yg-text);
}

.pagination-btns button.active,
.pagination-controls button.active,
.yg-pagination__controls button.active {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

.pagination-btns button:disabled,
.pagination-controls button:disabled,
.yg-pagination__controls button:disabled {
    color: var(--yg-text-disabled);
    cursor: not-allowed;
}

.pagination-per-page,
.yg-pagination__per-page {
    display: flex;
    align-items: center;
    gap: 8px;
    font: 400 11.5px / 1 var(--yg-mono);
    color: var(--yg-text-3);
}

.pagination-per-page select,
.yg-pagination__per-page select {
    height: 34px;
    padding: 0 8px;
    border: 1px solid var(--yg-hair);
    border-radius: var(--yg-radius-xs);
    background: var(--yg-well);
    box-shadow: var(--yg-well-inset);
    color: var(--yg-text);
    font: 500 12px / 1 var(--yg-mono);
}

/* ── assets/css/yg/20-components/empty.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — boş durum
   --------------------------------------------------------------------------
   "Boş durum da bir ekran": her boş durum bir EYLEM önerir. Maskot burada
   süs değil, durumu anlatan tek görsel.
   ========================================================================== */

.yg-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 34px 20px;
    text-align: center;
}

.yg-empty__title {
    font: 600 var(--yg-text-lg) / 1.3 var(--yg-display);
    color: var(--yg-text);
}

.yg-empty__message {
    font: 400 var(--yg-text-sm) / 1.55 var(--yg-sans);
    color: var(--yg-text-3);
    max-width: 34ch;
    text-wrap: pretty;
}

.yg-empty__action {
    margin-top: 4px;
}

/* Tablo/liste içinde daha sıkı varyant */
.yg-empty--inline {
    padding: 26px 16px;
    gap: 10px;
}

.yg-empty--inline .yg-empty__title {
    font-size: var(--yg-text-base);
}

/* ── Legacy adlı boş durum ──────────────────────────────────────────────
   `.empty-state` markup'ını sayfa JS'i üretiyor (aktivite logları, servis
   talepleri, siparişler…). Sınıf adı korunuyor, yalnızca deri değişiyor.
   Maskot yok: JS tarafında maskot kuralını uygulayamıyoruz (bağlam/boyut
   kararı PHP'de), o yüzden ikon + metin ile yetiniyor. */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 40px 20px;
    text-align: center;
    color: var(--yg-text-3);
}

.empty-state i {
    font-size: 26px;
    opacity: 0.45;
}

/* "Yüklenemedi" bir boşluk DEĞİL hata: veri yok ile veri alınamadı arasındaki
   fark kullanıcı için önemli (biri bekler, öteki tekrar dener). İkon ve metin
   kırmızıya döner ama ikon da değişir (ünlem) — renk tek sinyal değil (R9).
   `analytics.js` ve `shelf_management.js` bu varyantı üretiyor. */
.empty-state.is-danger {
    color: var(--yg-danger-soft);
}

.empty-state.is-danger i {
    opacity: 0.75;
}

.empty-state p {
    margin: 0;
    font: 400 var(--yg-text-sm) / 1.5 var(--yg-sans);
    max-width: 40ch;
}

/* ── assets/css/yg/20-components/mascot.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — maskot
   --------------------------------------------------------------------------
   Kurallar (tasarım dili el kitabından, kod tarafında App\Support\Ui\Mascot
   ile zorlanıyor; burada yalnızca görünüm):

     • KAFA HİÇ RENKLENDİRİLMEZ. Durum arkadaki halede taşınır.
     • 96px altına inilmez — vizör kapanır, ifade okunmaz.
     • Maskot dokunma hedefi değil: hover/rotate/scale efekti verilmez.
     • Bir ekranda tek maskot.

   R5: `.yg-mascot img` üzerinde `drop-shadow` dışında `filter` YASAK.
   ========================================================================== */

.yg-mascot {
    --yg-state: var(--yg-live);

    position: relative;
    display: grid;
    place-items: center;
    width: var(--yg-mascot-size, 130px);
    height: var(--yg-mascot-size, 130px);
    margin: 0;
    flex: none;
}

/* Durum halesi — kafanın arkasında, %16 opaklıkta */
.yg-mascot::before {
    content: '';
    position: absolute;
    inset: -18%;
    border-radius: 50%;
    background: radial-gradient(circle, var(--yg-state) 0%, transparent 68%);
    opacity: 0.16;
    pointer-events: none;
}

.yg-mascot[data-yg-status='warn'] {
    --yg-state: var(--yg-action);
}

.yg-mascot[data-yg-status='danger'] {
    --yg-state: var(--yg-danger);
}

.yg-mascot[data-yg-status='info'] {
    --yg-state: var(--yg-info);
}

.yg-mascot[data-yg-status='idle'] {
    --yg-state: var(--yg-text-3);
}

.yg-mascot img {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* Tek izinli filtre. Kafanın rengine dokunmaz, yalnızca zeminden ayırır. */
    filter: drop-shadow(0 12px 30px rgba(var(--yg-info-rgb), 0.35));
}

/* Sakin ifadelerde (notr, uykuda, uzgun) dosya animasyonu yavaş; tasarım dili
   üstüne hafif bir "nefes" eklenmesine izin veriyor: 1.9s, ölçek 1.04.
   Hareket azaltmada 02-base.css'teki global kural durduruyor. */
@keyframes ygMascotBreathe {
    0%, 100% { transform: scale(1) translateY(0); }
    50% { transform: scale(1.04) translateY(-3px); }
}

.yg-mascot--breathe img {
    animation: ygMascotBreathe 1.9s ease-in-out infinite;
}

/* ── assets/css/yg/20-components/skeleton.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — iskelet (yükleniyor)
   --------------------------------------------------------------------------
   "Dönen çark yoktur": yüklenme, gelecek içeriğin ŞEKLİNDE bir iskeletle ve
   kartın üst kenarındaki akan ışık şeridiyle anlatılır.

   Sınıf adları legacy enhancements.css ile AYNI (.skeleton, .skeleton-text)
   — mevcut iskelet markup'ı ve onu üreten JS değişmeden çalışmaya devam
   ediyor, yalnızca deri değişiyor. Camda iskelet gri blokla değil PARLAKLIKLA
   çalışır.
   ========================================================================== */

.skeleton,
.yg-skeleton {
    background: var(--yg-skeleton-sweep);
    background-size: 420px 100%;
    border-radius: var(--yg-radius-xs);
    animation: ygSkeleton 1.4s linear infinite;
}

.skeleton-text,
.yg-skeleton--text {
    height: 12px;
    width: var(--yg-skeleton-w, 100%);
    border-radius: 6px;
}

.yg-skeleton--title {
    height: 15px;
    width: var(--yg-skeleton-w, 70%);
    border-radius: 6px;
}

.yg-skeleton--value {
    height: 28px;
    width: 45%;
    border-radius: var(--yg-radius-xs);
}

/* Rozetin yerini tutan parça: yuvarlak uçlu, satır yüksekliğinde. */
.yg-skeleton--pill {
    height: 22px;
    width: var(--yg-skeleton-w, 90px);
    border-radius: var(--yg-radius-pill);
}

.yg-skeleton--thumb {
    width: 62px;
    height: 78px;
    border-radius: var(--yg-radius-sm);
}

.yg-skeleton--avatar {
    width: 36px;
    height: 36px;
    border-radius: var(--yg-radius-sm);
}

/* Bir kartın/kutunun yerini tutan parça. Yüksekliği knob: raf kutusu ile makine
   kartı farklı boyda ve iskeletin gelecek düzenle aynı ölçüde olması gerekiyor —
   iskelet ile gerçek içerik farklı yükseklikteyse yükleme bitince sayfa zıplar. */
.yg-skeleton--box {
    height: var(--yg-skeleton-h, 120px);
    border-radius: var(--yg-radius-sm);
}

/* İkinci ve sonraki satırlar sabit (parıltı yok): sekiz satırın birlikte
   parlaması gözü yoruyor, ilk satır yeterli sinyal. */
.yg-skeleton--still {
    background: var(--yg-skeleton-still);
    animation: none;
}

.yg-skeleton-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: var(--yg-pad-row);
}

.yg-skeleton-row__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

/* İkinci ve sonraki iskelet satırları geri planda kalır: göz ilk satıra
   odaklansın. */
.yg-skeleton-row--dim {
    opacity: 0.6;
}

/* ── Legacy adlı yükleniyor kabı ────────────────────────────────────────
   Sayfa JS'i tablo gövdesine `.loading-spinner` basıyor. Tasarım dili sayfa
   yüklenmesinde dönen çark istemiyor ama bu markup JS'te üretildiği için
   iskelete çeviremiyoruz (satır sayısı/şekli bilinmiyor). Çarkı sakinleştirip
   ortalıyoruz; iskelete geçiş o sayfaların JS'i elden geçerken yapılacak. */
.loading-spinner {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 44px 20px;
}

.loading-spinner .spinner-border {
    width: 24px;
    height: 24px;
    border-width: 2px;
    color: var(--yg-info);
    opacity: 0.7;
}

/* ── assets/css/yg/20-components/feedback.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · bileşen — geri bildirim (uyarı şeridi, toast, onay kutusu)
   --------------------------------------------------------------------------
   Toast ve onay kutusu markup'ı public/js/enhancements.js tarafından
   üretiliyor ve `body` altına eklendiği için kart bağlamı dışında yaşıyor.
   Sınıf adları legacy dosyayla aynı (.toast-enhanced, .confirm-*) — JS
   imzaları değişmedi, yalnızca deri değişti.

   NOT: legacy enhancements.css bu sayfalarda YÜKLENMİYOR (glass layout onu
   linklemiyor), o yüzden burada tam tanım veriliyor, "override" değil.
   ========================================================================== */

/* ── Uyarı şeridi (sayfa içi bildirim) ─────────────────────────────────── */
.yg-notice {
    --yg-state: var(--yg-info);
    --yg-state-fill: var(--yg-fill-info);
    --yg-state-edge: var(--yg-edge-info);

    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 15px 17px;
    border-radius: var(--yg-radius);
    background: var(--yg-state-fill);
    border: 1px solid var(--yg-state-edge);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    color: var(--yg-text);
    font: 400 13px / 1.5 var(--yg-sans);
}

.yg-notice[data-yg-status='warn'] {
    --yg-state: var(--yg-action);
    --yg-state-fill: rgba(var(--yg-action-rgb), 0.11);
    --yg-state-edge: rgba(var(--yg-action-rgb), 0.26);
}

.yg-notice[data-yg-status='danger'] {
    --yg-state: var(--yg-danger);
    --yg-state-fill: rgba(var(--yg-danger-rgb), 0.1);
    --yg-state-edge: rgba(var(--yg-danger-rgb), 0.24);
}

.yg-notice[data-yg-status='live'] {
    --yg-state: var(--yg-live);
    --yg-state-fill: rgba(var(--yg-live-rgb), 0.1);
    --yg-state-edge: rgba(var(--yg-live-rgb), 0.24);
}

.yg-notice__dot {
    flex: none;
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--yg-state);
}

.yg-notice__body {
    flex: 1;
    min-width: 0;
}

.yg-notice__close {
    flex: none;
    width: 24px;
    height: 24px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: var(--yg-radius-xs);
    background: transparent;
    color: var(--yg-text-2);
    cursor: pointer;
}

.yg-notice__close:hover {
    background: var(--yg-hover);
    color: var(--yg-text);
}

/* ── Toast ─────────────────────────────────────────────────────────────── */
@keyframes ygToastIn {
    from {
        opacity: 0;
        transform: translateX(24px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.toast-enhanced {
    --yg-state: var(--yg-info);
    --yg-state-fill: var(--yg-fill-info);
    --yg-state-edge: var(--yg-edge-info);

    position: fixed;
    top: 20px;
    right: 20px;
    z-index: var(--yg-z-toast);
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 450px;
    padding: 14px 18px;
    border-radius: var(--yg-radius);
    /* Toast sayfa içeriğinin üstünde uçuyor; arkasında ışık VAR ama kaydırılan
       içerik değişken olduğu için okunurluğu opak tabana bağlıyoruz. */
    background: var(--yg-g3-fill), var(--yg-surface-floating);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    border: 1px solid var(--yg-state-edge);
    border-left: 3px solid var(--yg-state);
    box-shadow: var(--yg-g3-shadow), var(--yg-g3-sheen);
    color: var(--yg-text);
    font: 500 13px / 1.45 var(--yg-sans);
    animation: ygToastIn var(--yg-dur-color) var(--yg-ease-sheet);
    transition: opacity var(--yg-dur-color) ease, transform var(--yg-dur-color) ease;
}

.toast-enhanced > .fas,
.toast-enhanced > .far {
    color: var(--yg-state);
}

.toast-enhanced--success {
    --yg-state: var(--yg-live);
    --yg-state-edge: var(--yg-edge-live);
}

.toast-enhanced--danger {
    --yg-state: var(--yg-danger);
    --yg-state-edge: var(--yg-edge-danger);
}

.toast-enhanced--warning {
    --yg-state: var(--yg-action);
    --yg-state-edge: var(--yg-edge-action);
}

.toast-enhanced--info {
    --yg-state: var(--yg-info);
    --yg-state-edge: var(--yg-edge-info);
}

.toast-enhanced .toast-close {
    flex: none;
    margin-left: 6px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    opacity: 0.5;
    font-size: 12px;
    cursor: pointer;
    transition: opacity var(--yg-dur-color) ease;
}

.toast-enhanced .toast-close:hover {
    opacity: 1;
}

/* ── Onay kutusu ───────────────────────────────────────────────────────── */
.confirm-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--yg-z-modal);
    display: grid;
    place-items: center;
    padding: 20px;
    background: var(--yg-scrim);
    backdrop-filter: var(--yg-scrim-blur);
    -webkit-backdrop-filter: var(--yg-scrim-blur);
}

.confirm-dialog {
    width: 100%;
    max-width: 420px;
    padding: 26px;
    border-radius: var(--yg-radius-xl);
    /* Perde üstü yüzey: cam dolgusu + opak taban. Bkz. 00-tokens.css */
    background: var(--yg-g3-fill), var(--yg-surface-floating);
    backdrop-filter: var(--yg-g3-blur);
    -webkit-backdrop-filter: var(--yg-g3-blur);
    border: 1px solid var(--yg-g3-border);
    box-shadow: var(--yg-g3-shadow), var(--yg-g3-sheen);
    display: flex;
    flex-direction: column;
    gap: 14px;
    text-align: center;
}

.confirm-icon {
    width: 52px;
    height: 52px;
    margin: 0 auto;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--yg-fill-neutral);
    border: 1px solid var(--yg-edge-neutral);
    color: var(--yg-text-2);
    font-size: 20px;
}

.confirm-icon.danger {
    background: var(--yg-fill-danger);
    border-color: var(--yg-edge-danger);
    color: var(--yg-danger-soft);
}

.confirm-icon.warning {
    background: var(--yg-fill-action);
    border-color: var(--yg-edge-action);
    color: var(--yg-action-soft);
}

.confirm-icon.info {
    background: var(--yg-fill-info);
    border-color: var(--yg-edge-info);
    color: var(--yg-info-soft);
}

.confirm-title {
    font: 600 var(--yg-text-lg) / 1.3 var(--yg-display);
    color: var(--yg-text);
}

.confirm-message {
    font: 400 13px / 1.55 var(--yg-sans);
    color: var(--yg-text-2);
}

.confirm-actions {
    display: flex;
    gap: 10px;
    margin-top: 4px;
}

.confirm-cancel,
.confirm-ok {
    flex: 1;
    height: var(--yg-control-h-sm);
    border-radius: var(--yg-radius-sm);
    font: 500 14px / 1 var(--yg-sans);
    cursor: pointer;
    transition: background var(--yg-dur-color) ease, border-color var(--yg-dur-color) ease;
}

.confirm-cancel {
    border: 1px solid var(--yg-g2-border);
    background: var(--yg-g2-flat);
    color: var(--yg-text);
}

.confirm-cancel:hover {
    background: var(--yg-active);
}

.confirm-ok {
    border: 0;
    background: var(--yg-action);
    color: var(--yg-on-action);
    font-weight: 600;
}

.confirm-ok:hover {
    background: var(--yg-action-hi);
}

/* Kırmızı dolgunun ÜSTÜNDE koyu mürekkep — amber düğmeyle aynı gerekçe:
   `--yg-danger` (#FF5A52) açık bir kırmızı, beyaz metinle 2.74:1 veriyor ve
   AA'nın altında kalıyor (ölçüldü). Koyu mürekkeple 6.55:1.
   Hover'da dolgu daha da açılıyor, mürekkep koyu kalıyor. */
.confirm-ok.danger {
    background: var(--yg-danger);
    color: var(--yg-ink);
}

.confirm-ok.danger:hover {
    background: var(--yg-danger-soft);
    color: var(--yg-ink);
}

/* ── assets/css/yg/90-utilities.css ─────────────────────────────────────── */
/* ==========================================================================
   Yuto Glass · 90 — Yardımcılar
   --------------------------------------------------------------------------
   BİLİNÇLİ OLARAK KISA. Utility-first yaklaşım burada yanlış: build adımı yok,
   dolayısıyla purge yok — elle bakılan bir yardımcı sayfası şişer ve JS'in
   ürettiği markup 12 sınıflı stringlere döner.

   Bootstrap'in RENK TAŞIMAYAN yerleşim yardımcıları (row, col-*, d-flex,
   gap-*, mb-3, text-end) olduğu gibi kullanılmaya devam ediyor — panelde
   314 `col-*` ve 160 `d-flex` var, hepsi bu geçişten sağ çıkıyor.
   Burada yalnızca Bootstrap'te KARŞILIĞI OLMAYANLAR var.
   ========================================================================== */

/* Izgara — kart listeleri. auto-fit ile kırılma noktası gerektirmez. */
.yg-grid {
    display: grid;
    gap: var(--yg-gap);
    grid-template-columns: repeat(auto-fit, minmax(var(--yg-grid-min, 250px), 1fr));
}

.yg-grid--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.yg-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.yg-grid--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* İki kolon, biri baskın. Oran KNOB: bazı sayfalarda ağırlık solda (liste +
   detay), bazılarında sağda (kimlik + form). Sayfanın `grid-template-columns`'u
   yeniden yazması R7 ihlali olurdu — o zaman aşağıdaki dar ekran kırılımlarını
   da kopyalaması gerekirdi ve biri unutulurdu. */
.yg-grid--split {
    grid-template-columns: minmax(0, var(--yg-split-a, 1.35fr)) minmax(0, var(--yg-split-b, 1fr));
    align-items: start;
}

@media (max-width: 1180px) {
    .yg-grid--split,
    .yg-grid--4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 900px) {
    .yg-grid--2,
    .yg-grid--3,
    .yg-grid--4,
    .yg-grid--split {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Dikey yığın — boşluk daima ebeveynin gap'i (bileşen kendi margin'ini
   tanımlamıyor, bkz. docs/tasarim-dili.md · SRP). */
.yg-stack {
    display: flex;
    flex-direction: column;
    gap: var(--yg-stack-gap, var(--yg-gap));
}

.yg-stack--tight {
    --yg-stack-gap: 8px;
}

.yg-inline {
    display: flex;
    align-items: center;
    gap: var(--yg-inline-gap, var(--yg-gap-sm));
    flex-wrap: wrap;
}

/* Sayı biçimi — kolonlar hizalanmalı */
.yg-num {
    font-family: var(--yg-mono);
    font-variant-numeric: tabular-nums;
}

.yg-money {
    font-family: var(--yg-mono);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.yg-money--strong {
    font-weight: 700;
    color: var(--yg-text);
}

/* Metin tonları */
.yg-t-2 { color: var(--yg-text-2); }
.yg-t-3 { color: var(--yg-text-3); }
.yg-t-live { color: var(--yg-live-soft); }
.yg-t-warn { color: var(--yg-action-soft); }
.yg-t-danger { color: var(--yg-danger-soft); }
.yg-t-info { color: var(--yg-info-soft); }

/* Taşan uzun metin */
.yg-truncate {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Yazdırmada gizlenecek öğeler için işaret */
.no-print {
    /* kural @media print içinde (02-base.css) */
    display: revert;
}

/* Kabuksuz belge gövdesi (giriş, hata, laboratuvar).
   Flex kolon: içerik `margin: auto` ile dikeyde ortalanabiliyor (giriş kartı),
   ya da normal akışta yukarıdan başlıyor (laboratuvar). */
.yg-bare {
    position: relative;
    z-index: var(--yg-z-content);
    min-height: 100vh;
    padding: 40px 28px 64px;
    display: flex;
    flex-direction: column;
}

/* Sağa yaslama — flex/grid içinde bir öğeyi uca itmek. Bootstrap'in `ms-auto`
   karşılığı; yg bileşenleri Bootstrap yardımcılarına bağımlı kalmasın diye
   kendi adıyla var. */
.yg-push {
    margin-left: auto;
}
