/* OtoSOR data display: cards, tables, badges, tags, KPIs, key-value lists. */

/* ── Card ───────────────────────────────────────────────── */
.os-card {
  background: var(--surface-card); border: 1px solid var(--border-default);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xs);
}
.os-card__header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-default);
}
.os-card__title { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.os-card__body { padding: var(--space-5); }
.os-card__footer {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border-default);
  background: var(--gray-25); border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* ── TAŞMA KORUMASI (genel) ───────────────────────────────────────
   Kök sebep: grid ve flex öğelerinin varsayılan min-width'i "auto"dur;
   yani öğe, içeriğinin en uzun kırılamayan parçasından daha ince
   olamaz. Şasi no (17+ karakter), IBAN, uzun model adı ve e-posta bu
   yüzden kabı taşırıyor — kap daralınca içerik daralmıyor.
   Çözüm iki parçalı: min-width:0 (daralmaya izin ver) +
   overflow-wrap:anywhere (son çare kelimeyi böl). Kırpmak yerine
   bölmek tercih edilir: veri okunabilir kalır.
   NOT: metin taşıyan her yeni bileşene bu ikili eklenir. */
.os-card, .os-card__header, .os-card__body, .os-card__footer,
.os-signal, .os-signal__value,
.os-detailhead, .os-detailhead__titles, .os-detailhead__titlerow, .os-detailhead__meta,
.os-timeline__item, .os-timeline__title, .os-timeline__desc,
.os-kpi, .os-kpi__value, .os-empty, .os-empty__desc,
.os-alert, .os-toast__msg, .os-field, .os-formgrid > * {
  min-width: 0;
}
.os-signal__value, .os-detailhead__code, .os-timeline__desc,
.os-kpi__value, .os-empty__desc, .os-alert, .os-toast__msg,
.os-table td { overflow-wrap: break-word; }
.os-badge, .os-tag { overflow-wrap: anywhere; }
/* Rozet ve çip KIRILMAZ (kısa metin, tek satır kalmalı) ama taşarsa
   kırpılır — kabın dışına çıkmaz.
   DİKKAT: overflow:hidden, flex öğesinin otomatik asgari boyutunu 0'a
   düşürür (min-width:auto artık min-content'i korumaz). flex-shrink
   varsayılan 1 olduğu için rozet, kap geniş olsa bile içeriğinin altına
   inip kırpılıyordu. Bu yüzden ETİKET bağlamlarında flex:none şart. */
.os-badge, .os-tag { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* Kart başlığındaki rozet esnek içerik değil ETİKET: kırpılmaz.
   Aynısı detay başlığı ve tablo başlığı için de geçerli. */
.os-card__header > .os-badge,
.os-card__header > .os-tag,
.os-card__header .os-badge,
.os-detailhead__titlerow > .os-badge,
.os-table th .os-badge { flex: none; }

/* ── Badge (status) ─────────────────────────────────────── */
.os-badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 var(--space-2);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  border-radius: var(--radius-sm); white-space: nowrap;
}
.os-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.os-badge--success { background: var(--status-success-bg); color: var(--status-success-fg); }
.os-badge--warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.os-badge--danger  { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.os-badge--info    { background: var(--status-info-bg);    color: var(--status-info-fg); }
/* İade / eksik evrak — "Yaklaşan" (kehribar, hue 35°) ile arasında yalnız
   20° hue farkı var ve renk körü benzetiminde ikisi de aynı renge çöküyor.
   Renk DEĞİŞTİRİLMEDİ (turuncu portal kanoniği --pending), ayrım BİÇİME
   taşındı: kesikli kenarlık + geri-dönüş oku. Aynı ilke stepper--skipped
   ve DecisionButtons'ta da kullanılıyor — ton ailesi tükendiğinde bir
   sonraki ayırt edici renk değil FORM olur. */
.os-badge--returned {
  background: var(--status-returned-bg); color: var(--status-returned-fg);
  border: 1px dashed var(--status-returned-solid);
}
.os-badge--returned::before {
  /* Nokta kutusu SIFIRLANIR — yalnız content değiştirmek yetmiyor,
     tabandaki 6x6 daire glifin arkasında kalıyor. */
  content: "↩";
  width: auto; height: auto; border-radius: 0; background: none;
  font-size: 1em; line-height: 1; font-weight: 700;
}
.os-badge--neutral { background: var(--surface-sunken);    color: var(--text-secondary); }
.os-badge--solid-danger { background: var(--status-danger-solid); color: var(--text-inverse); }
.os-badge--solid-danger::before { background: var(--text-inverse); }

/* ── Tag (removable filter chip) ────────────────────────── */
.os-tag {
  display: inline-flex; align-items: center; gap: var(--space-1);
  /* height → min-height (2026-10-26): dar kapta uzun etiket ("2026/4360 / ŞİLE İCRA MÜDÜRLÜĞÜ") ikinci satıra inince
     sabit yükseklikten taşıyordu; tek satırlık çip aynı kalır, uzun olan uzar. */
  min-height: 24px; padding: 2px var(--space-2); line-height: 1.3;
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  color: var(--text-brand); background: var(--surface-selected);
  border: 1px solid var(--blue-100); border-radius: var(--radius-sm);
}
.os-tag__x { cursor: pointer; opacity: 0.6; font-size: 13px; line-height: 1; border: 0; background: none; color: inherit; padding: 0 0 0 2px; }
.os-tag__x:hover { opacity: 1; }

/* ── Table ──────────────────────────────────────────────── */
.os-tablewrap { overflow-x: auto; border: 1px solid var(--border-default); border-radius: var(--radius-lg); background: var(--surface-card); }
.os-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.os-table th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-secondary); background: var(--gray-50);
  border-bottom: 1px solid var(--border-default); white-space: nowrap;
}
.os-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--gray-100);
  vertical-align: middle;
}
.os-table tbody tr:last-child td { border-bottom: 0; }
.os-table tbody tr:hover { background: var(--gray-25); }
.os-table tbody tr.os-row--selected { background: var(--surface-selected); }
.os-table .os-cell--num, .os-table th.os-cell--num { text-align: right; }
.os-table td.os-cell--num { font-feature-settings: var(--numeric-features); white-space: nowrap; }
.os-table--dense th, .os-table--dense td { padding: 6px var(--space-2); }
/* Ayarlar > Tablo Yogunlugu (UserSettings.applyTableDensity -> body.table-density-*). Kurallar css/layout.css'teydi
   ve o dosya hicbir sayfada yuklenmiyordu: ayar degisse de tablolar degismiyordu (2026-10-15). Kart (stacked) etkilenmez. */
body.table-density-compact .os-table:not(.os-table--stacked) th { padding: 4px var(--space-2); font-size: var(--text-2xs); }
body.table-density-compact .os-table:not(.os-table--stacked) td { padding: 3px var(--space-2); font-size: var(--text-sm); }
body.table-density-comfortable .os-table:not(.os-table--stacked) th { padding: var(--space-3) var(--space-4); font-size: var(--text-sm); }
body.table-density-comfortable .os-table:not(.os-table--stacked) td { padding: var(--space-3) var(--space-4); font-size: var(--text-md); }
.os-table tfoot td {
  padding: var(--space-2) var(--space-3);
  background: var(--gray-50); font-weight: var(--weight-semibold);
  border-top: 2px solid var(--border-strong);
}
/* Yoğun tabloda toplam satırı da yoğundur: bu kural tfoot bloğundan SONRA
   ve iki sınıflı (0,2,2) — aksi hâlde eşit özgüllükte kalıp kaybediyor ve
   toplam satırı gövdeden geniş olup kırpılıyordu. */
.os-table.os-table--dense tfoot td { padding: 6px var(--space-2); }

/* ── KPI / Stat ─────────────────────────────────────────── */
.os-kpi { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-4) var(--space-5); }
.os-kpi__label { font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
.os-kpi__value {
  font-size: var(--text-3xl); font-weight: var(--weight-bold); line-height: 1.1;
  font-feature-settings: var(--numeric-features);
}
.os-kpi__delta { font-size: var(--text-sm); font-weight: var(--weight-medium); display: inline-flex; align-items: center; gap: 4px; }
.os-kpi__delta--up { color: var(--amount-positive); }
.os-kpi__delta--down { color: var(--amount-negative); }

/* ── MOBİLDE SCROLLBAR YOK ───────────────────────────────
   Kural: <640px'te hiçbir kapta görünür scrollbar bulunmaz.
   Sebep: dokunmatikte scrollbar bir KONTROL değil, yalnız yer kaplayan
   bir göstergedir — parmak zaten doğrudan kaydırıyor. Görünür kalırsa
   (a) kabın yüksekliğini büyütür ve alt kenarlıkla karışır,
   (b) kullanıcı onu tutulabilir sanır.
   Kaydırma DAVRANIŞI korunur; "devamı var" bilgisi scrollbar yerine
   kenar solumasıyla (fade) ve gerekiyorsa ok butonuyla verilir. */
@media (max-width: 639px) {
  .os-tablewrap,
  .os-tabs,
  .os-swimlanes,
  .os-scrollx {
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .os-tablewrap::-webkit-scrollbar,
  .os-tabs::-webkit-scrollbar,
  .os-swimlanes::-webkit-scrollbar,
  .os-scrollx::-webkit-scrollbar { width: 0; height: 0; display: none; }

  /* Yatay kaydırılan kaplarda sağ kenar soluması: içeriğin devam ettiğini
     scrollbar olmadan gösterir. Kaydırma sonuna gelince JS --at-end
     sınıfını koyar ve soluma kalkar. */
  .os-tablewrap:has(.os-table--scroll),
  .os-swimlanes,
  .os-scrollx {
    /* #000 burada RENK DEĞİL: maske alfa kanalı (opak/şeffaf). Token almaz. */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
  }
  .os-tablewrap.at-end,
  .os-swimlanes.at-end,
  .os-scrollx.at-end { -webkit-mask-image: none; mask-image: none; }
}

/* ── MOBİLDE TABLO → KART ────────────────────────────────
   Yoğun bir tabloyu küçük ekranda yatay kaydırmaya bırakmak, kullanıcıyı
   tek satırı okumak için sağa sola gitmeye zorlar: bir hücreyi görürken
   hangi kaydın hücresi olduğunu göremez. <640px'te her SATIR bir KARTA
   dönüşür; kolon başlıkları her kartın içinde etiket olarak tekrarlanır
   (td[data-label]) ve sayfa yalnız AŞAĞI kaydırılır.

   Kullanım: her <td> kendi kolon başlığını data-label ile taşır.
     <td data-label="Kalan" class="os-cell--num">612.000,00</td>
   Bu öznitelik DataTable bileşeni tarafından otomatik yazılır; sayfa
   elle yazmaz (yazarsa kolon değişince unutulur).

   .os-table--scroll ile bu davranış kapatılabilir — yalnız gerçekten
   ızgara olarak okunması gereken tablolarda (PermissionMatrix gibi,
   satır × kolon kesişimi anlam taşıyanlar). */
@media (max-width: 639px) {
  /* Izgara tabloları: kaydırma kalır ama ipucu verilir. */
  .os-table--scroll { min-width: 560px; }
}
/* os-table-fit.js OLCUM durumu (ayni karede eklenip kaldirilir, hic cizilmez): masaustunde tek satira
   kilitli (nowrap + …) hucreler sarabiliyormus gibi sayilir — kisaltilabilen metin tablonun "sigmadigi"
   anlamina gelmez; en uzun KELIME sigmiyorsa gelir. */
/* 2026-10-26: "en uzun KELIME" niyeti kodda yoktu — overflow-wrap:anywhere kelimeyi HARF HARF bölünebilir sayıyordu;
   en dar genişlik tek harfe iniyor, hiçbir tablo "sığmıyor" görünmüyor, kolonlar "İSTA…", "7310…", "ŞİRKE T SAHİB İ"
   diye eziliyordu. Artık yalnız kelime aralarından kırılır; kod/tarih (os-mono, os-idcell), tutar (os-cell--num) ve rozet hiç kırılmaz. */
.os-table--olcum th, .os-table--olcum td, .os-table--olcum th *, .os-table--olcum td * { white-space: normal !important; overflow-wrap: normal !important; word-break: normal !important; }
.os-table--olcum .os-mono, .os-table--olcum .os-mono *, .os-table--olcum .os-idcell, .os-table--olcum .os-idcell *,
.os-table--olcum td.os-cell--num, .os-table--olcum td.os-cell--num *,
.os-table--olcum .os-badge, .os-table--olcum .os-badge *, .os-table--olcum .os-tag { white-space: nowrap !important; }
/* os-cell--clip: bilerek kısaltılan serbest metin (uzun açıklama, JSON/liste değeri — tam metin title'da). Boşluksuz uzun
   dizgi tablonun en dar genişliğini şişirip tabloyu her genişlikte karta çevirmesin diye ölçümde her yerden kırılabilir sayılır;
   js/os-table-fit.js bu hücrenin "…"sunu kesik saymaz. Kartta tam metin sarar. */
.os-table--olcum td.os-cell--clip, .os-table--olcum td.os-cell--clip * { white-space: normal !important; overflow-wrap: anywhere !important; }
.os-table.os-table--stacked td.os-cell--clip, .os-table.os-table--stacked td.os-cell--clip * { white-space: normal; overflow-wrap: anywhere; overflow: visible; text-overflow: clip; }
/* SARAN TABLO: os-table-fit.js tablo tek satır hâlinde kabına sığmazsa KARTA dönmeden önce bunu dener.
   Başlıklar ve metin hücreleri kelime aralarından alt satıra iner; tutar hücresi (os-cell--num) ve
   rozet/çipler bölünmez. Sığarsa tablo kalır (geniş ekranda kart çıkmasının asıl sebebi tek satıra
   kilitli başlıklardı — senet detayındaki sayfa içi çözümün ortak hâli, 2026-10-15). */
/* İç öğeler de kapsanır (2026-10-26): talep no os-mono içindeki <a>, rozetin metin sarmalı (.sp-txt) bölünüyordu. */
.os-table--sar th, .os-table--sar td,
.os-table--sar th *, .os-table--sar td *:not(.os-badge):not(.os-chip):not(.os-tag):not(.os-mono):not(.os-badge *):not(.os-chip *):not(.os-tag *):not(.os-mono *) { white-space: normal; overflow-wrap: break-word; }
/* Kartsiz sayfada sigmayan tablonun kabi (js/os-table-fit.js, 2026-11-05): tablo kendi kabinda kayar, sayfa kaymaz. */
.os-table-kaykap { overflow-x: auto; min-width: 0; max-width: 100%; }
/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
.os-tablewrap:has(> .os-table--stacked) {
    border: 0; border-radius: 0; background: transparent; overflow-x: visible;
  }
.os-table.os-table--stacked { display: block; font-size: var(--text-md); }
.os-table.os-table--stacked thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
/* Kartlar izgarada: dar kapta tek sutun, genis kapta (tablet / dar masaustu) yan yana — tam genislik
   tek kart 900px'lik alanda bosa yer kaplardi. */
.os-table.os-table--stacked tbody {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: var(--gap-inner); align-items: start;
}
/* Kart icinde alanlar yer varsa yan yana akar (genis kartta tek sutun dizi gereksiz uzundu);
   kaydin basligi, eylemler ve tek hucreli satir (bos durum) tam satir kaplar. */
.os-table.os-table--stacked tbody tr {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr));
    column-gap: var(--space-4); align-items: start;
    /* Secim kutusunun 44px dokunma hedefi kart kenarindan sarkip kabi kaydirilabilir yapiyordu (kullanici
       yonetimi 600px: 9px). clip: kaydirma kabi olusturmaz, gorunur icerigi kesmez. */
    overflow-x: clip;
    background: var(--surface-card);
    border: 1px solid var(--border-default); border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
  }
.os-table.os-table--stacked tbody td.os-cell--title,
.os-table.os-table--stacked tbody td.os-cell--actions,
.os-table.os-table--stacked tbody td[colspan] { grid-column: 1 / -1; }
/* os-cell--full: kartta tam satır (uzun kimlik/anahtar dar ızgara sütununda bölünmesin); tablo görünümünde etkisiz. */
.os-table.os-table--stacked tbody td.os-cell--full { grid-column: 1 / -1; }
/* Tek hucreli satir (bos durum / yukleniyor / hata) kart IZGARASINDA da tam satir: aksi halde tbody'nin
   320px'lik ilk izgara hucresine sikisip dar bir kart gibi duruyordu (senet detayi 13 sutun, 2026-10-07). */
.os-table.os-table--stacked tbody tr:has(> td[colspan]:only-child) { grid-column: 1 / -1; }
/* Masaustunde tek satira kilitli (nowrap + …) ic ogeler kartta satir kirar — kart kenarindan tasmasin. */
.os-table.os-table--stacked tbody td * { white-space: normal; max-width: 100%; }
/* Kartta boşluksuz uzun değer (şablon anahtarı, URL, e-posta) hücreden TAŞMAZ, gerekirse bölünür: break-word ızgara
   hücresinin en dar genişliğini küçültmüyordu, "INSTALLMENT_REMINDER_UPCOMING_SMS" yan kolona biniyordu (2026-10-26). */
.os-table.os-table--stacked tbody td, .os-table.os-table--stacked tbody td * { overflow-wrap: anywhere; }
/* os-page ortalanirken (margin-inline:auto) icerige gore daralir; tablo modunda genis tablo onu tam
   genislige itiyordu, kartlar itmiyor -> kap 587px'e buzuluyordu. Yalniz kart icerirken tam genislik:
   masaustu gorunumu degismez. */
.os-page:has(.os-table--stacked) { width: 100%; }
.os-table.os-table--stacked tbody tr:hover { background: var(--surface-card); }
/* Etiket ÜSTTE, değer ALTTA. Yan yana dizmek kısa değerlerde iyi
     görünüyor ama uzun metinde etiket flex:none olduğu için değere
     neredeyse hiç genişlik kalmıyor ve metin dikey harf dizisine
     dönüşüyordu. Dikey dizilim her uzunlukta okunur. */
  
.os-table.os-table--stacked tbody td {
    display: grid; grid-template-columns: minmax(0, 1fr);
    gap: 1px; padding: var(--space-1) 0; border: 0;
    text-align: left; white-space: normal; min-width: 0;
    /* Tablo gorunumu icin sayfanin verdigi sabit sutun genisligi (orn. firma adi 240px) kartta
       gecersiz: hucre kartin izgara izine uyar, kenardan tasmaz (olcum 2026-09-30, bayi listesi 69px). */
    width: auto; max-width: 100%;
    /* Rozet/çip/düğme kendi genişliğinde kalır; sütun boyu esneyip "• Reddedildi" şeridine dönmez
       (kartın karışık görünmesinin bir sebebi buydu, 2026-10-15). */
    justify-items: start;
  }
/* Boş değer: etiket yalnız kalmasın, tabloda olduğu gibi tire görünsün. */
.os-table.os-table--stacked tbody td[data-label]:empty::after { content: '—'; color: var(--text-muted); }
/* Etiket hücrenin İÇİNDE üretilir — ayrı bir DOM öğesi yok, böylece
     masaüstü görünümü hiç etkilenmez. */
  
.os-table.os-table--stacked tbody td[data-label]::before {
    content: attr(data-label);
    font-size: var(--text-xs); font-weight: var(--weight-semibold);
    letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted);
  }
/* Sayısal hücre kartta da sağda durur — ama artık etiketiyle aynı
     satırda, yani karşılaştırma değil OKUMA düzeni. */
  
.os-table.os-table--stacked tbody td.os-cell--num,
  .os-table.os-table--stacked tbody td.os-cell--num > * { text-align: left; }
/* Kart başlığı — kaydı TANIMLAYAN hücre. Konumla değil AÇIK SINIFLA
     belirlenir: :first-child kullanmak seçim onay kutusunu başlık yapar
     ve kaydın kimliği (senet no) sıradan bir satıra düşer.
     DataTable bu sınıfı ilk ETİKETLİ kolona otomatik yazar. */
  
.os-table.os-table--stacked tbody td.os-cell--title::before { display: none; }
.os-table.os-table--stacked tbody td.os-cell--title {
    /* Kart başlığı gövdeden TİPOGRAFİK olarak da ayrışır. Daha önce
       var(--text-base) yazılıydı ve o token TANIMSIZ olduğu için değer
       miras alınıyordu: başlık ile değer hücreleri aynı 14px'e düşüyor,
       ayrım yalnız font-weight ve alt çizgiye kalıyordu. */
    font-weight: var(--weight-semibold); font-size: var(--text-lg);
    padding-bottom: var(--space-2); margin-bottom: var(--space-1);
    border-bottom: 1px solid var(--border-default);
  }
/* Seçim hücresi: kartta başlığın SAĞINDA durur, etiketi yoktur.
     Kart başlığı ile aynı satırı paylaşır — ayrı bir satır israf olur. */
  
.os-table.os-table--stacked tbody tr:has(td.os-cell--select) { position: relative; }
.os-table.os-table--stacked tbody td.os-cell--select {
    position: absolute; top: var(--space-3); right: var(--space-4);
    padding: 0; margin: 0; border: 0; width: auto;
  }
.os-table.os-table--stacked tbody td.os-cell--select::before { display: none; }
/* Seçim kutusunun 44px'lik hedefi başlık metnine taşmasın: hücre
     absolute olduğu için yer başlıkta ELLE ayrılır (44 hedef + 8 nefes). */
  
.os-table.os-table--stacked tbody tr:has(td.os-cell--select) td.os-cell--title { padding-right: var(--space-12); }
/* Satır aksiyonları kartın altında, tam genişlikte ve 44px hedefte. */
  /* İşlem hücresi: etiketi gizlenir, butonlar yatay dizilir. */
  
.os-table.os-table--stacked tbody td.os-cell--actions {
    padding-top: var(--space-2); margin-top: var(--space-1);
    border-top: 1px solid var(--border-default);
    justify-items: end;
  }
.os-table.os-table--stacked tbody td.os-cell--actions::before { display: none; }
.os-table.os-table--stacked tfoot { display: block; margin-top: var(--gap-inner); }
.os-table.os-table--stacked tfoot tr { display: flex; justify-content: space-between; gap: var(--space-4); padding: var(--space-3) var(--space-4); background: var(--surface-sunken); border-radius: var(--radius-lg); }


/* ── Key-value description list ─────────────────────────── */
/* BASLIK USTTE, ICERIK ALTTA — her ekran boyunda (kullanici kurali 2026-10-08: "bilgiler yan yana
   yapmak yerine eskisi gibi alt alta olmalidir ... baslik-icerik"). Eskiden etiket sol kolonda,
   deger sag kolondaydi; yalniz <=420px'te alt alta idi. Alanlari yan yana dizmek isteyen yer
   KAPSAYICI izgarayla yapar (orn. talep merkezi: her alan ayri .os-infocell.os-kv hucresi).
   min-width:0 + overflow-wrap:anywhere: kirilamayan degerler (sasi no, IBAN) karti tasirmaz. */
.os-kv {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-1); margin: 0;
}
/* .os-kv__label: ayni baslik, <dl> kurulamayan hucrede (degerin yaninda dugme/radyo tasiyan
   div tabanli .os-infocell) — gorunum tek tanimda kalsin diye dt ile paylasilir. */
.os-kv dt, .os-kv__label {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em;
  min-width: 0; overflow-wrap: anywhere;
}
.os-kv dd {
  margin: 0; font-size: var(--text-sm); font-weight: var(--weight-medium);
  min-width: 0; overflow-wrap: anywhere;
}
/* Ayni listedeki bir sonraki cift: onceki degerden ayrilsin. */
.os-kv dd + dt { margin-top: var(--space-2); }
/* --inline: ETIKET SOLDA, DEGER SAGDA (kullanici istegi 2026-10-12: tahsilat detay ekranlarinda
   "Talep No" ve degerinin alt alta durmasi kotu). Genel kural (alt alta) DEGISMEZ; yalniz bu varyanti
   tasiyan listeler yan yana dizilir (bills/detail, installments/detail). Etiket kolonu dar ekranda
   kisalir; <=420px'te yine alt alta. */
.os-kv--inline {
  grid-template-columns: minmax(96px, 38%) minmax(0, 1fr);
  column-gap: var(--space-3); align-items: baseline;
}
.os-kv--inline dt { text-transform: none; letter-spacing: 0; font-size: var(--text-sm); color: var(--text-muted); }
.os-kv--inline dd + dt { margin-top: 0; }
.os-kv--inline > dt, .os-kv--inline > dd { padding-block: 2px; }
@media (max-width: 420px) {
  .os-kv--inline { grid-template-columns: minmax(0, 1fr); }
  .os-kv--inline dt { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); }
}
/* ── Signal (detay başlığı vurgu çipi) ───────────────────
   Mini-stat: etiket gri kalır, yalnız DEĞER tona boyanır; zemin soluk
   durum rengi. Dikkat çeker ama badge kadar bağırmaz — detay başlığında
   3–5 taneye kadar yan yana kullanılır. */
.os-signals { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.os-signal {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 1px;
  min-height: 44px; padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-sunken); border: 1px solid var(--border-default);
}
.os-signal__label {
  font-size: var(--text-2xs); font-weight: var(--weight-medium);
  color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em;
  white-space: nowrap;
}
.os-signal__value {
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
  color: var(--text-primary); font-feature-settings: var(--numeric-features);
  white-space: nowrap;
}
.os-signal--danger  { background: var(--status-danger-bg);  border-color: var(--red-100); }
.os-signal--danger .os-signal__value  { color: var(--status-danger-fg); }
.os-signal--warning { background: var(--status-warning-bg); border-color: var(--yellow-100); }
.os-signal--warning .os-signal__value { color: var(--status-warning-fg); }
.os-signal--success { background: var(--status-success-bg); border-color: var(--green-100); }
.os-signal--success .os-signal__value { color: var(--status-success-fg); }
.os-signal--info    { background: var(--status-info-bg);    border-color: var(--cyan-100); }
.os-signal--info .os-signal__value    { color: var(--status-info-fg); }

/* ── Avatar (kullanıcı baş harfleri) ────────────────────── */
.os-avatar {
  display: inline-grid; place-items: center; flex: none; user-select: none;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--blue-100); color: var(--blue-600);
  font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: 0.02em;
}
.os-avatar--sm { width: 24px; height: 24px; font-size: 10px; }
.os-avatar--lg { width: 40px; height: 40px; font-size: var(--text-md); }
.os-avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }

/* ── Progress (payment plan completion) ─────────────────── */
.os-progress { height: 6px; border-radius: var(--radius-pill); background: var(--gray-100); overflow: hidden; }
.os-progress__bar { height: 100%; border-radius: var(--radius-pill); background: var(--status-success-solid); transition: width var(--duration-normal) var(--ease-standard); }
.os-progress__bar--warning { background: var(--status-warning-solid); }
.os-progress__bar--danger { background: var(--status-danger-solid); }


/* ══ Tıklanabilir satır ═══════════════════════════════════════════════
   Kayda girmek için "göz" ikonuna basmak gerekmez — SATIRIN KENDİSİ
   tıklanır. Göz ikonu satır başına fazladan bir hedef, fazladan bir
   kolon ve fazladan bir öğrenme demekti; kullanıcı zaten satıra
   tıklamayı deniyor. Kaldırıldı.
   Erişilebilirlik: satır tıklaması tek başına yeterli değil — birincil
   hücre gerçek bir <a> taşır, böylece klavye ve ekran okuyucu da girer.
   Satırdaki diğer etkileşimli öğeler (onay kutusu, kopyala, kebap)
   olayı yutar; yanlışlıkla kayda girilmez. */
.os-table tbody tr.os-row--link { cursor: pointer; }
.os-table tbody tr.os-row--link:hover { background: var(--surface-selected); }
.os-table tbody tr.os-row--link:focus-within { box-shadow: inset 0 0 0 2px var(--border-focus); }

/* Kimlik hücresi — İKİ eylem, iki hedef.
   Kullanıcı iki şey istedi ve ikisi de doğru: "direkt tıklayınca girebilsin"
   ve "senet no'ya tıklayınca kopyalasın". Tek öğede toplanamazlar; ayrılır:
     METİN  = <a>  → kayda girer (klavye ve ekran okuyucunun kanonik yolu)
     İKON   = <button> → panoya biçimsiz değeri kopyalar
   Metni kopyala butonu yapmak satırdaki tek klavye yolunu siler; satır
   tıklaması yalnız FARE kolaylığıdır, erişilebilirliği o taşımaz. */
.os-idcell { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
/* Kod ASLA sarmaz: "SNT-2026-04821" üç satıra bölündüğünde okunmaz olur ve
   satır yüksekliğini üçe katlar. Kolon dar kalırsa kırpılır (title'da tam
   değer), sarmaz — kimlik dizgisi bir cümle değildir. */
.os-idcell a { white-space: nowrap; }
/* Kod ve TARİH hücreleri sarmaz. Önce yalnız .os-idcell kapsanmıştı;
   "15.07.2026" 0,5px açıkta kalınca "15.07.202" / "6" diye ikiye bölünüyordu.
   Tarih de bir kimlik dizgisidir — cümle değil. */
.os-table--minw td.os-mono, .os-table--minw td .os-mono { white-space: nowrap; }

/* Yoğun tablo taban genişliği: kolonlar içeriğinden dar kalmaz.
   table-layout:fixed yüzdeleri ORANI belirler, min-width ise TABANI —
   pano dar olduğunda sarmalayıcı yatay kayar, kolonlar ezilmez.
   <640px'te kart yerleşimi devralır ve taban sıfırlanır: mobilde
   kullanıcı aşağı kaydırır, yana değil. */
/* 2026-09-30: sabit 860px taban KALDIRILDI. Taban "pano darsa sarmalayici yatay kayar" icin vardi;
   kullanici kurali tablonun hic yana kaymamasi. Sigmayan tablo artik karta doner (js/os-table-fit.js,
   olcut: kaba sigmama / en dar dogal genislik (min-content) / baslik tasmasi). Sinif nowrap kurallari icin kalir. */
.os-table--stickyact thead th:last-child,
.os-table--stickyact tbody td:last-child,
.os-table--stickyact tfoot td:last-child {
  position: sticky; right: 0; z-index: 2;
  background: var(--surface-card);
  box-shadow: -1px 0 0 var(--border-default);
}
.os-table--stickyact thead th:last-child { z-index: 3; background: var(--gray-50); }
.os-table--stickyact tfoot td:last-child { background: var(--gray-50); }
.os-table--stickyact tbody tr:hover td:last-child { background: var(--surface-selected); }
.os-table--stickyact tbody tr.os-row--selected td:last-child { background: var(--surface-selected); }
/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
/* Kart yerleşiminde sabitleme anlamsız: satır zaten tek kolon */
  
.os-table--stickyact.os-table--stacked thead th:last-child,
  .os-table--stickyact.os-table--stacked tbody td:last-child,
  .os-table--stickyact.os-table--stacked tfoot td:last-child {
    position: static; box-shadow: none; background: transparent;
  }

/* Yapiskan ILK kolon (stickyact'in aynasi): yatay kayan izgaralarda (.os-table--scroll — yetki matrisi) satir
   basligi yerinde kalir. Kose basligi diger basliklarin ustunde (z 3), govde hucreleri opak; satir tonu veren
   os-row--group / os-row--child kendi td zeminini zaten verir (daha ozgul), hover yalniz duz satirda burada. */
.os-table--stickyfirst thead th:first-child,
.os-table--stickyfirst tbody td:first-child,
.os-table--stickyfirst tfoot td:first-child {
  position: sticky; left: 0; z-index: 2;
  background: var(--surface-card);
  box-shadow: 1px 0 0 var(--border-default);
}
.os-table--stickyfirst thead th:first-child { z-index: 3; background: var(--gray-50); }
.os-table--stickyfirst tfoot td:first-child { background: var(--gray-50); }
.os-table--stickyfirst tbody tr:not(.os-row--group):not(.os-row--child):hover td:first-child { background: var(--gray-25); }
.os-table--stickyfirst tbody tr.os-row--selected td:first-child { background: var(--surface-selected); }
.os-table--stickyfirst.os-table--stacked thead th:first-child,
  .os-table--stickyfirst.os-table--stacked tbody td:first-child,
  .os-table--stickyfirst.os-table--stacked tfoot td:first-child {
    position: static; box-shadow: none; background: transparent;
  }

/* Dikey sutun basligi: cok sutunlu izgarada (yetki matrisi: rol x evrak) sutun genisligini uzun baslik degil
   hucre belirler -> 13 rol sutunu masaustune yana kaymadan sigar. Metin asagidan yukari okunur; uzun ad yan yana
   ikinci-ucuncu dikey satira kirilir (sutun biraz genisler, metin kesilmez). */
.os-table th.os-cell--vhead { vertical-align: bottom; text-align: center; padding-left: var(--space-1); padding-right: var(--space-1); }
.os-cell--vhead > .os-vhead {
  display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg);
  white-space: normal; max-height: 9.5rem; text-align: left;
}
.os-table--stacked th.os-cell--vhead > .os-vhead { writing-mode: horizontal-tb; transform: none; max-height: none; }

/* Satir eylem kabi (R-29: eylemler arasi 8px, saga yasli, tek satir) — sayfalardaki "d-flex gap-1 justify-content-end" kopyasinin DS karsiligi */
.os-cell__actions { display: inline-flex; align-items: center; justify-content: flex-end; gap: var(--space-2); flex-wrap: nowrap; }

/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
.os-table--minw.os-table--stacked { min-width: 0; }


.os-copy {
  display: inline-flex; align-items: center; gap: 6px;
  border: 0; background: transparent; padding: 2px 4px; margin: -2px -4px;
  border-radius: var(--radius-sm); cursor: copy;
  font: inherit; color: inherit;
}
.os-copy:hover { background: var(--surface-sunken); }
.os-copy:focus-visible { box-shadow: var(--focus-ring); }
/* İkon DURAĞAN hâlde de görünür (.45) — buton yalnız ikondan ibaret;
   opacity:0 vermek onu keşfedilemez kılar, kullanıcı 21px'lik boş alanın
   üzerine gelmeyi tahmin edemez. Vurgu HÜCRE hover'ında gelir, butonun
   kendi hover'ında değil: hedefi görünmeyen bir butonun üzerine gelinmesi
   beklenemez. */
.os-copy__icon { width: 13px; height: 13px; flex: none; opacity: .45; transition: opacity var(--duration-fast) var(--ease-standard); color: var(--text-muted); }
.os-idcell:hover .os-copy__icon, .os-copy:hover .os-copy__icon, .os-copy:focus-visible .os-copy__icon { opacity: 1; color: var(--text-brand); }
@media (hover: none) { .os-copy__icon { opacity: 1; } }

/* ══ Belge satırı (portal .doc-item · document-upload.html:45) ═══════
   Sol kenarda 4px DURUM AKSANI — rozetin tekrarı değil, tarama kanalı:
   kullanıcı 12 satırlık listede "hangisi eksik" diye göz gezdiriyor,
   aksan çubukları o taramayı rozet metnini okumadan yapmasını sağlar. */
.os-doc {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 14px; background: var(--gray-25);
  border: 1px solid var(--border-default); border-left: 4px solid var(--border-strong);
  border-radius: var(--radius-md);
}
.os-doc--approved { border-left-color: var(--status-success-solid); background: var(--status-success-bg); }
.os-doc--pending  { border-left-color: var(--status-warning-solid); }
.os-doc--rejected { border-left-color: var(--status-danger-solid);  background: var(--status-danger-bg); }
.os-doc--error    { border-left-color: var(--status-danger-solid);  background: var(--status-danger-bg); }
/* Bilgi aksanı — kümedeki öne çıkan satır (ör. talep merkezi "Birleştirilmiş Talepler"de ana talep). */
.os-doc--info     { border-left-color: var(--status-info-solid);    background: var(--status-info-bg); }
.os-doc__icon { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--text-secondary); }
.os-doc__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }
/* Dosya adı TIKLANABİLİR: önizlenebilir tipte belgeyi açar, aksi hâlde
   indirir. Bağlantı olması şart — klavye ve ekran okuyucu için tek yol. */
.os-doc__name {
  font-size: 13px; font-weight: 500; color: var(--text-brand);
  text-align: left; background: 0; border: 0; padding: 0; font-family: inherit;
  cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.os-doc__name:hover { text-decoration: underline; }
.os-doc__name:focus-visible { box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
/* Meta: uzantı · boyut · tarih — adın ALTINDA, sola dayalı, tek satır. */
.os-doc__meta { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.os-doc__side { display: flex; align-items: center; gap: 8px; flex: none; }
/* Önizlemesi olmayan ad (üretilecek belge şablonu gibi): <span> olarak çağrılır,
   bağlantı rengi ve imleç almaz. Sayfa inline renk vermesin diye pakette. */
.os-doc__name:not(button):not(a) { color: var(--text-primary); font-weight: 600; cursor: default; }
.os-doc__name:not(button):not(a):hover { text-decoration: none; }
/* Bootstrap Icons <i> ile çağrıldığında boyut font-size'dan gelir (SVG'deki width/height değil). */
.os-doc__icon[class*="bi-"] { width: auto; height: auto; font-size: 17px; line-height: 1; }
/* Ad altındaki ek satırlar (red gerekçesi, e-Devlet sonucu): meta ile aynı ölçek, satır sarar. */
.os-doc__note { font-size: 11px; color: var(--text-muted); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Belge listesi: dikey yığın; --grid çok sütunlu (Belge Çıktıları). */
.os-doclist { display: flex; flex-direction: column; gap: 8px; }
.os-doclist--grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 10px; }
.os-doclist--grid > .os-doc { align-items: center; }
/* Belge grubu başlığı (Kimlik / Adres / Araç / Gelir ...): listeyi gruplar; kart açmadan ayırır. */
.os-doclist__title {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--text-primary);
  padding-bottom: var(--space-2); margin: 0 0 var(--space-3); border-bottom: 1px solid var(--border-default);
}
.os-doclist__title > .bi { color: var(--text-brand); }
@media (max-width: 639px) {
  .os-doc { flex-wrap: wrap; }
  .os-doc__side { width: 100%; justify-content: flex-end; padding-left: 29px; }
}

/* PermissionMatrix: rol × kaynak ızgarası dar panoda taşmaz — kaynak adı
   kolonu sabit 140px taban yerine oransal daralır. Onay kutuları zaten
   sabit genişlikte, esneyecek tek kolon metin kolonudur. */
.os-permgrid { table-layout: fixed; width: 100%; }
.os-permgrid th:first-child, .os-permgrid td:first-child { min-width: 0; width: 28%; }
.os-permgrid th:not(:first-child), .os-permgrid td:not(:first-child) { width: 18%; }
/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
.os-permgrid.os-table--stacked th,
  .os-permgrid.os-table--stacked td { width: auto; }


/* ── Signal ve Kpi: durum tonları ─────────────────────────────────────
   Signal'de dört ton vardı (danger · warning · success · info) ama
   "iade / ara adım" yoktu ve Kpi'da hiç ton yoktu — oysa ikisi de
   durum taşıyan gösterimler: "gecikmiş tutar" nötr olamaz.
   Ton yalnız SOL AKSAN ve DEĞER rengine uygulanır; etiket nötr kalır
   (R-24: etiket her zemin üzerinde 4.5:1 olmak zorunda). */
.os-signal--returned { border-left-color: var(--status-returned-solid); }
.os-signal--returned .os-signal__value { color: var(--status-returned-fg); }

.os-kpi--success  { border-left: 3px solid var(--status-success-solid); }
.os-kpi--warning  { border-left: 3px solid var(--status-warning-solid); }
.os-kpi--danger   { border-left: 3px solid var(--status-danger-solid); }
.os-kpi--returned { border-left: 3px solid var(--status-returned-solid); }
.os-kpi--info     { border-left: 3px solid var(--status-info-solid); }
.os-kpi--success  .os-kpi__value { color: var(--status-success-fg); }
.os-kpi--warning  .os-kpi__value { color: var(--status-warning-fg); }
.os-kpi--danger   .os-kpi__value { color: var(--status-danger-fg); }
.os-kpi--returned .os-kpi__value { color: var(--status-returned-fg); }
.os-kpi--info     .os-kpi__value { color: var(--status-info-fg); }

/* ══ Portal geri bildirimi düzeltmeleri (18.09.2026) ═══════════════ */

/* Geniş içerik — 12+ kolonlu operasyon listeleri */
.os-content--wide { max-width: var(--content-max-wide); }

/* Seçilebilir çip (toggle) — .os-tag'den AYRI bir iş.
   os-tag kaldırılabilir bir etikettir (× ile silinir); bu ise aç/kapa
   bir FİLTRE DÜĞMESİ. Seçili durum bir durum, kaldırma bir eylem —
   ikisini tek bileşene yüklemek os-tag__x'in anlamını bulanıklaştırır.
   Durum aria-pressed'den okunur: görünüm ile erişilebilirlik tek
   kaynaktan gelir, sınıf ve öznitelik ayrışamaz. */
.os-tag--toggle {
  min-height: var(--control-h-sm); padding: 3px var(--space-3); text-align: center;   /* uzun etiket sarar, taşmaz (bkz. .os-tag) */
  border-radius: 999px; cursor: pointer;
  background: var(--surface-card); color: var(--text-secondary);
  border: 1px solid var(--border-strong);
  font-size: var(--text-sm); font-weight: 500;
  transition: background var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.os-tag--toggle:hover { background: var(--surface-sunken); border-color: var(--text-muted); }
.os-tag--toggle[aria-pressed="true"] {
  background: var(--interactive-primary); border-color: var(--interactive-primary);
  color: var(--text-inverse);
}
.os-tag--toggle[aria-pressed="true"]:hover { background: var(--interactive-primary-hover); border-color: var(--interactive-primary-hover); }
.os-tag--toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); }
/* Sayaç taşıyan çip: "Gecikmiş 96" — sayı seçim öncesi de görünür */
.os-tag__count { margin-left: var(--space-2); opacity: .75; font-variant-numeric: tabular-nums;
  /* Sayi degisince cip boyu oynamasin (musteri listesi, 2026-10-15): 4 haneye kadar sabit yer, sayi sagda. */
  display: inline-block; min-width: 4ch; text-align: right; }

/* Kaydırılabilir tablo — kap ZORUNLU.
   .os-table--scroll min-width veriyor; kaydırma kabı olmadan bu değer
   SAYFAYI taşırır (ölçüm: search-analytics 216px). Kap artık asgari
   genişliği kendisi kurar, tablo yalnız doldurur. */
.os-tablewrap { overflow-x: auto; min-width: 0; }
.os-table--scroll { min-width: var(--table-scroll-min, 560px); }
/* Grid/flex içinde kap büzülmüyordu: min-width:0 olmadan grid öğesi
   içeriğinin asgari genişliğinde kalır ve satırı taşırır. */
.os-tablewrap, .os-scrollx { min-width: 0; }
/* Dar kartlarda 560px fazla — token'la daraltılır, kural değişmez */
.os-tablewrap--narrow { --table-scroll-min: 480px; }
/* Long content must not widen the shell or narrow card headings. */
.os-card { min-width:0; }
.os-card__header > * { min-width:0; }
@media(max-width:639px) {
 .os-card__header { flex-wrap:wrap; }
 .os-card__header > .os-badge { max-width:100%; white-space:normal; height:auto; }
}
/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
.os-table.os-table--stacked > caption { display:block; width:100%; }


/* Mobile card tables retain readable totals without an extra native table grid. */
/* Kart gorunumu: .os-table--stacked (js/os-table-fit.js tablo kabina sigmayinca ve <640px'te koyar). */
.os-table.os-table--stacked tfoot { display:block; width:100%; }
.os-table.os-table--stacked tfoot tr { display:flex; flex-wrap:wrap; gap:var(--space-2); }
.os-table.os-table--stacked tfoot td { display:block; max-width:100%; flex:1 1 auto; }
.os-table.os-table--stacked tfoot td:empty { display:none; }
.os-table.os-table--stacked tfoot td[data-label]:not([data-label=""])::before { content:attr(data-label); display:block; font-size:var(--text-xs); color:var(--text-muted); }



/* ── Hesap dökümü (os-ledger) — kalem satırları, açılır gruplar, satır içi düzeltme, toplam ──
   İlk kullanan: js/early-closing-panel.js (Spec 045 erken kapama paneli; bills/detail + closing/early-return).
   Grup alt satırları [hidden] ile açılır/kapanır (JS aria-expanded'i senkron tutar). Negatif tutar
   (indirim/düzeltme) başarı tonunda. Renk yalnız semantik token. */
.os-ledger {
  min-width: 0; padding: var(--space-2) var(--space-4) var(--space-3);
  background: var(--surface-sunken); border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  transition: opacity var(--duration-fast) var(--ease-standard);
}
.os-ledger--busy { opacity: .6; }
.os-ledger__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap;
  min-height: 38px; padding: var(--space-1) 0; border-bottom: 1px solid var(--border-default);
}
.os-ledger__label {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow-wrap: anywhere;
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
}
.os-ledger__amount {
  font-variant-numeric: tabular-nums lining-nums; font-feature-settings: var(--numeric-features); font-weight: var(--weight-semibold);
  color: var(--text-primary); white-space: nowrap; text-align: right;
}
.os-ledger__row > .os-ledger__amount, .os-ledger__subrow > .os-ledger__amount { margin-left: auto; }   /* sarınca da sağda */
.os-ledger__amount--neg { color: var(--status-success-fg); }
.os-ledger__cur { margin-left: var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-muted); }
.os-ledger__side { display: inline-flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; margin-left: auto; min-width: 0; }
.os-ledger__toggle {
  position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 30px; min-width: 0; padding: 0;
  border: 0; background: none; border-radius: var(--radius-sm); cursor: pointer; text-align: left;
  font: inherit; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
}
.os-ledger__toggle::before { content: ""; position: absolute; inset: -7px -4px; }   /* dokunma hedefi ≥44px */
.os-ledger__toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.os-ledger__chev { font-size: 12px; color: var(--text-muted); transition: transform var(--duration-fast) var(--ease-standard); }
.os-ledger [aria-expanded="true"] > .os-ledger__chev { transform: rotate(90deg); color: var(--text-brand); }
.os-ledger__count { font-size: var(--text-2xs); font-weight: var(--weight-medium); color: var(--text-muted); white-space: nowrap; }
.os-ledger__sub { padding: 0 0 var(--space-2) var(--space-6); border-bottom: 1px solid var(--border-default); }
.os-ledger__subrow {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap;
  padding: 6px 0; font-size: var(--text-sm); color: var(--text-secondary);
}
.os-ledger__subrow > :first-child { min-width: 0; overflow-wrap: anywhere; }
.os-ledger__subrow .os-ledger__amount { font-weight: var(--weight-medium); }
.os-ledger__edit { display: inline-flex; align-items: center; gap: var(--space-1); }
.os-ledger__edit > .os-input { width: 128px; }
.os-ledger__reason { flex-basis: 100%; width: 100%; max-width: 460px; margin: 6px 0 4px auto; }
.os-ledger__total {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-1); padding: 14px 0 6px; border-top: 2px solid var(--border-strong);
}
.os-ledger__total .os-ledger__label { font-size: var(--text-xs); font-weight: var(--weight-bold); letter-spacing: .08em; text-transform: uppercase; }
.os-ledger__total .os-ledger__amount { font-size: var(--text-xl); font-weight: var(--weight-bold); }
.os-ledger__detail { margin-top: var(--space-2); }
.os-ledger__strong { font-size: var(--text-md); font-weight: var(--weight-bold); }
.os-ledger__list { margin: var(--space-1) 0 0; padding-left: 18px; }
.os-ledger__list > li { margin: 3px 0; overflow-wrap: anywhere; }
/* Döküm/yazdırma tablosu satır tonları (os-table içinde) */
.os-table tbody tr.os-ledger__row--muted td { color: var(--text-muted); }
.os-table tbody tr.os-ledger__row--total td { font-weight: var(--weight-bold); background: var(--surface-sunken); }
@media (prefers-reduced-motion: reduce) { .os-ledger, .os-ledger__chev { transition: none; } }
@media (max-width: 600px) {
  .os-ledger { padding: 6px var(--space-3) 10px; }
  .os-ledger__edit > .os-input { width: 112px; }
  .os-ledger__sub { padding-left: var(--space-4); }
}

/* ── os-kv çok satırlı serbest metin değeri (dekont açıklaması, yorum, gerekçe): satır sonları korunur ── */
.os-kv > dd.os-kv__multiline { white-space: pre-wrap; font-weight: var(--weight-regular); }

/* ── Yazdırma belgesi (os-printdoc) — önizleme penceresinde sade belge; yazdırırken yalnız o basılır ──
   Kullanım: önizleme os-dialog içinde .os-printdoc; yazdırma anında body'ye .os-printhost eklenir ve
   body'ye .os-printing konur (js/early-closing-panel.js). */
.os-printdoc {
  display: flex; flex-direction: column; gap: var(--space-4); min-width: 0;
  padding: 28px 30px; background: var(--surface-card); color: var(--text-primary);
  border: 1px solid var(--border-default); border-radius: var(--radius-md);
}
.os-printdoc__head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap;
  padding-bottom: var(--space-3); border-bottom: 2px solid var(--border-strong);
}
.os-printdoc__title { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold); letter-spacing: -.01em; }
.os-printdoc__sign {
  display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: var(--space-8);
  font-size: var(--text-xs); color: var(--text-secondary); text-align: center;
}
.os-printdoc__sign > div { padding-top: 6px; border-top: 1px solid var(--border-strong); }
.os-printhost { display: none; }
@media (max-width: 600px) { .os-printdoc { padding: 18px 16px; } }
@media print {
  body.os-printing > *:not(.os-printhost) { display: none !important; }
  body.os-printing .os-printhost { display: block !important; }
  body.os-printing .os-printhost .os-printdoc { border: none; padding: 0; }
}


/* ── Ilerleme cubugu: iade/ara durum tonu (ana sayfa kirilimi — iade asamasi, iade sebepleri) ── */
.os-progress__bar--returned { background: var(--status-returned-solid); }
/* ── KPI: baglanti hucresi (<a class="os-kpi"> — listeye goturen gosterge) ── */
a.os-kpi { color: inherit; text-decoration: none; }
a.os-kpi:hover { background: var(--surface-sunken); text-decoration: none; }
a.os-kpi:focus-visible { outline: none; box-shadow: inset var(--focus-ring); }

/* KART GORUNUMUNDE HOVER (2026-10-15): .os-table--clickable satiri hucre hucre boyuyordu (tr:hover td); kart
   izgarasinda hucreler ayrik oldugu icin yamali acik mavi bloklar cikiyordu. Kartta hucreler boyanmaz, KART
   tepki verir: kenarlik marka rengi + hafif golge. Tablo gorunumundeki satir boyamasi degismez. Dosya sonunda:
   ayni ozgulluktaki .os-table--stickyact son-hucre kuralini da ezer. */
.os-table.os-table--stacked tbody tr:hover td,
.os-table.os-table--stacked tbody tr:hover td:last-child { background: transparent; }
.os-table--clickable.os-table--stacked tbody tr { cursor: pointer; transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
.os-table--clickable.os-table--stacked tbody tr:hover { background: var(--surface-card); border-color: var(--interactive-primary); box-shadow: var(--shadow-sm); }
.os-table--clickable.os-table--stacked tbody tr:has(> td[colspan]:only-child) { cursor: default; }
.os-table--clickable.os-table--stacked tbody tr:has(> td[colspan]:only-child):hover { border-color: var(--border-default); box-shadow: none; }
